PHP 单进程同步阻塞处理优化
前段时间接手了一个老系统,其中对于“订单”的处理是通过一个 PHP 脚本来完成的。
这里说的“订单”,不一定是传统的订单概念,因为业务场景相对特殊,上面脚本的作用就是用来处理大量数据库 IO 操作。
<?php
function doSomething(){
// 查询数据库是否有需要处理的"订单"
if ($exists) {
// todo
}
}
while (true) {
doSomething();
}
起初上线时并没有什么问题,但随着用户逐渐增多,最近暴露出了很多问题。
- 首先上面那个脚本的处理方式是同步阻塞
- “旧订单”还没处理完,“新订单”又进来了,“订单”处理不及时从而引发一系列业务问题
- 类似处理还有其他几个脚本。导致数据库压力较大(数据库没做读写分离,单机部署)。
请问:
- 这个场景有什么好的处理方式吗?
- Swoole 的协程是否适用于该场景?
(老系统历史包袱较重,不适宜对项目整体进行大改动)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
处理任务递交到队列中是个很好的思路。
判断一下无效的IO操作多吗?最先能想到的是空轮询。队列的阻塞能力可以避免过多空轮询消耗在网络传输中。
可以分析一下exists()的sql是否存在锁表现象,这会导致CPU长时间处于sleep状态,会让你的任务吞吐速度很慢。数据库出现压力跟处理速度慢应该是互为因果的。
如果IO阻塞过于频繁,可以考虑使用swoole协程或者简单一点直接fork多进程去处理任务就好了。
关于数据库压力要根据你的业务来分析,如果是通过减缓处理速度来实现的话(“订单”处理不及时从而引发一系列业务问题)这个问题应该还是会处理,需要提交
doSomething();
对于数据库的压力。队列可以分担走existst()产生的压力,后面的要看具体业务了楼上的队列倒是一个很好的方案。
但换个角度看问题:你这里分为阻塞跟数据库压力
如果采用swoole的话,协程能够解决阻塞问题,定时器执行能够缓解数据库压力。