ElasticBeanstalk伸缩时偶发404的原因
使用EB Passenger with Ruby部署rails时,如果是以默认配置启动,没有做对应的配置,在ASG Scale Up的时候,可能会有请求没法正常处理,返回404。
原因
- EB中创建的ELB,默认是使用TCP:80的方式来检查Instance的健康状态的。
- ELB的
health check
的默认Interval
是10 seconds,Healthy threshold
是3 requests。 - 当ASG Scale Up时,新建的Instance中Passenger在Rails APP部署完成之前就已经在监听80端口了。
- Passenger启动30秒之后,因为超过了
Healthy threshold * Interval
的时间, 并且每次检查都是OK的,ELB会判定Instance是可用的,就会将流量导入到该Instance中。 - 但此时rails APP可能并没有部署完成(bundle install加上precompile,部署一个新的APP可能需要5分钟左右),所以client会得到404的错误。
解决办法
- 通过修改EB中ELB的
health check
的检查方式为HTTP方式,可以避免该问题。 - 在Rails中新增一个单纯返回200 OK的路由(可以是任意的路由,此处以
/health
为例) 在EB Console中,设置ELB中
Health check path
为/health
。选择Configuration中的load balancer,点击modify
,在Health check
设置中设置Health check path
的值为对应的链接。设置过后,当ASG启动新的Instance时,在APP部署完毕,
health check
链接生效之前, ELB的检查都无法成功,也就不会将流量导给新的Instance了。只有APP部署完成,health check
通过后,才会将流量导给Instance。
注意点:
- 建议专门用一个只回应200 OK的链接用来响应
health Check
, 而不要使用带有业务逻辑的链接。 - 必须要先发布Rails APP添加/health,接下来才能修改ELB的Health check path。