我遇到了一些问题,对于页面的请求,在处理很长时间后没有得到响应。
我已将 nginx 设置为使用 php-fpm。我在 PHP-FPM 中设置了两个池。一个池用于一般网页请求,一个池用于提供图像和其他大文件。
从我的 php-fpm 配置文件:
[www]
listen = var/run/php54/php-fpm-www.sock
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 20
pm.max_requests = 200
[www-images]
listen = var/run/php54/php-fpm-images.sock
pm = dynamic
pm.max_children = 5
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 40
Nginx 配置为使用这两个单独的池,对存储在 Amazon S3 中的图像的请求将通过“www-images”池调整为请求的大小。从我的 nginx 配置文件中:
location ~* ^/proxy {
try_files $uri @404;
fastcgi_pass unix:/opt/local/var/run/php54/php-fpm-images.sock;
include /opt/local/etc/nginx/fastcgi.conf;
}
location / {
try_files $uri /routing.php?$args;
fastcgi_pass unix:/opt/local/var/run/php54/php-fpm-www.sock;
include /opt/local/etc/nginx/fastcgi.conf;
}
因为我在糟糕的互联网连接上进行测试,所以这些请求在 PHP 中超时,这是预料之中的。
2013/01/20 15:47:34 [错误] 77#0:*531 上游读取响应标头时超时(60:操作超时),客户端:127.0.0.1,服务器:example.com,请求:“GET /proxy/hugeimage.png HTTP/1.1”,上游:“fastcgi://unix:/opt/local/var/run/php54/php-fpm-images.sock:”,主机:“example.com”,引荐来源:“http://example.com/pictures“
我想要解决的意外问题是,任何应该进入“www”池的请求都超时了,因为 nginx 没有收到来自 PHP-FPM 的响应。
2013/01/20 15:50:06 [错误] 77#0:*532 上游读取响应标头时超时(60:操作超时),客户端:127.0.0.1,服务器:example.com,请求:“GET /pictures HTTP/1.1”,上游:“fastcgi://unix:/opt/local/var/run/php54/php-fpm-www.sock:”,主机:“example.com”
几分钟后,对“www”池的请求又开始工作,无需我采取任何行动。
我认为使用单独的池意味着即使一个池存在请求花费很长时间的问题,另一个池也不会受到影响。
所以我的问题是;我如何隔离这两个池,以便一个池被超时的请求淹没,不会影响另一个池。
需要澄清的是,我设计时希望限制通过“www-images”池一次发出的请求数。虽然实际上几乎不会达到此限制(因为要缓存从 S3 下载到服务器的文件),但如果出现异常情况,即该池达到其限制,我希望 www 池继续运行,因为网站功能实际上就位于此处。
答案1
我发现了两件事:
- 将 session_write_close(); 添加到任何长时间运行的 PHP 脚本,因为会话数据被锁定以防止并发写入,因此任何时候只有一个脚本可以对会话进行操作。
- 对于任何可能加载缓慢的图像,请确保从与您提供网页和 Ajax 调用的域不同的域加载它们,因为当有大量活动请求时,Web 浏览器会将请求排队到同一个域。
虽然这是两个独立的事情,但它们具有相同的效果,即使对“www”池的请求被对“www-images”池的请求阻止。