Yii2的非同步多執行緒服務之swoole

2021-07-11 02:25:20 字數 4941 閱讀 1412

廢話不多說,進入正題。做**開發時,發現有很多後端功能需要一直在執行,起初是使用的crontab定時執行,後來功能越來越多crontab已經不能滿足需求。比如**的一些傳送簡訊、郵件等功能,都需要curl經過網路通訊的,網路不好、高併發時不非同步處理會阻塞程序,所以考慮引入些開源的非同步多執行緒服務swoole。

引入swoole的目的是只用它建立乙個server非同步伺服器,對資料庫等功能性操作使用原來的yii2框架。以下主要從swoole定時器、tcp的非同步多執行緒通訊做簡單介紹。

swoole是目前比較新的乙個php非同步處理框架,由國內人員開發,」新「->就會導致它前期版本有很多bug,不過現在提供的幾個版本已經很穩定了。話說剛開始接觸yii2做**時,連個socket通訊都沒~感覺怪怪的,接觸swoole後發現,終於找回了些以前做c/c++的感覺。(哦~原來你在這裡!)

借用官網的定義swoole重新定義了php,它是php的非同步、並行、高效能網路通訊引擎,使用純c語言編寫,提供了php語言的非同步多執行緒伺服器,非同步tcp/udp網路客戶端,非同步mysql,非同步redis,資料庫連線池,asynctask,訊息佇列,毫秒定時器,非同步檔案讀寫,非同步dns查詢。

server端

由於swoole服務端只能執行在cli模式下(有興趣的可以了解下php的執行模式cli命令列執行和fastcgi常駐型cgi,後者就是我們常說的fpm),而yii2的console支援控制台命令,這樣就可以通過指令碼啟動swoole的server,和乙個yii2的console應用將兩者結合起來。

通過指令碼啟動乙個tcp的swoole_server,和乙個yii2的終端應用。

$this->serv = new swoole_server("127.0.0.1", cc_swoole_port );

$this->serv->set(array(

'worker_num' => 8,

'task_worker_num' => 8,

'daemonize' => 1,

'max_request' => 10000,

'dispatch_mode' => 2,

'debug_mode'=> 1,

'log_file' => __dir__."/runtime/swoole.log",

));$this->serv->start();

public function __construct()

...}

server端首先會建立乙個master程序(pid=9747,可在onstart中通過swoole_set_process_name重新命名程序),保證swoole框架的執行,從下圖可以看出,它建立了乙個pid=9748程序,這是個manager程序,他是所有worker/task程序的父程序,它的主要作用是**子程序,避免殭屍程序,並在伺服器關閉時傳送signal通知子程序關閉(可以kill -9 9748會發現其它work程序都會關閉)。剩下的是8個worker程序和8個task程序,用於非同步處理來自client端的資料。

root      9747

10 apr15 ? 00:00:01 masterswooleserver

root 9748

9747

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9758

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9759

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9760

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9761

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9762

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9763

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9764

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9765

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9766

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9767

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9768

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9769

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9770

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9771

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 9772

9748

0 apr15 ? 00:00:00 php swoole/swooleserver.php

root 22094

9748

010:22 ? 00:00:13 php swoole/swooleserver.php

定時器
public

function

onworkerstart

( $serv , $worker_id) );

}}

非同步伺服器

在處理前端高併發非同步任務時,前端通過建立client端將訊息傳送到server,由server端的worker程序處理,在worker程序中可通過console物件去處理yii的功能/或者執行自己的非同步任務。由於前面配置了8個worker程序,swoole中會有8個worker程序的receive處理,如果併發請求超過8個,swoole會按照佇列方式處理。如果你要處理的內容耗時很長或者併發量很大,可以在worker程序receive後丟到task程序去處理。

public

function

onreceive

( swoole_server $serv, $fd, $from_id, $data ) else

}

client端

client端主要用於處理yii2前端**耗時的功能(發簡訊/郵件等),將訊息傳送給server由server接受到訊息後去處理。

起先使用的方法是

$client = new swoole_client(swoole_sock_tcp, swoole_sock_async); //非同步非阻塞考慮到client端和server端都是在一台伺服器上,走同步tcp本地socket也很快,並且同步swoole_client支援在fpm下執行。優化後採用長鏈結方式去做client端,防止自己處理fd出現bug,client端也不用斷開,fd重複利用。

$client

=new swoole_client(swoole_sock_tcp | swoole_keep);

$client

->connect('127.0.0.1', cc_swoole_port, 0.5);

$client

->send($msg);

以上是通過tcp通訊做的,swoole還增加了乙個程序管理模組,用來替代php的pcntl擴充套件,api封裝的簡單易用,server端可以通過swoole_process建立的子程序中去處理功能,前端通過swoole_process->usequeue訊息佇列模式,將訊息swoole_process->push(string $data)到佇列中,server端取佇列處理資料。具體介面可以檢視這裡。

server端的掛掉自啟動,前期swoole版本會經常內部庫堆疊崩潰,導致伺服器掛掉,影響線上功能,故配置了server的定時檢測功能,以下是在crontab中配置的檢測伺服器執行狀態的,也可以自己寫乙個單獨的守護程序指令碼去執行。

#!/usr/bin/env sh

processcount=`ps -ef | grep masterswooleserver | grep -v grep | wc -l`

if [ $processcount

-lt1 ];

then

ps -eaf |grep "swooleserver.php" | grep -v "grep"| awk ''|xargs kill -9

sleep 2

ulimit -c unlimited

echo

"restart";

fi

...

$this->serv->start();

錯誤:

...

$this->serv->start();

yii2框架 yii2自身的自動載入 三

上一節說完了composer的自動載入,下面我們來說一下yii2自身的自動載入。在我們的入口檔案,例如index.php,如下 comment out the following two lines when deployed to production defined yii debug or d...

yii2框架 yii2的asset資源包 十一

link license license use yii web assetbundle author qiang xue since 2.0 定義按需載入css方法,注意載入順序在最後 public static function addcss view,cssfile 將需要載入的檔案已陣列聚合...

yii2框架 yii2的主題化設計 十九

最近發現漏了很重要的一章章節知識點 關於yii2的主題化設計。所謂的主題話設計簡單點說就是通過設定不同的模板主題,可以快速切換,無需更改檢視渲染 的方法。在yii2中使用主題,首先要配置主題,在components中 view theme baseurl web themes blue pathma...