我在 RubyOnRails 中有一个应用程序,由位于 CDN 服务后面的 NGINX 服务器代理。CDN 有一个限制,即如果响应的第一个字节在 60 秒内未到达,则 CDN 服务器会做出以下响应:
Error 503 first byte timeout
问题是我确实有一些请求在 Rails 端需要超过 60 秒才能处理。有没有办法破解响应,在响应完成处理之前发送几个字节?怎么做?
编辑1:
我知道 60 秒是很长的时间,我们正在考虑如何避免这种情况。不过,我需要一个临时解决方案,让这些 60 秒的请求能够正常工作。即使我使用 Ajax,一些 ajax 调用也会花费超过 60 秒的时间,并会陷入同样的问题。tcp_nopush 或 tcp_nodelay 选项不起作用,我认为这是因为 nginx 正在等待 rails 应用程序响应以知道它应该发送什么标头。所以,也许解决方案是我需要在 RubyOnRails 请求/响应周期中进行破解的
答案1
请求耗时超过 60 秒是相当长的时间。您可能需要检查您的应用程序。这么长的页面加载时间可能会导致大量访问者退出您的应用程序。您可能需要考虑异步加载数据,例如使用 AJAX 或 websockets。
第一个字节的时间通常应用于标头,而不是响应主体。客户端应该尽早接收标头。你确定是你的 CDN 使请求超时了吗?NGinx 也会使你的请求超时。一个好的检查方法是使用 curl:
curl -I -H "Host: <domain>" http://<ip of proxy>/request/uri
(使用代理的真实 IP,而不是 CDN IP)
-I 选项将显示响应标头,这样您就可以清楚地了解 nginx 返回了什么错误代码(如果有)。您还可以查看是否正在接收请求标头以及接收所需的时间,因为这就是 tcp 第一个字节所指的内容。
如果您没有快速收到标头,请尝试使用:
http {
tcp_nopush off;
tcp_nodelay on; # force socket to send buffer
}
如果您收到网关超时错误或类似错误,请尝试以下配置选项:
http {
keepalive_timeout 300;
proxy_connect_timeout 300;
proxy_read_timeout 300;
proxy_send_timeout 300;
}