Laravel8中使Swoole协程

作者: 温新

分类: 【高性能PHP】

阅读: 2753

时间: 2021-04-24 16:37:31

Laravel8中如何使用Swoole协程?此篇文章仍旧以LaravelS扩展包作为案例笔记。本篇文章中需要先使用异步任务,关于异步任务请先按照 基于LaravelS Swoole实现异步任务队列 实现(完成前2步即可)。

第一步:编码协程代码

文件:app/Processes/TestProcess.php

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(152, 26, 26)"><?</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">namespace</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">App\Processes</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">App\Jobs\TestTask</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Hhxsv5\LaravelS\Swoole\Process\CustomProcessInterface</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Hhxsv5\LaravelS\Swoole\Task\Task</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Support\Facades\Log</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Swoole\Coroutine</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Swoole\Http\Server</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Swoole\Process</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">TestProcess</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">implements</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">CustomProcessInterface</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">static</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">getName</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(119, 0, 136)">return</span> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">"test"</span>; <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 进程名称</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">static</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">callback</span>(<span style="box-sizing: border-box;color: rgb(0, 0, 0)">Server</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$swoole</span>, <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Process</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$process</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 进程运行的代码,不能退出,一旦退出Manager进程会自动再次创建该进程</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 频繁退出/创建进程会消耗系统性能</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Log</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">info</span>(<span style="box-sizing: border-box;color: rgb(34, 17, 153)">__METHOD__</span>, [<span style="box-sizing: border-box;color: rgb(0, 0, 0)">posix_getpid</span>(), <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$swoole</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">stats</span>()]);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(119, 0, 136)">while</span> (<span style="box-sizing: border-box;color: rgb(34, 17, 153)">true</span>) {  <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 需要通过 while(true) 进行循环保持不退出</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Log</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">info</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'Test process: running'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 相当于 PHP 的 sleep 函数,但是底层会自动启动协程,让出时间片,睡眠时间结束后恢复运行</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Coroutine</span>::<span style="box-sizing: border-box;color: rgb(51, 0, 170)">sleep</span>(<span style="box-sizing: border-box;color: rgb(17, 102, 68)">1</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 在自定义进程中调度任务, 但不支持任务的 finish 回调</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 注意:</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 1、第二个参数设置为 true,表示通过消息管道通信</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 2、在 config/laravels.php 配置文件中设置 task_ipc_mode 为 1 或 2</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// task_ipc_mode 用于设置 task worker 与 worker 进程之间的通信模式,1 表示通过 unix socket,2 表示使用消息队列</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$ret</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Task</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">deliver</span>(<span style="box-sizing: border-box;color: rgb(119, 0, 136)">new</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">TestTask</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'task data'</span>), <span style="box-sizing: border-box;color: rgb(34, 17, 153)">true</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(51, 0, 170)">var_dump</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$ret</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">            <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 上一层会捕获本函数抛出的异常并将其记录到 Swoole 日志中,如果异常数超过10个,该进程会退出,然后 Master 进程会重新创建这个进程</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    <span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">static</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">onReload</span>(<span style="box-sizing: border-box;color: rgb(0, 0, 0)">Server</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$swoole</span>, <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Process</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$process</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 结束进程</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$process</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(119, 0, 136)">exit</span>(<span style="box-sizing: border-box;color: rgb(17, 102, 68)">0</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>

注意:callback()方法不能退出,如果退出,Manager进程将会重新创建进程

第二步:注册

修改config/laravels.php

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 17, 17)">'processes'</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span> [</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    [</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'class'</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span>  <span style="box-sizing: border-box;color: rgb(0, 0, 0)">\App\Processes\TestProcess</span>::<span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span>,</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'redirect'</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span> <span style="box-sizing: border-box;color: rgb(34, 17, 153)">false</span>, <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 是否重定向输入输出</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'pipe'</span>     <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span> <span style="box-sizing: border-box;color: rgb(17, 102, 68)">0</span>,     <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 管道类型:0不创建管道,1创建SOCK_STREAM类型管道,2创建SOCK_DGRAM类型管道</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">        <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'enable'</span>   <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=></span> <span style="box-sizing: border-box;color: rgb(34, 17, 153)">true</span>,  <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 是否启用,默认true</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">    ],</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">],</span>

第三步:启动laravels

php bin/laravels start

第四步:查看laravel.log

<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">tail</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">f</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">laravel</span>.<span style="box-sizing: border-box;color: rgb(0, 0, 0)">log</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">[<span style="box-sizing: border-box;color: rgb(17, 102, 68)">2021</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">04</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">24</span> <span style="box-sizing: border-box;color: rgb(17, 102, 68)">16</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">34</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">06</span>] <span style="box-sizing: border-box;color: rgb(0, 0, 0)">local</span>.<span style="box-sizing: border-box;color: rgb(0, 0, 0)">INFO</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Test</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">process</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">running</span>  </span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">[<span style="box-sizing: border-box;color: rgb(17, 102, 68)">2021</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">04</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">24</span> <span style="box-sizing: border-box;color: rgb(17, 102, 68)">16</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">34</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">07</span>] <span style="box-sizing: border-box;color: rgb(0, 0, 0)">local</span>.<span style="box-sizing: border-box;color: rgb(0, 0, 0)">INFO</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">App\Jobs\TestTask</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">开始处理任务</span> [<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"task data"</span>] </span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">[<span style="box-sizing: border-box;color: rgb(17, 102, 68)">2021</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">04</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">24</span> <span style="box-sizing: border-box;color: rgb(17, 102, 68)">16</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">34</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">07</span>] <span style="box-sizing: border-box;color: rgb(0, 0, 0)">local</span>.<span style="box-sizing: border-box;color: rgb(0, 0, 0)">INFO</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Test</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">process</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">running</span>  </span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">[<span style="box-sizing: border-box;color: rgb(17, 102, 68)">2021</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">04</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">24</span> <span style="box-sizing: border-box;color: rgb(17, 102, 68)">16</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">34</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">08</span>] <span style="box-sizing: border-box;color: rgb(0, 0, 0)">local</span>.<span style="box-sizing: border-box;color: rgb(0, 0, 0)">INFO</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">App\Jobs\TestTask</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">开始处理任务</span> [<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"task data"</span>] </span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">[<span style="box-sizing: border-box;color: rgb(17, 102, 68)">2021</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">04</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">24</span> <span style="box-sizing: border-box;color: rgb(17, 102, 68)">16</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">34</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">08</span>] <span style="box-sizing: border-box;color: rgb(0, 0, 0)">local</span>.<span style="box-sizing: border-box;color: rgb(0, 0, 0)">INFO</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Test</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">process</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">running</span>  </span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">[<span style="box-sizing: border-box;color: rgb(17, 102, 68)">2021</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">04</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">24</span> <span style="box-sizing: border-box;color: rgb(17, 102, 68)">16</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">34</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">09</span>] <span style="box-sizing: border-box;color: rgb(0, 0, 0)">local</span>.<span style="box-sizing: border-box;color: rgb(0, 0, 0)">INFO</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Test</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">process</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">running</span>  </span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">[<span style="box-sizing: border-box;color: rgb(17, 102, 68)">2021</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">04</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">24</span> <span style="box-sizing: border-box;color: rgb(17, 102, 68)">16</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">34</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">09</span>] <span style="box-sizing: border-box;color: rgb(0, 0, 0)">local</span>.<span style="box-sizing: border-box;color: rgb(0, 0, 0)">INFO</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">App\Jobs\TestTask</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">开始处理任务</span> [<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"task data"</span>] </span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">[<span style="box-sizing: border-box;color: rgb(17, 102, 68)">2021</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">04</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(17, 102, 68)">24</span> <span style="box-sizing: border-box;color: rgb(17, 102, 68)">16</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">34</span>:<span style="box-sizing: border-box;color: rgb(17, 102, 68)">10</span>] <span style="box-sizing: border-box;color: rgb(0, 0, 0)">local</span>.<span style="box-sizing: border-box;color: rgb(0, 0, 0)">INFO</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Test</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">process</span>: <span style="box-sizing: border-box;color: rgb(0, 0, 0)">running</span>  </span>

由于使用swoole 协程,异步任务会每1秒执行一次且是异步非阻塞

请登录后再评论