swoole.php
1 #!/bin/env php 2 <?php 3 /** 4 * 默認時區定義 5 */ 6 date_default_timezone_set('Asia/Shanghai'); 7 8 /** 9 * 設置錯誤報告模式 10 */ 11 error_reporting(0); 12 13 /** 14 * 設置默認區域 15 */ 16 setlocale(LC_ALL, "zh_CN.utf-8"); 17 18 /** 19 * 檢測 PDO_MYSQL 20 */ 21 if (!extension_loaded('pdo_mysql')) { 22 exit('PDO_MYSQL extension is not installed' . PHP_EOL); 23 } 24 /** 25 * 檢查exec 函數是否啟用 26 */ 27 if (!function_exists('exec')) { 28 exit('exec function is disabled' . PHP_EOL); 29 } 30 /** 31 * 檢查命令 lsof 命令是否存在 32 */ 33 exec("whereis lsof", $out); 34 if ($out[0] == 'lsof:') { 35 exit('lsof is not found' . PHP_EOL); 36 } 37 /** 38 * 定義項目根目錄&swoole-task pid 39 */ 40 define('SWOOLE_PATH', __DIR__); 41 define('SWOOLE_TASK_PID_PATH', SWOOLE_PATH . DIRECTORY_SEPARATOR . 'Swoole' . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR . 'swoole-task.pid'); 42 define('SWOOLE_TASK_NAME_PRE', 'swooleServ'); 43 44 /** 45 * 加載 swoole server 46 */ 47 include SWOOLE_PATH . DIRECTORY_SEPARATOR . 'Swoole' . DIRECTORY_SEPARATOR . 'SwooleServer.php'; 48 49 function portBind($port) { 50 $ret = []; 51 $cmd = "lsof -i :{$port}|awk '$1 != \"COMMAND\" {print $1, $2, $9}'"; 52 exec($cmd, $out); 53 if ($out) { 54 foreach ($out as $v) { 55 $a = explode(' ', $v); 56 list($ip, $p) = explode(':', $a[2]); 57 $ret[$a[1]] = [ 58 'cmd' => $a[0], 59 'ip' => $ip, 60 'port' => $p, 61 ]; 62 } 63 } 64 65 return $ret; 66 } 67 68 function servStart($host, $port, $daemon, $name) { 69 echo "正在啟動 swoole-task 服務" . PHP_EOL; 70 if (!is_writable(dirname(SWOOLE_TASK_PID_PATH))) { 71 exit("swoole-task-pid文件需要目錄的寫入權限:" . dirname(SWOOLE_TASK_PID_PATH) . PHP_EOL); 72 } 73 if (file_exists(SWOOLE_TASK_PID_PATH)) { 74 $pid = explode("\n", file_get_contents(SWOOLE_TASK_PID_PATH)); 75 $cmd = "ps ax | awk '{ print $1 }' | grep -e \"^{$pid[0]}$\""; 76 exec($cmd, $out); 77 if (!empty($out)) { 78 exit("swoole-task pid文件 " . SWOOLE_TASK_PID_PATH . " 存在,swoole-task 服務器已經啟動,進程pid為:{$pid[0]}" . PHP_EOL); 79 } else { 80 echo "警告:swoole-task pid文件 " . SWOOLE_TASK_PID_PATH . " 存在,可能swoole-task服務上次異常退出(非守護模式ctrl+c終止造成是最大可能)" . PHP_EOL; 81 unlink(SWOOLE_TASK_PID_PATH); 82 } 83 } 84 $bind = portBind($port); 85 if ($bind) { 86 foreach ($bind as $k => $v) { 87 if ($v['ip'] == '*' || $v['ip'] == $host) { 88 exit("端口已經被占用 {$host}:$port, 占用端口進程ID {$k}" . PHP_EOL); 89 } 90 } 91 } 92 unset($_SERVER['argv']); 93 $_SERVER['argc'] = 0; 94 echo "啟動 swoole-task 服務成功" . PHP_EOL; 95 $server = new SwooleServer('127.0.0.1', 9501); 96 $server->run(); 97 //確保服務器啟動后swoole-task-pid文件必須生成 98 /*if (!empty(portBind($port)) && !file_exists(SWOOLE_TASK_PID_PATH)) { 99 exit("swoole-task pid文件生成失敗( " . SWOOLE_TASK_PID_PATH . ") ,請手動關閉當前啟動的swoole-task服務檢查原因" . PHP_EOL); 100 }*/ 101 } 102 103 function servStop($host, $port, $isRestart = false) { 104 echo "正在停止 swoole-task 服務" . PHP_EOL; 105 if (!file_exists(SWOOLE_TASK_PID_PATH)) { 106 exit('swoole-task-pid文件:' . SWOOLE_TASK_PID_PATH . '不存在' . PHP_EOL); 107 } 108 $pid = explode("\n", file_get_contents(SWOOLE_TASK_PID_PATH)); 109 $bind = portBind($port); 110 if (empty($bind) || !isset($bind[$pid[0]])) { 111 exit("指定端口占用進程不存在 port:{$port}, pid:{$pid[0]}" . PHP_EOL); 112 } 113 $cmd = "kill {$pid[0]}"; 114 exec($cmd); 115 do { 116 $out = []; 117 $c = "ps ax | awk '{ print $1 }' | grep -e \"^{$pid[0]}$\""; 118 exec($c, $out); 119 if (empty($out)) { 120 break; 121 } 122 } while (true); 123 //確保停止服務后swoole-task-pid文件被刪除 124 if (file_exists(SWOOLE_TASK_PID_PATH)) { 125 unlink(SWOOLE_TASK_PID_PATH); 126 } 127 $msg = "執行命令 {$cmd} 成功,端口 {$host}:{$port} 進程結束" . PHP_EOL; 128 if ($isRestart) { 129 echo $msg; 130 } else { 131 exit($msg); 132 } 133 } 134 135 function servReload($host, $port, $isRestart = false) { 136 echo "正在平滑重啟 swoole-task 服務" . PHP_EOL; 137 try { 138 $client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); 139 $ret = $client->connect($host, $port); 140 if (empty($ret)) { 141 exit("{$host}:{$port} swoole-task服務不存在或者已經關閉" . PHP_EOL); 142 } else { 143 $client->send(json_encode(array('action' => 'reload'))); 144 } 145 $msg = "執行命令reload成功,端口 {$host}:{$port} 進程重啟" . PHP_EOL; 146 if ($isRestart) { 147 echo $msg; 148 } else { 149 exit($msg); 150 } 151 } catch (Exception $e) { 152 exit($e->getMessage() . PHP_EOL . $e->getTraceAsString()); 153 } 154 } 155 156 function servClose($host, $port, $isRestart = false) { 157 echo "正在關閉 swoole-task 服務" . PHP_EOL; 158 try { 159 $client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); 160 $ret = $client->connect($host, $port); 161 if (empty($ret)) { 162 exit("{$host}:{$port} swoole-task服務不存在或者已經關閉" . PHP_EOL); 163 } else { 164 $client->send(json_encode(array('action' => 'close'))); 165 } 166 //確保停止服務后swoole-task-pid文件被刪除 167 if (file_exists(SWOOLE_TASK_PID_PATH)) { 168 unlink(SWOOLE_TASK_PID_PATH); 169 } 170 $msg = "執行命令close成功,端口 {$host}:{$port} 進程結束" . PHP_EOL; 171 if ($isRestart) { 172 echo $msg; 173 } else { 174 exit($msg); 175 } 176 } catch (\Exception $e) { 177 exit($e->getMessage() . PHP_EOL . $e->getTraceAsString()); 178 } 179 } 180 181 function servStatus($host, $port) { 182 echo "swoole-task {$host}:{$port} 運行狀態" . PHP_EOL; 183 $pid = explode("\n", file_get_contents(SWOOLE_TASK_PID_PATH)); 184 $bind = portBind($port); 185 if (empty($bind) || !isset($bind[$pid[0]])) { 186 exit("指定端口占用進程不存在 port:{$port}, pid:{$pid[0]}" . PHP_EOL); 187 } 188 $client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); 189 $ret = $client->connect($host, $port); 190 if (empty($ret)) { 191 exit("{$host}:{$port} swoole-task服務不存在或者已經停止" . PHP_EOL); 192 } else { 193 $client->send(json_encode(array('action' => 'status'))); 194 $out = $client->recv(); 195 $a = json_decode($out); 196 $b = array( 197 'start_time' => '服務器啟動的時間', 198 'connection_num' => '當前連接的數量', 199 'accept_count' => '接受的連接數量', 200 'close_count' => '關閉的連接數量', 201 'tasking_num' => '當前正在排隊的任務數', 202 'request_count' => '請求的連接數量', 203 'worker_request_count' => 'worker連接數量', 204 'task_process_num' => '任務進程數量' 205 ); 206 foreach ($a as $k1 => $v1) { 207 if ($k1 == 'start_time') { 208 $v1 = date("Y-m-d H:i:s", $v1); 209 } 210 echo $b[$k1] . ":\t$v1" . PHP_EOL; 211 } 212 } 213 exit(); 214 } 215 216 function servList() { 217 echo "本機運行的swoole-task服務進程" . PHP_EOL; 218 $cmd = "ps aux|grep " . SWOOLE_TASK_NAME_PRE . "|grep -v grep|awk '{print $1, $2, $6, $8, $9, $11}'"; 219 exec($cmd, $out); 220 if (empty($out)) { 221 exit("沒有發現正在運行的swoole-task服務" . PHP_EOL); 222 } 223 echo "USER PID RSS(kb) STAT START COMMAND" . PHP_EOL; 224 foreach ($out as $v) { 225 echo $v . PHP_EOL; 226 } 227 exit(); 228 } 229 230 //可執行命令 231 $cmds = [ 232 'start', 233 'stop', 234 'restart', 235 'reload', 236 'close', 237 'status', 238 'list', 239 ]; 240 $shortopts = "dDh:p:n:"; 241 $longopts = [ 242 'help', 243 'daemon', 244 'nondaemon', 245 'host:', 246 'port:', 247 'name:', 248 ]; 249 $opts = getopt($shortopts, $longopts); 250 251 if (isset($opts['help']) || $argc < 2) { 252 echo <<<HELP 253 用法:php swoole.php 選項 ... 命令[start|stop|restart|reload|close|status|list] 254 管理swoole-task服務,確保系統 lsof 命令有效 255 如果不指定監聽host或者port,使用配置參數 256 257 參數說明 258 --help 顯示本幫助說明 259 -d, --daemon 指定此參數,以守護進程模式運行,不指定則讀取配置文件值 260 -D, --nondaemon 指定此參數,以非守護進程模式運行,不指定則讀取配置文件值 261 -h, --host 指定監聽ip,例如 php swoole.php -h127.0.0.1 262 -p, --port 指定監聽端口port, 例如 php swoole.php -h127.0.0.1 -p9520 263 -n, --name 指定服務進程名稱,例如 php swoole.php -ntest start, 則進程名稱為SWOOLE_TASK_NAME_PRE-name 264 啟動swoole-task 如果不指定 host和port,讀取默認配置 265 強制關閉swoole-task 必須指定port,沒有指定host,關閉的監聽端口是 *:port,指定了host,關閉 host:port端口 266 平滑關閉swoole-task 必須指定port,沒有指定host,關閉的監聽端口是 *:port,指定了host,關閉 host:port端口 267 強制重啟swoole-task 必須指定端口 268 平滑重啟swoole-task 必須指定端口 269 獲取swoole-task 狀態,必須指定port(不指定host默認127.0.0.1), tasking_num是正在處理的任務數量(0表示沒有待處理任務) 270 271 HELP; 272 exit; 273 } 274 //參數檢查 275 foreach ($opts as $k => $v) { 276 if (($k == 'h' || $k == 'host')) { 277 if (empty($v)) { 278 exit("參數 -h --host 必須指定值\n"); 279 } 280 } 281 if (($k == 'p' || $k == 'port')) { 282 if (empty($v)) { 283 exit("參數 -p --port 必須指定值\n"); 284 } 285 } 286 if (($k == 'n' || $k == 'name')) { 287 if (empty($v)) { 288 exit("參數 -n --name 必須指定值\n"); 289 } 290 } 291 } 292 293 //命令檢查 294 $cmd = $argv[$argc - 1]; 295 if (!in_array($cmd, $cmds)) { 296 exit("輸入命令有誤 : {$cmd}, 請查看幫助文檔\n"); 297 } 298 299 //監聽ip 127.0.0.1,空讀取配置文件 300 $host = '127.0.0.1'; 301 if (!empty($opts['h'])) { 302 $host = $opts['h']; 303 if (!filter_var($host, FILTER_VALIDATE_IP)) { 304 exit("輸入host有誤:{$host}"); 305 } 306 } 307 if (!empty($opts['host'])) { 308 $host = $opts['host']; 309 if (!filter_var($host, FILTER_VALIDATE_IP)) { 310 exit("輸入host有誤:{$host}"); 311 } 312 } 313 //監聽端口,9501 讀取配置文件 314 $port = 9501; 315 if (!empty($opts['p'])) { 316 $port = (int)$opts['p']; 317 if ($port <= 0) { 318 exit("輸入port有誤:{$port}"); 319 } 320 } 321 if (!empty($opts['port'])) { 322 $port = (int)$opts['port']; 323 if ($port <= 0) { 324 exit("輸入port有誤:{$port}"); 325 } 326 } 327 //進程名稱 沒有默認為 SWOOLE_TASK_NAME_PRE; 328 $name = SWOOLE_TASK_NAME_PRE; 329 if (!empty($opts['n'])) { 330 $name = $opts['n']; 331 } 332 if (!empty($opts['name'])) { 333 $name = $opts['n']; 334 } 335 //是否守護進程 -1 讀取配置文件 336 $isdaemon = -1; 337 if (isset($opts['D']) || isset($opts['nondaemon'])) { 338 $isdaemon = 0; 339 } 340 if (isset($opts['d']) || isset($opts['daemon'])) { 341 $isdaemon = 1; 342 } 343 //啟動swoole-task服務 344 if ($cmd == 'start') { 345 servStart($host, $port, $isdaemon, $name); 346 } 347 //強制停止swoole-task服務 348 if ($cmd == 'stop') { 349 if (empty($port)) { 350 exit("停止swoole-task服務必須指定port" . PHP_EOL); 351 } 352 servStop($host, $port); 353 } 354 //關閉swoole-task服務 355 if ($cmd == 'close') { 356 if (empty($port)) { 357 exit("停止swoole-task服務必須指定port" . PHP_EOL); 358 } 359 servClose($host, $port); 360 } 361 //強制重啟swoole-task服務 362 if ($cmd == 'restart') { 363 if (empty($port)) { 364 exit("重啟swoole-task服務必須指定port" . PHP_EOL); 365 } 366 echo "重啟swoole-task服務" . PHP_EOL; 367 servStop($host, $port, true); 368 servStart($host, $port, $isdaemon, $name); 369 } 370 //平滑重啟swoole-task服務 371 if ($cmd == 'reload') { 372 if (empty($port)) { 373 exit("平滑重啟swoole-task服務必須指定port" . PHP_EOL); 374 } 375 echo "平滑重啟swoole-task服務" . PHP_EOL; 376 servReload($host, $port, true); 377 } 378 //查看swoole-task服務狀態 379 if ($cmd == 'status') { 380 if (empty($host)) { 381 $host = '127.0.0.1'; 382 } 383 if (empty($port)) { 384 exit("查看swoole-task服務必須指定port(host不指定默認使用127.0.0.1)" . PHP_EOL); 385 } 386 servStatus($host, $port); 387 } 388 //查看swoole-task服務進程列表 389 if ($cmd == 'list') { 390 servList(); 391 }
SwooleServer.php
1 <?php 2 3 /** 4 * Swoole服務端 5 */ 6 class SwooleServer { 7 8 private $_serv = null; 9 private $_setting = array(); 10 11 public function __construct($host = '0.0.0.0', $port = 9501) { 12 $this->_setting = array( 13 'host' => $host, 14 'port' => $port, 15 'env' => 'dev', //環境 dev|test|prod 16 'process_name' => SWOOLE_TASK_NAME_PRE, //swoole 進程名稱 17 'worker_num' => 4, //一般設置為服務器CPU數的1-4倍 18 'task_worker_num' => 4, //task進程的數量 19 'task_ipc_mode' => 3, //使用消息隊列通信,並設置為爭搶模式 20 'task_max_request' => 10000, //task進程的最大任務數 21 'daemonize' => 1, //以守護進程執行 22 'max_request' => 10000, 23 'dispatch_mode' => 2, 24 'log_file' => SWOOLE_PATH . DIRECTORY_SEPARATOR . 'App' . DIRECTORY_SEPARATOR . 'Runtime' . DIRECTORY_SEPARATOR . 'Logs' . DIRECTORY_SEPARATOR . 'Swoole' . date('Ymd') . '.log', //日志 25 ); 26 } 27 28 /** 29 * 運行swoole服務 30 */ 31 public function run() { 32 $this->_serv = new \swoole_server($this->_setting['host'], $this->_setting['port']); 33 $this->_serv->set(array( 34 'worker_num' => $this->_setting['worker_num'], 35 'task_worker_num' => $this->_setting['task_worker_num'], 36 'task_ipc_mode ' => $this->_setting['task_ipc_mode'], 37 'task_max_request' => $this->_setting['task_max_request'], 38 'daemonize' => $this->_setting['daemonize'], 39 'max_request' => $this->_setting['max_request'], 40 'dispatch_mode' => $this->_setting['dispatch_mode'], 41 'log_file' => $this->_setting['log_file'] 42 )); 43 $this->_serv->on('Start', array($this, 'onStart')); 44 $this->_serv->on('Connect', array($this, 'onConnect')); 45 $this->_serv->on('WorkerStart', array($this, 'onWorkerStart')); 46 $this->_serv->on('ManagerStart', array($this, 'onManagerStart')); 47 $this->_serv->on('WorkerStop', array($this, 'onWorkerStop')); 48 $this->_serv->on('Receive', array($this, 'onReceive')); 49 $this->_serv->on('Task', array($this, 'onTask')); 50 $this->_serv->on('Finish', array($this, 'onFinish')); 51 $this->_serv->on('Shutdown', array($this, 'onShutdown')); 52 $this->_serv->on('Close', array($this, 'onClose')); 53 $this->_serv->start(); 54 } 55 56 /** 57 * 設置swoole進程名稱 58 * @param string $name swoole進程名稱 59 */ 60 private function setProcessName($name) { 61 if (function_exists('cli_set_process_title')) { 62 cli_set_process_title($name); 63 } else { 64 if (function_exists('swoole_set_process_name')) { 65 swoole_set_process_name($name); 66 } else { 67 trigger_error(__METHOD__ . " failed. require cli_set_process_title or swoole_set_process_name."); 68 } 69 } 70 } 71 72 /** 73 * Server啟動在主進程的主線程回調此函數 74 * @param $serv 75 */ 76 public function onStart($serv) { 77 if (!$this->_setting['daemonize']) { 78 echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server master worker start\n"; 79 } 80 $this->setProcessName($this->_setting['process_name'] . '-master'); 81 //記錄進程id,腳本實現自動重啟 82 $pid = "{$serv->master_pid}\n{$serv->manager_pid}"; 83 file_put_contents(SWOOLE_TASK_PID_PATH, $pid); 84 } 85 86 /** 87 * worker start 加載業務腳本常駐內存 88 * @param $server 89 * @param $workerId 90 */ 91 public function onWorkerStart($serv, $workerId) { 92 if ($workerId >= $this->_setting['worker_num']) { 93 $this->setProcessName($this->_setting['process_name'] . '-task'); 94 } else { 95 $this->setProcessName($this->_setting['process_name'] . '-event'); 96 } 97 // 開啟調試模式 建議開發階段開啟 部署階段注釋或者設為false 98 define('APP_DEBUG', True); 99 // 定義應用目錄 100 define('APP_PATH', SWOOLE_PATH . DIRECTORY_SEPARATOR . 'Application' . DIRECTORY_SEPARATOR); 101 // 定義應用模式 102 define('APP_MODE', 'cli'); 103 // 引入ThinkPHP入口文件 104 require SWOOLE_PATH . DIRECTORY_SEPARATOR . 'ThinkPHP' . DIRECTORY_SEPARATOR . 'ThinkPHP.php'; 105 } 106 107 /** 108 * 監聽連接進入事件 109 * @param $serv 110 * @param $fd 111 */ 112 public function onConnect($serv, $fd) { 113 if (!$this->_setting['daemonize']) { 114 echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server connect[" . $fd . "]\n"; 115 } 116 } 117 118 /** 119 * worker 進程停止 120 * @param $server 121 * @param $workerId 122 */ 123 public function onWorkerStop($serv, $workerId) { 124 if (!$this->_setting['daemonize']) { 125 echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server[{$serv->setting['process_name']} worker:{$workerId} shutdown\n"; 126 } 127 } 128 129 /** 130 * 當管理進程啟動時調用 131 * @param $serv 132 */ 133 public function onManagerStart($serv) { 134 if (!$this->_setting['daemonize']) { 135 echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server manager worker start\n"; 136 } 137 $this->setProcessName($this->_setting['process_name'] . '-manager'); 138 } 139 140 /** 141 * 此事件在Server結束時發生 142 */ 143 public function onShutdown($serv) { 144 if (file_exists(SWOOLE_TASK_PID_PATH)) { 145 unlink(SWOOLE_TASK_PID_PATH); 146 } 147 if (!$this->_setting['daemonize']) { 148 echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server shutdown\n"; 149 } 150 } 151 152 /** 153 * 監聽數據發送事件 154 * @param $serv 155 * @param $fd 156 * @param $from_id 157 * @param $data 158 */ 159 public function onReceive($serv, $fd, $from_id, $data) { 160 if (!$this->_setting['daemonize']) { 161 echo "Get Message From Client {$fd}:{$data}\n\n"; 162 } 163 $result = json_decode($data, true); 164 switch ($result['action']) { 165 case 'reload': //重啟 166 $serv->reload(); 167 break; 168 case 'close': //關閉 169 $serv->shutdown(); 170 break; 171 case 'status': //狀態 172 $serv->send($fd, json_encode($serv->stats())); 173 break; 174 default: 175 $serv->task($data); 176 break; 177 } 178 } 179 180 /** 181 * 監聽連接Task事件 182 * @param $serv 183 * @param $task_id 184 * @param $from_id 185 * @param $data 186 */ 187 public function onTask($serv, $task_id, $from_id, $data) { 188 $result = json_decode($data, true); 189 //用TP處理各種邏輯 190 $serv->finish($data); 191 } 192 193 /** 194 * 監聽連接Finish事件 195 * @param $serv 196 * @param $task_id 197 * @param $data 198 */ 199 public function onFinish($serv, $task_id, $data) { 200 if (!$this->_setting['daemonize']) { 201 echo "Task {$task_id} finish\n\n"; 202 echo "Result: {$data}\n\n"; 203 } 204 } 205 206 /** 207 * 監聽連接關閉事件 208 * @param $serv 209 * @param $fd 210 */ 211 public function onClose($serv, $fd) { 212 if (!$this->_setting['daemonize']) { 213 echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server close[" . $fd . "]\n"; 214 } 215 } 216 217 218 }
相關命令:
1、服務啟動
#啟動服務,不指定綁定端口和ip,則使用默認配置
php swoole.php start
#啟動服務 指定ip 和 port
php swoole.php -h127.0.0.1 -p9501 start
#啟動服務 守護進程模式
php swoole.php -h127.0.0.1 -p9501 -d start
#啟動服務 非守護進程模式
php swoole.php -h127.0.0.1 -p9501 -D start
#啟動服務 指定進程名稱(顯示進程名為 swooleServ-9510-[master|manager|event|task]
php swoole.php -h127.0.0.1 -p9501 -n 9501 start
2、強制服務停止
php swoole.php stop
php swoole.php -p9501 stop
php swoole.php -h127.0.0.1 -p9501 stop
3、關閉服務
php swoole.php close
php swoole.php -p9501 close
php swoole.php -h127.0.0.1 -p9501 close
4、強制服務重啟
php swoole.php restart
php swoole.php -p9501 restart
php swoole.php -h127.0.0.1 -p9501 restart
5、平滑服務重啟
php swoole.php reload
php swoole.php -p9501 reload
php swoole.php -h127.0.0.1 -p9501 reload
6、服務狀態
php swoole.php status
php swoole.php -h127.0.0.1 -p9501 status
7、swoole-task所有啟動實例進程列表(一台服務器swoole-task可以有多個端口綁定的實例)
php swoole.php list
Swoole-ThinkPHP.zip ( 1.14 MB )