Rails の ajax 処理で504エラーが出たので対処した
以下のエラーが消えずに困っていた。
rails-ujs.js:216 POST https://*** 504
どうもリクエストから60秒経つと強制でタイムアウトとなるのが原因っぽい。
処理の流れは以下のような感じ。どこでタイムアウトが発生しているのか調べてみる。
Internet => ALB => ECS => Nginx => Puma => Rails => ajax
ajax
ajax処理の中身は XMLHttpRequest
。ドキュメントを見てみる。デフォルト設定ではタイムアウトは無かった。
XMLHttpRequest.timeout は unsigned long 型で、リクエストが自動的に終了するまでの時間をミリ秒で示します。既定値は 0 で、タイムアウトが無いことを示します。
XMLHttpRequest.timeout - Web API | MDN
Rails + Puma
ソースは見つからなかったが、Rails と Puma にはタイムアウトの制御は無いらしい。
Railsでタイムアウトのエラーをログに出力する方法 - Qiita
Nginx
第一の原因は Nginx だった。とりあえず以下のようにタイムアウト時間を 60秒 => 180秒 に設定。
sendfile on;
keepalive_timeout 180;
send_timeout 180;
proxy_connect_timeout 180;
proxy_read_timeout 180;
proxy_send_timeout 180;
upstream app {
server unix:///app/tmp/sockets/puma.sock;
}
ALB
Nginx の修正だけでは直らなかったのでALBまで遡った。
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
IpAddressType: ipv4
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: 180
AWS::ElasticLoadBalancingV2::LoadBalancer - AWS CloudFormation
これで解決した。