使用EB Passenger with Ruby部署rails时,如果是以默认配置启动,没有做对应的配置,在ASG Scale Up的时候,可能会有请求没法正常处理,返回404。

原因

  1. EB中创建的ELB,默认是使用TCP:80的方式来检查Instance的健康状态的。
  2. ELB的health check的默认Interval是10 seconds,Healthy threshold是3 requests。
  3. 当ASG Scale Up时,新建的Instance中Passenger在Rails APP部署完成之前就已经在监听80端口了。
  4. Passenger启动30秒之后,因为超过了Healthy threshold * Interval的时间, 并且每次检查都是OK的,ELB会判定Instance是可用的,就会将流量导入到该Instance中。
  5. 但此时rails APP可能并没有部署完成(bundle install加上precompile,部署一个新的APP可能需要5分钟左右),所以client会得到404的错误。

解决办法

  1. 通过修改EB中ELB的health check的检查方式为HTTP方式,可以避免该问题。
  2. 在Rails中新增一个单纯返回200 OK的路由(可以是任意的路由,此处以/health为例)
  3. 在EB Console中,设置ELB中Health check path/health。选择Configuration中的load balancer,点击modify,在Health check设置中设置Health check path的值为对应的链接。

    health_check_setting_on_EB

  4. 设置过后,当ASG启动新的Instance时,在APP部署完毕,health check链接生效之前, ELB的检查都无法成功,也就不会将流量导给新的Instance了。只有APP部署完成,health check通过后,才会将流量导给Instance。

注意点:

  1. 建议专门用一个只回应200 OK的链接用来响应health Check, 而不要使用带有业务逻辑的链接。
  2. 必须要先发布Rails APP添加/health,接下来才能修改ELB的Health check path。

Reference

留言