我在两台几乎相同的服务器上使用带有 MySQL 和 PHP 的 Windows Server 2016 上的 IIS。我最近注意到我的两台服务器之一的速度变慢了,但只有当我的站点尝试同时执行多个脚本实例时才会发生这种情况。他们似乎被困在了彼此身上。
一个完美的例子是我的搜索页面。当用户键入搜索查询时,每次按键(在第二个字母之后)只要自上次按键后至少有 200 毫秒的延迟,就会执行一次搜索。因此,如果您快速键入,它最后只会进行一次搜索,但对于较慢的打字员(按键之间等待超过 200 毫秒的人),这将触发对搜索结果的多次调用。请参阅此屏幕截图。
请注意所有待处理的请求,在此屏幕截图中,第一个请求刚刚在 19.08 秒完成。显然太长了。当他们全部完成时,他们都已经超过 15 秒才能返回一个简单的结果集。
请记住,这些查询在 MySQL Workbench 中运行时以及在我的其他没有遇到此问题的服务器上运行时只需要几分之一秒。在此屏幕截图(来自良好的服务器)中看到完全相同的搜索在四分之一秒内返回。
在我看来,(在坏的服务器上)由于某种原因它们无法同时执行,因为如果我只执行一次搜索(通过快速键入以触发一次搜索)它很快就会回来,但是如果我像这样执行倍数,他们都像堵车一样卡住了。什么可能导致这种情况?
下一个屏幕截图显示了我在坏服务器上仅触发一次搜索时的结果。如您所见,它恢复得非常快。所以问题只是在同时执行多个相同的脚本时。
我最近确实对坏服务器进行了一些更改,但据我所知,我所做的唯一更改是允许上传更大的文件。
- 在 PHP 中我增加了 post_max_size = 500M
- 在 PHP 中我增加了 upload_max_filesize = 500M
- 在 IIS 中,我将 UploadReadAheadSize 增加到 49152000
- 在 IIS 中,我将允许的最大内容长度增加到 300000000
我可能对此服务器进行了其他我不记得的更改。
临时修复
我可以通过在搜索时允许更长的按键之间的延迟来缓解这个问题,我已经做到了,将它增加到 800 毫秒,所以即使是慢速打字机也看不到这个问题,但这只是一个创可贴解决方案,并没有解决也影响我网站其他区域的潜在问题。
我试过的
到目前为止,我已经确认我的 IIS 配置、MySQL 配置(my.ini)和我的 PHP 配置(php.ini)在两台服务器上的所有重要方面都是相同的(至少在我看来是显而易见的) . 我还确认,如果我在 MySQL Workbench 中执行我在此搜索中运行的选择语句,它们在两台服务器上的性能同样出色。仅在我的网络应用程序中遇到此问题。
为了以防万一,我暂时撤消了我对 IIS 所做的两个更改以上传更大的文件,但这似乎没有什么区别。
我还下载并安装了 LeanSentry,它每天会警告我一两次,我的网站已看到被阻止的请求,我认为这正是我在这里看到的,但不幸的是,LeanSentry 只能查明 ASP 问题的根源页面,而不是 PHP。所以它本质上只是对我确认存在问题,但除此之外它无法帮助我。
其他症状
如果我同时打开多个报告,我会看到类似的问题。如果我允许一个报告在打开下一个报告之前完成加载,它们都会快速加载,但如果我强制我的应用程序一次打开多个报告,它们都会卡住。
什么可能导致这个瓶颈问题?
我认为不是它的 IIS 服务器在这里有问题,你搜索的每一件事都在你的代码中请求一个新的调用,它看起来像你的 PHP 脚本中的东西需要很长时间。
每次你发送一个新请求时,你只是阻塞了一个新的 PHP 瞬间,当 PHP 用完瞬间它就会崩溃。
很难知道您在搜索 PHP 文件中在做什么,但我认为您正在调用某个 SQL 服务器或其他东西进行搜索。您可以尝试在代码中注释搜索查询并进行相同的测试吗?
现在我只是猜测我能做到的最好的,它听起来就像你在 SQL 数据库中使用正则表达式或类似的函数,当你有很多行时,它的调用速度非常慢,这就是它挂起很多的原因。
但我只是想这么晚我才知道我告诉你做的测试结果。
事实证明,HTML 渲染导致了挂起。当我的搜索结果很长时,浏览器需要很长时间才能呈现所有 HTML,并且在这样做时它无法处理下一个请求。
我通过将搜索结果限制为 50 行解决了这个问题,因此现在 HTML 几乎立即呈现并且可以执行下一个请求。因此,阻止请求的不是 IIS,而是浏览器。