php Swoole实现毫秒级定时任务
<p>项目开发中,如果有定时任务的业务要求,我们会使用linux的crontab来解决,但是它的最小粒度是分钟级别,如果要求粒度是秒级别的,甚至毫秒级别的,crontab就无法满足,值得庆幸的是swoole提供的强大的毫秒定时器。<br><br><strong>应用场景举例</strong><br>我们可能会遇到这样的场景:</p><ul>
<li>场景一:每隔30秒获取一次本机内存使用率</li>
<li>场景二:2分钟后执行报表发送任务</li>
<li>场景三:每天凌晨2点钟定时请求第三方接口,如果接口有数据返回则停止任务,如果接口由于某种原因没有响应或者没有数据返回则5分钟后继续尝试请求该接口,尝试5次后仍然失败则停止该任务</li>
</ul>
<p>以上的三个场景我们都可以归纳为定时任务的范畴。<br><br><strong>Swoole毫秒定时器</strong><br>Swoole提供了异步毫秒定时器函数:</p>
<p><code>swoole_timer_tick(int $msec, callable $callback)</code>:设置一个间隔时钟定时器,每隔$msec毫秒执行一次$callback,类似于javascript中的<code>setInterval()</code>。</p>
<p><code>swoole_timer_after(int $after_time_ms, mixed $callback_function)</code>:在指定的时间$after_time_ms后执行$callback_function,类似于javascript的<code>setTimeout()</code>。</p>
<p><code>swoole_timer_clear(int $timer_id)</code>:删除指定id的定时器,类似于javascript的<code>clearInterval()</code>。</p>
<h3><strong>解决方案</strong></h3>
<p>对于场景一,经常用在系统检测统计方面,实时性要求比较高,但又能控制好频率,多用于后台服务器性能监控,可以生成可视化图表。可以是30秒获取一次内存使用率,也可以是10秒,而crontab最小粒度只能设置为1分钟。</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_wrapper_has cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="9">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> swoole_timer_tick(30000, <span style="color: rgba(0, 0, 255, 1)">function</span>(<span style="color: rgba(128, 0, 128, 1)">$timer</span>) <span style="color: rgba(0, 0, 255, 1)">use</span> (<span style="color: rgba(128, 0, 128, 1)">$task_id</span>) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 启用定时器,每30秒执行一次</span>
<span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(128, 0, 128, 1)">$memPercent</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>->getMemoryUsage(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">计算内存使用率</span>
<span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(0, 128, 128, 1)">date</span>('Y-m-d H:i:s') . '当前内存使用率:'.<span style="color: rgba(128, 0, 128, 1)">$memPercent</span>."\n"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">4</span> });</pre>
</div>
<p> </p>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p> </p>
<p>对于场景二,直接定义xx时间后执行某项任务的话,貌似crontab比较困难,而使用swoole的<code>swoole_timer_after</code>可以实现:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_wrapper_has cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="8">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> swoole_timer_after(120000, <span style="color: rgba(0, 0, 255, 1)">function</span>() <span style="color: rgba(0, 0, 255, 1)">use</span> (<span style="color: rgba(128, 0, 128, 1)">$str</span>) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">2分钟后执行</span>
<span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->sendReport(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">发送报表</span>
<span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 255, 1)">echo</span> "send report, <span style="color: rgba(128, 0, 128, 1)">$str</span>\n"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">4</span> });</pre>
</div>
<p> </p>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>对于场景三,用来作尝试请求,请求失败后继续,如果成功则停止请求。用crontab也能解决,但是比较傻,比如设置每隔5分钟请求一次,不管成功会失败都会去执行一次。而用swoole定时器则智能多了。</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_wrapper_has cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="7">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> swoole_timer_tick(5*60*1000, <span style="color: rgba(0, 0, 255, 1)">function</span>(<span style="color: rgba(128, 0, 128, 1)">$timer</span>) <span style="color: rgba(0, 0, 255, 1)">use</span> (<span style="color: rgba(128, 0, 128, 1)">$url</span>) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 启用定时器,每5分钟执行一次</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(128, 0, 128, 1)">$rs</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>->postUrl(<span style="color: rgba(128, 0, 128, 1)">$url</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(128, 0, 128, 1)">$rs</span><span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">业务代码...</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> swoole_timer_clear(<span style="color: rgba(128, 0, 128, 1)">$timer</span>); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 停止定时器</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(0, 128, 128, 1)">date</span>('Y-m-d H:i:s'). "请求接口任务执行成功\n"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> } <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(0, 128, 128, 1)">date</span>('Y-m-d H:i:s'). "请求接口失败,5分钟后再次尝试\n"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">11</span> });</pre>
</div>
<p> </p>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<h3><strong>示例代码</strong></h3>
<p>新建文件\src\App\Task.php:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_wrapper_has cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="6">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 0, 1)">namespace Helloweba\Swoole;
</span><span style="color: rgba(0, 128, 128, 1)">3</span>
<span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> swoole_server;
</span><span style="color: rgba(0, 128, 128, 1)">5</span>
<span style="color: rgba(0, 128, 128, 1)">6</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)">7</span> <span style="color: rgba(0, 128, 0, 1)">* 任务调度
</span><span style="color: rgba(0, 128, 128, 1)">8</span> <span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)">9</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Task
</span><span style="color: rgba(0, 128, 128, 1)"> 10</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)"> 11</span> <span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(128, 0, 128, 1)">$serv</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 12</span> <span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(128, 0, 128, 1)">$host</span> = '127.0.0.1'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 13</span> <span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(128, 0, 128, 1)">$port</span> = 9506<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 14</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 进程名称</span>
<span style="color: rgba(0, 128, 128, 1)"> 15</span> <span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(128, 0, 128, 1)">$taskName</span> = 'swooleTask'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 16</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> PID路径</span>
<span style="color: rgba(0, 128, 128, 1)"> 17</span> <span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(128, 0, 128, 1)">$pidPath</span> = '/run/swooletask.pid'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 18</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置运行时参数</span>
<span style="color: rgba(0, 128, 128, 1)"> 19</span> <span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(128, 0, 128, 1)">$options</span> =<span style="color: rgba(0, 0, 0, 1)"> [
</span><span style="color: rgba(0, 128, 128, 1)"> 20</span> 'worker_num' => 4, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">worker进程数,一般设置为CPU数的1-4倍</span>
<span style="color: rgba(0, 128, 128, 1)"> 21</span> 'daemonize' => <span style="color: rgba(0, 0, 255, 1)">true</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">启用守护进程</span>
<span style="color: rgba(0, 128, 128, 1)"> 22</span> 'log_file' => '/data/log/swoole-task.log', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">指定swoole错误日志文件</span>
<span style="color: rgba(0, 128, 128, 1)"> 23</span> 'log_level' => 0, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">日志级别 范围是0-5,0-DEBUG,1-TRACE,2-INFO,3-NOTICE,4-WARNING,5-ERROR</span>
<span style="color: rgba(0, 128, 128, 1)"> 24</span> 'dispatch_mode' => 1, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">数据包分发策略,1-轮询模式</span>
<span style="color: rgba(0, 128, 128, 1)"> 25</span> 'task_worker_num' => 4, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">task进程的数量</span>
<span style="color: rgba(0, 128, 128, 1)"> 26</span> 'task_ipc_mode' => 3, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">使用消息队列通信,并设置为争抢模式</span>
<span style="color: rgba(0, 128, 128, 1)"> 27</span> <span style="color: rgba(0, 0, 0, 1)"> ];
</span><span style="color: rgba(0, 128, 128, 1)"> 28</span>
<span style="color: rgba(0, 128, 128, 1)"> 29</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> __construct(<span style="color: rgba(128, 0, 128, 1)">$options</span> =<span style="color: rgba(0, 0, 0, 1)"> [])
</span><span style="color: rgba(0, 128, 128, 1)"> 30</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 31</span> date_default_timezone_set('PRC'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)"> 32</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 构建Server对象,监听127.0.0.1:9506端口</span>
<span style="color: rgba(0, 128, 128, 1)"> 33</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->serv = <span style="color: rgba(0, 0, 255, 1)">new</span> swoole_server(<span style="color: rgba(128, 0, 128, 1)">$this</span>->host, <span style="color: rgba(128, 0, 128, 1)">$this</span>-><span style="color: rgba(0, 0, 0, 1)">port);
</span><span style="color: rgba(0, 128, 128, 1)"> 34</span>
<span style="color: rgba(0, 128, 128, 1)"> 35</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 255, 1)">empty</span>(<span style="color: rgba(128, 0, 128, 1)">$options</span><span style="color: rgba(0, 0, 0, 1)">)) {
</span><span style="color: rgba(0, 128, 128, 1)"> 36</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->options = <span style="color: rgba(0, 128, 128, 1)">array_merge</span>(<span style="color: rgba(128, 0, 128, 1)">$this</span>->options, <span style="color: rgba(128, 0, 128, 1)">$options</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)"> 37</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 38</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->serv->set(<span style="color: rgba(128, 0, 128, 1)">$this</span>-><span style="color: rgba(0, 0, 0, 1)">options);
</span><span style="color: rgba(0, 128, 128, 1)"> 39</span>
<span style="color: rgba(0, 128, 128, 1)"> 40</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 注册事件</span>
<span style="color: rgba(0, 128, 128, 1)"> 41</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->serv->on('Start', [<span style="color: rgba(128, 0, 128, 1)">$this</span>, 'onStart'<span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 128, 128, 1)"> 42</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->serv->on('Connect', [<span style="color: rgba(128, 0, 128, 1)">$this</span>, 'onConnect'<span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 128, 128, 1)"> 43</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->serv->on('Receive', [<span style="color: rgba(128, 0, 128, 1)">$this</span>, 'onReceive'<span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 128, 128, 1)"> 44</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->serv->on('Task', [<span style="color: rgba(128, 0, 128, 1)">$this</span>, 'onTask'<span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 128, 128, 1)"> 45</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->serv->on('Finish', [<span style="color: rgba(128, 0, 128, 1)">$this</span>, 'onFinish'<span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 128, 128, 1)"> 46</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->serv->on('Close', [<span style="color: rgba(128, 0, 128, 1)">$this</span>, 'onClose'<span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 128, 128, 1)"> 47</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 48</span>
<span style="color: rgba(0, 128, 128, 1)"> 49</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> start()
</span><span style="color: rgba(0, 128, 128, 1)"> 50</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 51</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Run worker</span>
<span style="color: rgba(0, 128, 128, 1)"> 52</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->serv-><span style="color: rgba(0, 0, 0, 1)">start();
</span><span style="color: rgba(0, 128, 128, 1)"> 53</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 54</span>
<span style="color: rgba(0, 128, 128, 1)"> 55</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> onStart(<span style="color: rgba(128, 0, 128, 1)">$serv</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)"> 56</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 57</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置进程名</span>
<span style="color: rgba(0, 128, 128, 1)"> 58</span> cli_set_process_title(<span style="color: rgba(128, 0, 128, 1)">$this</span>-><span style="color: rgba(0, 0, 0, 1)">taskName);
</span><span style="color: rgba(0, 128, 128, 1)"> 59</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">记录进程id,脚本实现自动重启</span>
<span style="color: rgba(0, 128, 128, 1)"> 60</span> <span style="color: rgba(128, 0, 128, 1)">$pid</span> = "{<span style="color: rgba(128, 0, 128, 1)">$serv</span>->master_pid}\n{<span style="color: rgba(128, 0, 128, 1)">$serv</span>->manager_pid}"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 61</span> <span style="color: rgba(0, 128, 128, 1)">file_put_contents</span>(<span style="color: rgba(128, 0, 128, 1)">$this</span>->pidPath, <span style="color: rgba(128, 0, 128, 1)">$pid</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)"> 62</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 63</span>
<span style="color: rgba(0, 128, 128, 1)"> 64</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">监听连接进入事件</span>
<span style="color: rgba(0, 128, 128, 1)"> 65</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> onConnect(<span style="color: rgba(128, 0, 128, 1)">$serv</span>, <span style="color: rgba(128, 0, 128, 1)">$fd</span>, <span style="color: rgba(128, 0, 128, 1)">$from_id</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)"> 66</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 67</span> <span style="color: rgba(128, 0, 128, 1)">$serv</span>->send( <span style="color: rgba(128, 0, 128, 1)">$fd</span>, "Hello {<span style="color: rgba(128, 0, 128, 1)">$fd</span>}!"<span style="color: rgba(0, 0, 0, 1)"> );
</span><span style="color: rgba(0, 128, 128, 1)"> 68</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 69</span>
<span style="color: rgba(0, 128, 128, 1)"> 70</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 监听数据接收事件</span>
<span style="color: rgba(0, 128, 128, 1)"> 71</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> onReceive(swoole_server <span style="color: rgba(128, 0, 128, 1)">$serv</span>, <span style="color: rgba(128, 0, 128, 1)">$fd</span>, <span style="color: rgba(128, 0, 128, 1)">$from_id</span>, <span style="color: rgba(128, 0, 128, 1)">$data</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)"> 72</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 73</span> <span style="color: rgba(0, 0, 255, 1)">echo</span> "Get Message From Client {<span style="color: rgba(128, 0, 128, 1)">$fd</span>}:{<span style="color: rgba(128, 0, 128, 1)">$data</span>}\n"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 74</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">$this->writeLog('接收客户端参数:'.$fd .'-'.$data);</span>
<span style="color: rgba(0, 128, 128, 1)"> 75</span> <span style="color: rgba(128, 0, 128, 1)">$res</span>['result'] = 'success'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 76</span> <span style="color: rgba(128, 0, 128, 1)">$serv</span>->send(<span style="color: rgba(128, 0, 128, 1)">$fd</span>, json_encode(<span style="color: rgba(128, 0, 128, 1)">$res</span>)); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 同步返回消息给客户端</span>
<span style="color: rgba(0, 128, 128, 1)"> 77</span> <span style="color: rgba(128, 0, 128, 1)">$serv</span>->task(<span style="color: rgba(128, 0, 128, 1)">$data</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 执行异步任务</span>
<span style="color: rgba(0, 128, 128, 1)"> 78</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 79</span>
<span style="color: rgba(0, 128, 128, 1)"> 80</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 81</span> <span style="color: rgba(0, 128, 0, 1)"> * @param $serv swoole_server swoole_server对象
</span><span style="color: rgba(0, 128, 128, 1)"> 82</span> <span style="color: rgba(0, 128, 0, 1)"> * @param $task_id int 任务id
</span><span style="color: rgba(0, 128, 128, 1)"> 83</span> <span style="color: rgba(0, 128, 0, 1)"> * @param $from_id int 投递任务的worker_id
</span><span style="color: rgba(0, 128, 128, 1)"> 84</span> <span style="color: rgba(0, 128, 0, 1)"> * @param $data string 投递的数据
</span><span style="color: rgba(0, 128, 128, 1)"> 85</span> <span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 86</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> onTask(swoole_server <span style="color: rgba(128, 0, 128, 1)">$serv</span>, <span style="color: rgba(128, 0, 128, 1)">$task_id</span>, <span style="color: rgba(128, 0, 128, 1)">$from_id</span>, <span style="color: rgba(128, 0, 128, 1)">$data</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)"> 87</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 88</span> swoole_timer_tick(30000, <span style="color: rgba(0, 0, 255, 1)">function</span>(<span style="color: rgba(128, 0, 128, 1)">$timer</span>) <span style="color: rgba(0, 0, 255, 1)">use</span> (<span style="color: rgba(128, 0, 128, 1)">$task_id</span>) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 启用定时器,每30秒执行一次</span>
<span style="color: rgba(0, 128, 128, 1)"> 89</span> <span style="color: rgba(128, 0, 128, 1)">$memPercent</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>-><span style="color: rgba(0, 0, 0, 1)">getMemoryUsage();
</span><span style="color: rgba(0, 128, 128, 1)"> 90</span> <span style="color: rgba(0, 0, 255, 1)">echo</span> <span style="color: rgba(0, 128, 128, 1)">date</span>('Y-m-d H:i:s') . '当前内存使用率:'.<span style="color: rgba(128, 0, 128, 1)">$memPercent</span>."\n"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 91</span> <span style="color: rgba(0, 0, 0, 1)"> });
</span><span style="color: rgba(0, 128, 128, 1)"> 92</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 93</span>
<span style="color: rgba(0, 128, 128, 1)"> 94</span>
<span style="color: rgba(0, 128, 128, 1)"> 95</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 96</span> <span style="color: rgba(0, 128, 0, 1)"> * @param $serv swoole_server swoole_server对象
</span><span style="color: rgba(0, 128, 128, 1)"> 97</span> <span style="color: rgba(0, 128, 0, 1)"> * @param $task_id int 任务id
</span><span style="color: rgba(0, 128, 128, 1)"> 98</span> <span style="color: rgba(0, 128, 0, 1)"> * @param $data string 任务返回的数据
</span><span style="color: rgba(0, 128, 128, 1)"> 99</span> <span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)">100</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> onFinish(swoole_server <span style="color: rgba(128, 0, 128, 1)">$serv</span>, <span style="color: rgba(128, 0, 128, 1)">$task_id</span>, <span style="color: rgba(128, 0, 128, 1)">$data</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">101</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">102</span> <span style="color: rgba(0, 128, 0, 1)">//
</span><span style="color: rgba(0, 128, 128, 1)">103</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">104</span>
<span style="color: rgba(0, 128, 128, 1)">105</span>
<span style="color: rgba(0, 128, 128, 1)">106</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 监听连接关闭事件</span>
<span style="color: rgba(0, 128, 128, 1)">107</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span> onClose(<span style="color: rgba(128, 0, 128, 1)">$serv</span>, <span style="color: rgba(128, 0, 128, 1)">$fd</span>, <span style="color: rgba(128, 0, 128, 1)">$from_id</span><span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 128, 1)">108</span> <span style="color: rgba(0, 0, 255, 1)">echo</span> "Client {<span style="color: rgba(128, 0, 128, 1)">$fd</span>} close connection\n"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">109</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">110</span>
<span style="color: rgba(0, 128, 128, 1)">111</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> stop()
</span><span style="color: rgba(0, 128, 128, 1)">112</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">113</span> <span style="color: rgba(128, 0, 128, 1)">$this</span>->serv-><span style="color: rgba(0, 0, 0, 1)">stop();
</span><span style="color: rgba(0, 128, 128, 1)">114</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">115</span>
<span style="color: rgba(0, 128, 128, 1)">116</span> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getMemoryUsage()
</span><span style="color: rgba(0, 128, 128, 1)">117</span> <span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">118</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> MEMORY</span>
<span style="color: rgba(0, 128, 128, 1)">119</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">false</span> === (<span style="color: rgba(128, 0, 128, 1)">$str</span> = @<span style="color: rgba(0, 128, 128, 1)">file</span>("/proc/meminfo"))) <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">120</span> <span style="color: rgba(128, 0, 128, 1)">$str</span> = <span style="color: rgba(0, 128, 128, 1)">implode</span>("", <span style="color: rgba(128, 0, 128, 1)">$str</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">121</span> <span style="color: rgba(0, 128, 128, 1)">preg_match_all</span>("/MemTotal\s{0,}\:+\s{0,}([\d\.]+).+?MemFree\s{0,}\:+\s{0,}([\d\.]+).+?Cached\s{0,}\:+\s{0,}([\d\.]+).+?SwapTotal\s{0,}\:+\s{0,}([\d\.]+).+?SwapFree\s{0,}\:+\s{0,}([\d\.]+)/s", <span style="color: rgba(128, 0, 128, 1)">$str</span>, <span style="color: rgba(128, 0, 128, 1)">$buf</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">122</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">preg_match_all("/Buffers\s{0,}\:+\s{0,}([\d\.]+)/s", $str, $buffers);</span>
<span style="color: rgba(0, 128, 128, 1)">123</span>
<span style="color: rgba(0, 128, 128, 1)">124</span> <span style="color: rgba(128, 0, 128, 1)">$memTotal</span> = <span style="color: rgba(0, 128, 128, 1)">round</span>(<span style="color: rgba(128, 0, 128, 1)">$buf</span>/1024, 2<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">125</span> <span style="color: rgba(128, 0, 128, 1)">$memFree</span> = <span style="color: rgba(0, 128, 128, 1)">round</span>(<span style="color: rgba(128, 0, 128, 1)">$buf</span>/1024, 2<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">126</span> <span style="color: rgba(128, 0, 128, 1)">$memUsed</span> = <span style="color: rgba(128, 0, 128, 1)">$memTotal</span> - <span style="color: rgba(128, 0, 128, 1)">$memFree</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">127</span> <span style="color: rgba(128, 0, 128, 1)">$memPercent</span> = (<span style="color: rgba(0, 128, 128, 1)">floatval</span>(<span style="color: rgba(128, 0, 128, 1)">$memTotal</span>)!=0) ? <span style="color: rgba(0, 128, 128, 1)">round</span>(<span style="color: rgba(128, 0, 128, 1)">$memUsed</span>/<span style="color: rgba(128, 0, 128, 1)">$memTotal</span>*100,2):0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">128</span>
<span style="color: rgba(0, 128, 128, 1)">129</span> <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">$memPercent</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">130</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">131</span> }</pre>
</div>
<p> </p>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p> </p>
<p>我们以场景一为例,在<code>onTask</code>启用定时任务,每隔30秒计算一次内存使用率。实际应用中可以把计算好的内存按时间写入数据库等存储中,然后可以根据前端需求用来渲染成统计图表,如:</p>
<p><span class="cke_widget_wrapper cke_widget_inline cke_widget_image cke_image_nocaption cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="图像" data-cke-widget-id="5"><img class="has cke_widget_element lazyload" alt="" width="655" height="400" src="https://img-blog.csdnimg.cn/20191121143100626.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzgxNDQ1OA==,size_16,color_FFFFFF,t_70" data-cke-widget-data="{&quot;hasCaption&quot;:false,&quot;src&quot;:&quot;https://img-blog.csdnimg.cn/20191121143100626.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzgxNDQ1OA==,size_16,color_FFFFFF,t_70&quot;,&quot;alt&quot;:&quot;&quot;,&quot;width&quot;:&quot;655&quot;,&quot;height&quot;:&quot;400&quot;,&quot;lock&quot;:true,&quot;align&quot;:&quot;none&quot;,&quot;classes&quot;:{&quot;has&quot;:1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="image" data-src="https://img-blog.csdnimg.cn/20191121143100626.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzgxNDQ1OA==,size_16,color_FFFFFF,t_70"><span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="><span class="cke_image_resizer" title="点击并拖拽以改变尺寸"></span></span></span></p>
<p><br><br></p>
<p>接着服务端代码 public\taskServer.php :</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_wrapper_has cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="4">
<div class="cnblogs_code">
<pre><?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(0, 0, 255, 1)">require</span> <span style="color: rgba(0, 128, 128, 1)">dirname</span>(__DIR__) . '/vendor/autoload.php'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">use</span><span style="color: rgba(0, 0, 0, 1)"> Helloweba\Swoole\Task;
</span><span style="color: rgba(128, 0, 128, 1)">$opt</span> =<span style="color: rgba(0, 0, 0, 1)"> [
</span>'daemonize' => <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
];
</span><span style="color: rgba(128, 0, 128, 1)">$ser</span> = <span style="color: rgba(0, 0, 255, 1)">new</span> Task(<span style="color: rgba(128, 0, 128, 1)">$opt</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 0, 128, 1)">$ser</span>->start();</pre>
</div>
<p> </p>
<img class="cke_reset cke_widget_drag_handler lazyload" style="font-family: "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></div>
<p> </p>
<p>客户端代码 public\taskClient.php :</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_wrapper_has cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="3">
<div class="cnblogs_code">
<pre><?<span style="color: rgba(0, 0, 0, 1)">php
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Client
{
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(128, 0, 128, 1)">$client</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> __construct() {
</span><span style="color: rgba(128, 0, 128, 1)">$this</span>->client = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> swoole_client(SWOOLE_SOCK_TCP);
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> connect() {
</span><span style="color: rgba(0, 0, 255, 1)">if</span>( !<span style="color: rgba(128, 0, 128, 1)">$this</span>->client->connect("127.0.0.1", 9506 , 1<span style="color: rgba(0, 0, 0, 1)">) ) {
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "Error: {<span style="color: rgba(128, 0, 128, 1)">$this</span>->client->errMsg}[{<span style="color: rgba(128, 0, 128, 1)">$this</span>->client->errCode}]\n"<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 128, 1)">fwrite</span>(STDOUT, "请输入消息 Please input msg:"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(128, 0, 128, 1)">$msg</span> = <span style="color: rgba(0, 128, 128, 1)">trim</span>(<span style="color: rgba(0, 128, 128, 1)">fgets</span><span style="color: rgba(0, 0, 0, 1)">(STDIN));
</span><span style="color: rgba(128, 0, 128, 1)">$this</span>->client->send( <span style="color: rgba(128, 0, 128, 1)">$msg</span><span style="color: rgba(0, 0, 0, 1)"> );
</span><span style="color: rgba(128, 0, 128, 1)">$message</span> = <span style="color: rgba(128, 0, 128, 1)">$this</span>->client-><span style="color: rgba(0, 0, 0, 1)">recv();
</span><span style="color: rgba(0, 0, 255, 1)">echo</span> "Get Message From Server:{<span style="color: rgba(128, 0, 128, 1)">$message</span>}\n"<span style="color: rgba(0, 0, 0, 1)">;
}
}
</span><span style="color: rgba(128, 0, 128, 1)">$client</span> = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Client();
</span><span style="color: rgba(128, 0, 128, 1)">$client</span>->connect();</pre>
</div>
<p> </p>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<h3><strong>验证效果</strong></h3>
<p>1.启动服务端:</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_wrapper_has cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="2">
<div class="cnblogs_code">
<pre>php taskServer.php</pre>
</div>
<p> </p>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>2.客户端输入:</p>
<p>另开命令行窗口,执行</p>
<div class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_wrapper_has cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="代码段" data-cke-widget-id="1">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> php taskClient.php </span>
<span style="color: rgba(0, 0, 0, 1)">请输入消息 Please input msg:hello
Get Message From Server</span>:{"result":"success"<span style="color: rgba(0, 0, 0, 1)">}
<span style="color: rgba(0, 128, 0, 1)">#</span> </pre>
</div>
<p> </p>
<span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="></span></div>
<p>3.服务端返回:</p>
<p><span class="cke_widget_wrapper cke_widget_inline cke_widget_image cke_image_nocaption cke_widget_selected" data-cke-widget-wrapper="1" data-cke-filter="off" data-cke-display-name="图像" data-cke-widget-id="0"><img class="has cke_widget_element lazyload" alt="" width="631" height="217" src="https://img-blog.csdnimg.cn/20191121143724919.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzgxNDQ1OA==,size_16,color_FFFFFF,t_70" data-cke-widget-data="{&quot;hasCaption&quot;:false,&quot;src&quot;:&quot;https://img-blog.csdnimg.cn/20191121143724919.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzgxNDQ1OA==,size_16,color_FFFFFF,t_70&quot;,&quot;alt&quot;:&quot;&quot;,&quot;width&quot;:&quot;631&quot;,&quot;height&quot;:&quot;217&quot;,&quot;lock&quot;:true,&quot;align&quot;:&quot;none&quot;,&quot;classes&quot;:{&quot;has&quot;:1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="image" data-src="https://img-blog.csdnimg.cn/20191121143724919.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzgxNDQ1OA==,size_16,color_FFFFFF,t_70"><span class="cke_reset cke_widget_drag_handler_container"><img class="cke_reset cke_widget_drag_handler lazyload" title="点击并拖拽以移动" alt="" width="15" height="15" data-cke-widget-drag-handler="1" data-src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw=="><span class="cke_image_resizer" title="点击并拖拽以改变尺寸"></span></span></span></p>
<p>如果返回上图中的结果,则定时任务正常运行,我们会发现每隔30秒会输出一条信息。</p>
<p> </p>
<p>很<strong>多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的加群(点击→)677079770</strong></p><br><br>
来源:https://www.cnblogs.com/a609251438/p/11905592.html
頁:
[1]