swoole進程關系梳理

基于上一篇文章swoole+tp5異步多線程,發現很多問題,所以深入理解一下swoole的進程模型

想探討一下swoole,swoole在大流量生產環境下需要哪些特別注意的地方, 求指導,聯系我就可以

運行環境linux? 服務開啟命令? php think Tcp

namespace app\swoole\command;

use app\common\cache\Redis;

use think\console\Command;

use think\console\Input;

use think\console\Output;

use think\Db;

use think\Log;

class Tcp extends Command{

TP5命令行使用方法,手冊可以查到,原理是加載文件并執行文件

? ? protected function configure(){

? ? ? ? $this->setName('Tcp')->setDescription('OK ');

? ? }

? ? public function execute(Input $input, Output $output){

參數配置

? ? ? ? $serv = new \swoole_server("0.0.0.0", 9501);

? ? ? ? $serv->set([

? ? ? ? ? ? 'reactor_num' => 1,//同服務器核心數

? ? ? ? ? ? 'worker_num' => 2,//同服務器核心數或1--4倍服務器核心數

? ? ? ? ? ? 'task_worker_num' => 4,//當task繁忙導致server沒有響應請求時,可以適當增加num,具體根據官方文檔和試運行情況修改

? ? ? ? ? ? 'backlog' => 128,

? ? ? ? ? ? 'daemonize' => 0,//加入此參數后,執行php server.php將轉入后臺作為守護進程運行

? ? ? ? ? ? 'max_conn' => 10000,//此參數用來設置Server最大允許維持多少個tcp連接。超過此數量后,新進入的連接將被拒絕。

? ? ? ? ? ? 'max_request' => 2000,//此參數表示worker進程在處理完n次請求后結束運行。manager會重新創建一個worker進程。此選項用來防止worker進程內存溢出。

//? ? ? ? ? 'log_file' => '/data/log/Swoole.log',//指定swoole錯誤日志文件。在swoole運行期發生的異常信息會記錄到這個文件中。默>認會打印到屏幕。

? ? ? ? ? ? 'heartbeat_check_interval' => 30,//每隔多少秒檢測一次,單位秒,Swoole會輪詢所有TCP連接,將超過心跳時間的連接關閉掉

? ? ? ? ? ? 'heartbeat_idle_time' => 60,//TCP連接的最大閑置時間,單位s , 如果某fd最后一次發包距離現在的時間超過? ? heartbeat_idle_time必須大于或等于heartbeat_check_interval

? ? ? ? ? ? 'task_max_request' => 100,//設置task進程的最大任務數。一個task進程在處理完超過此數值的任務后將自動退出。這個參數是為了防止PHP進程內存溢出。如果不希望進程自動退出可以設置為0。

? ? ? ? ? ? 'open_cpu_affinity' => 1,//啟用CPU親和性設置。在多核的硬件平臺中,啟用此特性會將swoole的reactor線程/worker進程綁定到固定的一個核上。可以避免進程/線程的運行時在多個核之間互相切換,提高CPU Cache的命中率。

? ? ? ? ]);

常用方法的回調函數

? ? ? ? $serv->on('start', function ($serv){

? ? ? ? ? ? $this->timter();

? ? ? ? ? ? echo "第一步master進程被拉起\n";

? ? ? ? });

注意:如果manager進程和worker進程存在多個,請不要在manager和worker進程中開啟全局任務

? ? ? ? $serv->on('ManagerStart', function ($serv){

? ? ? ? ? ? echo "第二步指定數目的調度reactor進程被拉起\n";

? ? ? ? });

? ? ? ? $serv->on('WorkerStart', function ($serv){

? ? ? ? ? ? echo "第三步指定數目的worker進程被拉起\n";

? ? ? ? });

? ? ? ? $serv->on('WorkerStop', function (){

? ? ? ? ? ? echo "第四步指定數目的worker進程被kill\n";

? ? ? ? });

? ? ? ? $serv->on('ManagerStop', function (){

? ? ? ? ? ? echo "第五步指定數目的reactor進程被kill\n";

? ? ? ? });

? ? ? ? $serv->on('shutdown', function (){

? ? ? ? ? ? echo "第六步master進程被kill\n";

? ? ? ? });

? ? ? ? $serv->on('receive', function($serv, $fd, $from_id, $data) {

? ? ? ? ? ? if(intval($data) == '9501'){

? ? ? ? ? ? ? ? $serv->reload();//觸發worker進程的stop方法

//? ? ? ? ? ? ? ? $serv->shutdown();//觸發所有進程的stop及shutdown方法

? ? ? ? ? ? ? ? return;

? ? ? ? ? ? }

? ? ? ? ? ? //投遞異步任務

? ? ? ? ? ? $task_id = $serv->task($data);

? ? ? ? ? ? echo "任務".$task_id."開始\n";

? ? ? ? });

? ? ? ? //模擬處理異步任務

? ? ? ? $serv->on('task', function ($serv, $task_id, $from_id, $data) {

? ? ? ? ? ? $begin = intval($data);

? ? ? ? ? ? $insertAll = [];

? ? ? ? ? ? for ($i = $begin; $i < $begin+20000; $i++){

? ? ? ? ? ? ? ? $insert = array();

? ? ? ? ? ? ? ? $insert['value'] = $i.mt_rand($i, $i+1000);

? ? ? ? ? ? ? ? $insert['addtime'] = time();

? ? ? ? ? ? ? ? $insert['from_id'] = $from_id;

? ? ? ? ? ? ? ? $insert['task_id'] = $task_id;

? ? ? ? ? ? ? ? $insertAll[] = $insert;

//? ? ? ? ? ? ? ? Db::table('test')->insert($insert);

? ? ? ? ? ? }

? ? ? ? ? ? Db::table('test')->insertAll($insertAll);

? ? ? ? ? ? //返回任務執行的結果

? ? ? ? ? ? unset($insertAll);

? ? ? ? ? ? $serv->finish("ID".$task_id);

? ? ? ? });

? ? ? ? //處理異步任務的結果

? ? ? ? $serv->on('finish', function ($serv, $task_id, $data) {

? ? ? ? ? ? echo "任務".$data."結束\n";

? ? ? ? });

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

? ? }

定時器調用方法

? ? private function timter(){

? ? ? ? \swoole_timer_tick(3000, function () {

? ? ? ? ? ? //30S一次

? ? ? ? ? ? echo 1;

? ? ? ? ? ? $this->checkPort();

? ? ? ? });

? ? }

監聽系統服務php-fpm/nginx/swoole

? ? private function checkPort(){

? ? ? ? $res = exec('netstat -apn | grep 9501');

? ? ? ? if(!$res){

? ? ? ? ? ? Log::write(time().'|9501|swooleStop');

? ? ? ? ? ? $this->sendEmail();

? ? ? ? }

? ? ? ? $res = exec('netstat -apn | grep 9000');

? ? ? ? if(!$res){

? ? ? ? ? ? Log::write(time().'|9000|fpmStop');

? ? ? ? ? ? $this->sendEmail();

? ? ? ? }

? ? ? ? $res = exec('netstat -apn | grep 80');

? ? ? ? if(!$res){

? ? ? ? ? ? Log::write(time().'|80|nginxStop');

? ? ? ? ? ? $this->sendEmail();

? ? ? ? }

}

郵件提醒

? ? private function sendEmail(){

? ? ? ? $email='xbc@gmail.com';

? ? ? ? $subject='線上提醒';

? ? ? ? $content='服務器出現問題請及時處理';

? ? ? ? send_email($email,$subject,$content);

? ? }

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。