基于上一篇文章swoole+tp5異步多線程梅桩,發(fā)現(xiàn)很多問題讯私,所以深入理解一下swoole的進程模型
想探討一下swoole缀皱,swoole在大流量生產(chǎn)環(huán)境下需要哪些特別注意的地方, 求指導晒奕,聯(lián)系我就可以
運行環(huán)境linux? 服務(wù)開啟命令? 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命令行使用方法闻书,手冊可以查到,原理是加載文件并執(zhí)行文件
? ? protected function configure(){
? ? ? ? $this->setName('Tcp')->setDescription('OK ');
? ? }
? ? public function execute(Input $input, Output $output){
參數(shù)配置
? ? ? ? $serv = new \swoole_server("0.0.0.0", 9501);
? ? ? ? $serv->set([
? ? ? ? ? ? 'reactor_num' => 1,//同服務(wù)器核心數(shù)
? ? ? ? ? ? 'worker_num' => 2,//同服務(wù)器核心數(shù)或1--4倍服務(wù)器核心數(shù)
? ? ? ? ? ? 'task_worker_num' => 4,//當task繁忙導致server沒有響應(yīng)請求時脑慧,可以適當增加num魄眉,具體根據(jù)官方文檔和試運行情況修改
? ? ? ? ? ? 'backlog' => 128,
? ? ? ? ? ? 'daemonize' => 0,//加入此參數(shù)后,執(zhí)行php server.php將轉(zhuǎn)入后臺作為守護進程運行
? ? ? ? ? ? 'max_conn' => 10000,//此參數(shù)用來設(shè)置Server最大允許維持多少個tcp連接闷袒。超過此數(shù)量后坑律,新進入的連接將被拒絕囊骤。
? ? ? ? ? ? 'max_request' => 2000,//此參數(shù)表示worker進程在處理完n次請求后結(jié)束運行。manager會重新創(chuàng)建一個worker進程也物。此選項用來防止worker進程內(nèi)存溢出宫屠。
//? ? ? ? ? 'log_file' => '/data/log/Swoole.log',//指定swoole錯誤日志文件滑蚯。在swoole運行期發(fā)生的異常信息會記錄到這個文件中抵栈。默>認會打印到屏幕。
? ? ? ? ? ? 'heartbeat_check_interval' => 30,//每隔多少秒檢測一次坤次,單位秒,Swoole會輪詢所有TCP連接缰猴,將超過心跳時間的連接關(guān)閉掉
? ? ? ? ? ? 'heartbeat_idle_time' => 60,//TCP連接的最大閑置時間,單位s , 如果某fd最后一次發(fā)包距離現(xiàn)在的時間超過? ? heartbeat_idle_time必須大于或等于heartbeat_check_interval
? ? ? ? ? ? 'task_max_request' => 100,//設(shè)置task進程的最大任務(wù)數(shù)滑绒。一個task進程在處理完超過此數(shù)值的任務(wù)后將自動退出闷堡。這個參數(shù)是為了防止PHP進程內(nèi)存溢出。如果不希望進程自動退出可以設(shè)置為0蹬挤。
? ? ? ? ? ? 'open_cpu_affinity' => 1,//啟用CPU親和性設(shè)置缚窿。在多核的硬件平臺中棘幸,啟用此特性會將swoole的reactor線程/worker進程綁定到固定的一個核上焰扳。可以避免進程/線程的運行時在多個核之間互相切換误续,提高CPU Cache的命中率吨悍。
? ? ? ? ]);
常用方法的回調(diào)函數(shù)
? ? ? ? $serv->on('start', function ($serv){
? ? ? ? ? ? $this->timter();
? ? ? ? ? ? echo "第一步master進程被拉起\n";
? ? ? ? });
注意:如果manager進程和worker進程存在多個,請不要在manager和worker進程中開啟全局任務(wù)
? ? ? ? $serv->on('ManagerStart', function ($serv){
? ? ? ? ? ? echo "第二步指定數(shù)目的調(diào)度reactor進程被拉起\n";
? ? ? ? });
? ? ? ? $serv->on('WorkerStart', function ($serv){
? ? ? ? ? ? echo "第三步指定數(shù)目的worker進程被拉起\n";
? ? ? ? });
? ? ? ? $serv->on('WorkerStop', function (){
? ? ? ? ? ? echo "第四步指定數(shù)目的worker進程被kill\n";
? ? ? ? });
? ? ? ? $serv->on('ManagerStop', function (){
? ? ? ? ? ? echo "第五步指定數(shù)目的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();//觸發(fā)worker進程的stop方法
//? ? ? ? ? ? ? ? $serv->shutdown();//觸發(fā)所有進程的stop及shutdown方法
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? ? ? //投遞異步任務(wù)
? ? ? ? ? ? $task_id = $serv->task($data);
? ? ? ? ? ? echo "任務(wù)".$task_id."開始\n";
? ? ? ? });
? ? ? ? //模擬處理異步任務(wù)
? ? ? ? $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);
? ? ? ? ? ? //返回任務(wù)執(zhí)行的結(jié)果
? ? ? ? ? ? unset($insertAll);
? ? ? ? ? ? $serv->finish("ID".$task_id);
? ? ? ? });
? ? ? ? //處理異步任務(wù)的結(jié)果
? ? ? ? $serv->on('finish', function ($serv, $task_id, $data) {
? ? ? ? ? ? echo "任務(wù)".$data."結(jié)束\n";
? ? ? ? });
? ? ? ? $serv->start();
? ? }
定時器調(diào)用方法
? ? private function timter(){
? ? ? ? \swoole_timer_tick(3000, function () {
? ? ? ? ? ? //30S一次
? ? ? ? ? ? echo 1;
? ? ? ? ? ? $this->checkPort();
? ? ? ? });
? ? }
監(jiān)聽系統(tǒng)服務(wù)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='服務(wù)器出現(xiàn)問題請及時處理';
? ? ? ? send_email($email,$subject,$content);
? ? }
}