apache 如何调试/解决由于max.并发请求(PHP,Laravel,Shopware)

gt0wga4j  于 2023-06-06  发布在  Apache
关注(0)|答案(1)|浏览(135)

我目前正在做一个涉及嵌套api调用的项目。在我的项目中,我目前面临着一个死锁问题,我有点不知道如何调试这个问题。

设置

在我的设置中,我有两个仓库:
1.面向客户端的Laravel
1.内部Shopware 6
laravel项目将通过REST API调用。在一些API调用的情况下,Laravel将在内部调用Shopware以获取一些客户或店面信息。这些调用通过Guzzle进行。这在大多数测试用例中工作正常,但如果同时发出多个Laravel请求,则会失败。

问题

如果同时进行多个商店相关的API调用,Shopware将不再从Laravel项目接收这些内部调用。对Shopware的内部调用将被推迟,直到Laravel调用失败(由于存储请求超时)。一旦Laravel请求完成,看似排队的内部请求就会到达Shopware,但此时显然为时已晚,因为响应将不再被处理。
所以时间线看起来是这样的:
1.多个请求到达Laravel

  1. Laravel开始处理请求
  2. Laravel向Shopware发送内部请求
  3. Laravel由于超时而停止监听请求
  4. Laravel返回错误响应
  5. Shopware开始处理以前的请求
  6. Shopware完成请求,但Laravel不再侦听

假设

对于初始的Laravel请求,它似乎占用了所有可用的并发请求。因此,Laravel似乎无法发送内部请求到Shopware,直到初始请求(到Laravel)完成。因此,通过这种方式,会创建死锁,其中初始请求等待后续请求,而后续请求正在等待初始请求完成。

思考

有一段时间,我想知道是否在某个地方有一个锁--就像提到的here--它会阻止Shopware请求的执行。但我认为我可以排除这种情况,因为只有在同时发生多个嵌套Shopware调用时才会出现该问题。如果只有几个请求正在发生,那么请求将按预期发送。此外,我可以看到Shopware在Laravel请求完成之前根本不会被调用。由于index.php的第一行甚至没有被调用,我想我可以排除潜在的机制,包括锁。
我的猜测是我的系统达到了同时请求的极限。因此,内部请求将被排队,直到初始请求完成并且请求槽被释放。一旦槽变得可用,则随后将处理排队的请求。
不幸的是,我不知道如何明确地调试/证明我的猜测。我也试过几次试图解决这个问题,但到目前为止,我没有成功。因此,我将感谢任何提示,可以提示我一个解决方案。

尝试次数

我已经尝试增加MaxRequestWorkers计数,以及其他一些参数。

<IfModule mpm_prefork_module>
  StartServers    50
  MinSpareServers 50
  MaxSpareServers 150
  MaxRequestWorkers       150
  MaxConnectionsPerChild  5000
</IfModule>
    • 结果**:无变化

我尝试将数据库存储在两个独立的MySQL设置中。MySQL 5中的Laravel数据库和MySQL 8中的Shopware,以避免可能的数据库锁定。

    • 结果**:无变化

环境

  • macOS Ventura
  • MAMP Pro 6.6
  • Apache 2.4.46
  • MySQL 5.7.34

相关问题

  1. long poll hanging all other server requests
  2. Simultaneous Requests to PHP Script
  3. Allow clients to run multiple simultaneous PHP requests
    干杯zZeepo
q5lcpyga

q5lcpyga1#

我找到解决办法了!🎉
问题是FastCGI PHP_FCGI_CHILDREN配置。
这控制了PHP进程产生多少子进程。当fastcgi启动时,它会创建许多子进程,这些子进程一次处理一个页面请求。值0表示PHP不会启动额外的进程,主进程将自己处理FastCGI请求。注意这个进程可能会死(因为PHP_FCGI_MAX_REQUESTS),并且它不会自动重生。值1及以上会强制PHP启动额外的进程来处理请求。主进程将在子进程死亡时重新启动子进程。因此,默认情况下,您将能够处理1个并发的PHP页面请求。其他请求将排队。增加这个数字将允许更好的并发性,特别是如果您有需要大量时间来创建的页面,或者提供大量数据(例如通过PHP下载大文件)。另一方面,运行更多的进程将使用更多的RAM,同时生成太多的PHP页面将意味着每个请求都将变慢。
此参数设置为4。因此,只要4个并发请求发送到Laravel,就不会产生进一步的子进程,从而导致前面描述的死锁。
该值以/Applications/MAMP/fcgi-bin/php8.1.0.fcgi为单位定义

#!/bin/sh
export PHP_FCGI_CHILDREN=4
export PHP_FCGI_MAX_REQUESTS=200
exec /Applications/MAMP/bin/php/php8.1.0/bin/php-cgi -c "/Library/Application Support/appsolute/MAMP PRO/conf/php8.1.0.ini"

我已经将值增加到PHP_FCGI_CHILDREN=10,这对于我的开发环境应该足够了,它解决了我的问题。

相关问题