本文分享一个本人应用swoole毫秒定时器遇过的坑,以及解决的办法。心愿能帮忙遇到大家。
学习毫秒定时器前,须要具备应用的根底语法,请参考官网文档(https://wiki.swoole.com/#/timer),我就不照搬了。
其中应用毫秒定时器的注意事项要多留神一下,以防前面犯错都不晓得啥起因
1. 定时器仅在以后过程空间内无效2. 定时器是纯异步实现的,不能与同步 IO 的函数一起应用,否则定时器的执行工夫会产生错乱3. 定时器在执行的过程中可能存在肯定误差
置信大家在看swoole的毫秒定时器时,跟着官网根底的例子都会写。但用到理论我的项目中,要怎么联合呢?上面就开始分享一下我本人在理论我的项目中应用swoole定时器的形式。
咱们以think5.1框架为例子,比方在某个控制器中,应用毫秒定时器依据官网文档,写出这么一个例子。
public function test(){ $param1 = 'aaa'; $path = __DIR__.'/demo.txt'; //每隔两秒往demo.txt文件写一次数据,用此例子代替业务逻辑 swoole_timer_tick(2000,function () use ($param1, $path) { file_put_contents($path,$param1.'|'.'1'.PHP_EOL,FILE_APPEND); });}
你们感觉有问题吗?
马上运行看看
解说一下运行形式:咱们都晓得swoole运行在cli形式下,间接通过浏览器拜访这个办法,必定会报错。报swoole只能运行在cli形式下。那咱们要在cli下如何运行呢?在thinkphp中,咱们就能够在入口文件处,以上面的形式运行swoole。php index.php api/task/test
api/task/test tp中拜访形式:模块名/控制器名/办法名
发现报错.
这个谬误我当初百度谷歌了半天,没搞懂。通过询问官网作者后,得以解决.
须要在程序开端加这么一段代码
`public function test()
{ $param1 = 'aaa'; $path = __DIR__.'/demo.txt'; //每隔两秒往demo.txt文件写一次数据,用此例子代替业务逻辑 swoole_timer_tick(2000,function () use ($param1, $path) { file_put_contents($path,$param1.'|'.'1'.PHP_EOL,FILE_APPEND); }); \Swoole\Event::wait();}`
因为定时器是异步的,执行完定时器后,会持续往下执行,而上面没有代码程序就完结了。所以在加一个wait操作,使程序阻塞在那里。这样定时器在两秒后能力继续执行,不会报错。
联想:
而在swoole\server的onWorkerStart办法中应用定时器,为啥不必加wait操作,是因为在server->start操作中,其实就加了wait操作。swoole底层解决了,让程序始终阻塞在start办法中。
加上后,再次运行
发现不报错了,查看文件也是有数据的,此时胜利了一大半了。
此时发现程序始终占用着终端。如果咱们ctrl + c,退出定时器就退出了,咱们的业务逻辑就不执行了,这时又来了一个问题,如果定时器能在变成守护过程,始终在后盾运行就好了。
如何变成后盾运行的形式呢?分享两个我的做法。
1.应用nohup命令(linux自带命令)。不挂断的执行某个命令
nohup /usr/local/php/bin/php index.php api/task/test >/dev/null 2>&1 &
解释:在后盾不间断的运行命令(/usr/local/php/bin/php index.php api/task/test),并把运行中的输入重定向到linxu的/dev/null(黑洞文件),2>&1是标准化输入。 & 是nohup的命令要求。
这样子,就能够把脚本变成守护过程运行了。如下图,就不会霸占光标当前台的形式始终运行了
2.应用superviosr工具
1.能够让一些脚本变成守护过程。
2.能够检测过程的状况,在异样退出时主动重启。比方能够检测swoole的守护过程是否异样退出
把脚本当成一个子过程,被superviosr治理。
区别:比方容错率比nohup要好一点,适宜业务逻辑比拟重要的场景。间接应用nohup比拟不便,不必再去下载superviosr工具,适宜边缘化一点业务场景。
在此文中就不细讲superviosr了,网上很多教程,留神给一个解决问题的方向。
好啦,这样子咱们就能欢快的把swoole定时器与理论我的项目联合啦。
本文为夜雨闻铃原创文章,转载无需和我分割,但请注明文章出处。文章出处:夜雨闻铃的思否文章(https://segmentfault.com/a/11...)