我会尝试对此非常具体 - 这并不容易,所以请尽量遵循。
我们有一个在NGINX上使用PHP运行的脚本 - PHP-fpm FastCGI。 此脚本从尝试访问它的用户获取信息,并在实时上运行某些算法。它不能是在后台运行的预定进程。 有时,甚至需要加载5-12秒之间的页面 - 而确定。 通常,我们从用户收集数据并向第三方服务器发出多个传出请求,收集数据,分析数据并为用户返回响应。
问题是, 有很多很多用户运行此脚本,服务器非常繁忙 - 因为它们都是服务器上的活动连接,等待响应。 我们有2台服务器在1负载均衡器下运行,这还不够。 有时,服务器一次有超过1,500个活动连接。您可以想象这些服务器在该时间范围内的响应方式。
我正在寻找解决方案。 我们可以为LB添加越来越多的服务器,但这是唯一的解决方案,这听起来很荒谬。 我们跑过那个脚本并将其优化到最大程度,我可以向你保证 - 对于该脚本的长时间运行没有真正的解决方案,因为它依赖于第三方服务器需要时间来回应我们的实时流量。
是否有一个你能想到的解决方案,保持这个脚本不变 - 但不知何故,为了降低这些活动连接对整个服务器功能的影响? 有时,他们只是停下来回应。
非常感谢您的阅读!
答案 0 :(得分:3)
3个月的问题,我知道,但我无法帮助它思考:
如果您确定所有对第三方服务器的请求的网络总和加上PHP脚本中相应的响应处理多低于硬件的限制。
然后,您的PHP脚本可能会无效地忙于循环,直到所有响应都从第三方服务器返回
如果我正在处理这样的问题,我会这样做:
停止使用自定义外部C ++ curl,因为PHP脚本正在忙着等待它。
Google,了解PHP的curl-multi实现的非繁忙循环使用
希望这是有道理的。
答案 1 :(得分:1)
我的建议是为请求设置有限的超时,为每个第三方请求使用异步请求。
例如,对于您的页面,您必须显示5个第三方请求的结果。这意味着,您在内部脚本中调用cURL
或file_get_contents
5次,但脚本会因第三方的每次超时而冻结。一步步。这意味着,如果对于每个请求,您必须等待10秒才能得到响应 - 您将总共有50秒
User calls the script -> script wait to end -> server is loaded for 50 seconds
现在,如果对第三方的每个请求都将异步发送 - 它会将脚本的加载时间减少到最大请求延迟。因此,您将拥有一些较小的脚本,这些脚本的寿命会缩短 - 并且会降低服务器的负载
User calls the script -> script is loaded -> requests are sent -> there are no scripts that are waiting for the response and consuming resources of your server
愿AJAX和你在一起! ;)
答案 2 :(得分:0)
这是一个非常老的问题,但是由于我有一个类似的问题,所以我可以分享我的解决方案。长时间运行的脚本会影响系统的各个部分,并导致web服务器(处于活动连接状态),php-fpm和mysql / other数据库的压力。这些往往会导致一系列影响,例如其他请求开始失败。
首先确保服务器上已安装netdata(https://github.com/netdata/netdata)。如果您正在运行许多实例,则可能会发现具有Grafana / Prometheus设置也是值得的。
接下来,确保它可以看到PHP FPM进程Mysql和Nginx。 Netdata显示了很多东西,但是对于这个问题,我的关键指标是:
请确保您有足够的文件句柄(https://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files/),并且磁盘未完全占用。这两个都将阻止您使工作正常进行,因此请在麻烦的服务器上将它们增大。
下一步检查Nginx在nginx.conf中是否有足够的资源:
worker_processes auto;
worker_rlimit_nofile 30000;
events {
worker_connections 768;
}
这将使您有时间找出问题所在。
接下来查看php-fpm(/etc/php/7.2/fpm/pool.d/www.conf):
然后观看。我的问题是每个请求都会阻止传入连接。对同一脚本的更多请求将阻止更多连接。机器可以正常运行,但是执行卷曲命中或慢速SQL语句的单个慢速脚本将在整个持续时间内保持该连接,因此30秒=减少了处理传入请求的php进程。最终,您击中500,然后用尽。如果您可以增加FPM进程的数量,以使慢速脚本请求的频率与其运行的秒数相匹配。因此,如果脚本花费2秒并每秒被命中2次,则您将需要不断增加4个fpm worker线程来执行任何操作。
如果可以的话,就停在那儿-额外的努力可能不值得。如果仍然有问题,请在包装盒上创建第二个php-fpm实例,并将对慢速脚本的所有请求发送到该新实例。这样,在运行时间过多的情况下,您可以离散地使那些请求失败。这将使您有能力执行两项重要操作:
希望能帮助有人在负载下挣扎的生活!