PHP 单进程同步阻塞处理优化

发布于 2022-09-12 13:42:26 字数 554 浏览 21 评论 0

前段时间接手了一个老系统,其中对于“订单”的处理是通过一个 PHP 脚本来完成的。

这里说的“订单”,不一定是传统的订单概念,因为业务场景相对特殊,上面脚本的作用就是用来处理大量数据库 IO 操作。

<?php
function doSomething(){
     // 查询数据库是否有需要处理的"订单"
     if ($exists) {
        // todo 
     }
}
while (true) {
    doSomething();
}

起初上线时并没有什么问题,但随着用户逐渐增多,最近暴露出了很多问题。

  • 首先上面那个脚本的处理方式是同步阻塞
  • “旧订单”还没处理完,“新订单”又进来了,“订单”处理不及时从而引发一系列业务问题
  • 类似处理还有其他几个脚本。导致数据库压力较大(数据库没做读写分离,单机部署)。

请问:

  • 这个场景有什么好的处理方式吗?
  • Swoole 的协程是否适用于该场景?

(老系统历史包袱较重,不适宜对项目整体进行大改动)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

枕头说它不想醒 2022-09-19 13:42:26

处理任务递交到队列中是个很好的思路。

判断一下无效的IO操作多吗?最先能想到的是空轮询。队列的阻塞能力可以避免过多空轮询消耗在网络传输中。
可以分析一下exists()的sql是否存在锁表现象,这会导致CPU长时间处于sleep状态,会让你的任务吞吐速度很慢。数据库出现压力跟处理速度慢应该是互为因果的。
如果IO阻塞过于频繁,可以考虑使用swoole协程或者简单一点直接fork多进程去处理任务就好了。
关于数据库压力要根据你的业务来分析,如果是通过减缓处理速度来实现的话(“订单”处理不及时从而引发一系列业务问题)这个问题应该还是会处理,需要提交doSomething();对于数据库的压力。队列可以分担走existst()产生的压力,后面的要看具体业务了

捎一片雪花 2022-09-19 13:42:26

楼上的队列倒是一个很好的方案。

但换个角度看问题:你这里分为阻塞跟数据库压力
如果采用swoole的话,协程能够解决阻塞问题,定时器执行能够缓解数据库压力。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文