宝哥软件园

Swoole4.4协同抢先调度器详解

编辑:宝哥软件园 来源:互联网 时间:2021-08-23

前言

Swoole内核团队开设的专栏将逐步致力于撰写文章,介绍Swoole的开发过程、实现原理和应用实践,让大家更好地交流,共同学习,构建PHP生态。

协同调度

去年Swoole发布4.0版本后,完全支持PHP协同学。我们可以实现基于协同学的CSP编程,周围的开发者惊呼原来PHP代码也可以这样写。Swoole的协同默认是基于IO调度的,如果程序出现堵塞,当前的协同会自动放弃。我们在这里不讨论合作的优势。如果是IO密集型场景,可以表现得非常好。但是对于CPU密集型的场景,有些协同学会因为拿不到CPU时间片而饿死。

抢先调度

今年年初,我们计划实现Swoole的抢占式调度,以满足某些场景下调度不平衡带来的问题。我们中间经历了好几个版本,所以想和大家分享一下开发过程中的动力和解决方案。

我们的目的是平衡每个协调过程的CPU时间。比如协调进程3需要很长的执行时间,所以我们必须主动中断协调进程3的CPU时间,而不依赖于IO事件,这样每个协调进程才能得到一个平均的执行时间。

最初我们的想法是可以从PHP的循环中自动检测执行实践,如果达到极限,就可以自动放弃当前的协调过程。因为毕竟马平川很少有人写占用大量CPU的代码,而且大部分都是由循环条件控制的。我们挂钩循环指令,每次执行循环指令都要检查协调的执行时间。我们很高兴得到原始版本。然而,这是更黑的,在opcode被opcache优化后,情况会变得有些复杂。

后来我们使用了PHP的ticks机制,即在PHP代码的编译过程中,注入ticks指令来执行相应的功能,我们可以检测这些功能中协调的处理时间,达到抢占的效果。然而,这里有一个问题。PHP的declare(ticks=N)语法只对当前的脚本范围有效,也就是说,如果项目稍微大一点,需要或者包含的脚本不会自动注入ticks指令。我们也尝试给PHP官方一个PR,可以在扩展层设置一个全局默认的ticks,但是官方不愿意采用我们的提交,因为官方认为这个功能会造成很大的性能损失,在PHP8中删除这个功能是有可能的。实际上,这种性能损失经过实际测量并不大,我们在生产环境中进行了验证,取得了显著的效果,即可以放弃一些CPU密集型的逻辑部分,使得整个对应的服务时间更加均衡。

下图是生产环境中RPC接口的调用方统计信息的比较。客户端等待2秒的超时时间,超时时间被视为错误。

左侧没有抢占调度,右侧没有抢占调度。可以发现左侧总是会偶尔超时。优化后没有超时请求,请求的响应时间非常流畅,提高了服务的稳定性。

从上图可以看出,由于抢占式调度的加入,去除了高请求耗时的毛刺,平均请求时间变得更加平滑稳定。

PHP有两种方法可以进行抢先调度

单线程PHP执行流可以在PHP执行流中注入逻辑来检查执行时间。另外,Swoole的协调能力可以在不同的协调进程之间切换,达到抢占CPU的目的。考虑打开一个线程,负责检查当前执行协调的执行时间。尝试以上方法后,注入指令的方式数量基本无法得到官方支持,只能另辟蹊径,多开一个线程,只负责检查当前的协调进程。具体方法是使用PHP-7.1.0引入的VM中断机制,默认每5毫秒检查一次当前协调进程是否达到最大执行时间,默认为10 m

需要Swoole 4.4或更高版本?phpco :3360 set([' enable _ preempt _ scheduler '=1]);$ start=micro time(1);echo“start n”;$ flag=1;go(function())使用($ flag){ echo ' coro 1 start to loop n ';$ I=0;for(;){ if(!$ flag){ break;} $ I;} echo“coro 1可以退出 n”;});$ end=micro time(1);$ msec=($ end-$ start)* 1000;echo“使用时间$ msec n”;go(function())使用($ flag){ echo ' coro 2 set flag=false n ';$ flag=false});回声“end n”;执行结果

Start coro1 start to loop使用时间11.121988296509 coro 2 set flag=false endcoro 1 canexit。可以发现,代码逻辑可以自动从第一协同的无限循环中屈服,执行第二协同。没有这个特性,第二个协同学永远不会执行,导致饥饿。这样,第二协调过程可以成功执行,并且在最终执行之后,第一协调过程将继续执行。达到我们二次协作主动抢占一次协作CPU的效果。

此功能在生产环境中非常有用,尤其是对于响应时间敏感的实时系统或场景。

最后的

感谢您对Swoole的长期支持和关注。

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

更多资讯
游戏推荐
更多+