Swoole TCP服務端與客戶端的 初步研究 持續更新

Swoole TCP服務端與客戶端的 初步研究 持續更新

簡單TCP 服務端實現

server.php

<?php
$serv = new swoole_server('0.0.0.0', 9906);

$serv->set([
    'worker_num' => 4, // 最大連接
    'max_request' => 10000, // worker進程數
    'log_level' => SWOOLE_LOG_ERROR, // 日誌等級 關閉開啓debug
    'trace_flags' => SWOOLE_TRACE_SERVER, // 日誌等級 關閉開啓debug
]);

//設置事件回調函數
$serv->on('connect', function ($serv, $fd, $reactorId) {
    echo "Client:{$reactorId} - {$fd} - Connect.\n";
});

// 接受函數
$serv->on('receive', function ($serv, $fd, $reactorId, $data) {
//    echo 'cli:' . $data . "\n";
    $serv->send($fd, "server: {$reactorId} - {$fd} - {$data}");
//    $serv->close($fd);
});

$serv->on('close', function ($serv, $fd) {
    echo "Client: Close.\n";
});

//啓動服務器
$serv->start();

如果想看是否真的啓動了配置中的最大連接數 可以執行以下命令查看

 ps aft | grep server.php

set相關配置參數

名稱 參數值 描述
最大連接 max_conn 此參數用來設置Server最大允許維持多少個tcp連接。超過此數量後,新進入的連接將被拒絕。此參數不要調整的過大,根據機器內存的實際情況來設置。底層會根據此數值一次性分配一塊大內存來保存Connection信息 max_conn => 10000
守護進程化 daemonize 加入此參數後,執行php server.php將轉入後臺作爲守護進程運行 daemonize => 1
reactor線程數 reactor_num 通過此參數來調節Reactor線程的數量,以充分利用多核,reactor_num和默認設置爲CPU核數 reactor_num => 2
worker進程數 worker_num 設置啓動的Worker進程數量。Swoole採用固定Worker進程的模式。全異步非阻塞服務器 worker_num配置爲CPU核數的1-4倍即可。同步阻塞服務器,worker_num配置爲100或者更高,具體要看每次請求處理的耗時和操作系統負載狀況。當設定的Worker進程數小於reactor線程數時,會自動調低reactor線程的數量 worker_num => 4
max_request max_request 此參數表示worker進程在處理完n次請求後結束運行。manager會重新創建一個worker進程。此選項用來防止worker進程內存溢出。PHP代碼也可以使用memory_get_usage來檢測進程的內存佔用情況,發現接近memory_limit時,調用exit()退出進程。manager進程會回收此進程,然後重新啓動一個新的Worker進程。onConnect/onClose不增加計數設置爲0表示不自動重啓。在Worker進程中需要保存連接信息的服務,需要設置爲0. max_request => 2000
Listen隊列長度 backlog 此參數將決定最多同時有多少個待accept的連接,swoole本身accept效率是很高的,基本上不會出現大量排隊情況。 backlog => 128
CPU親和設置 open_cpu_affinity 啓用CPU親和設置 open_cpu_affinity => 1
TCP_NoDelay啓用 open_tcp_nodelay 啓用tcp_nodelay open_tcp_nodelay => 1
TCP_DEFER_ACCEPT tcp_defer_accept 此參數設定一個秒數,當客戶端連接連接到服務器時,在約定秒數內並不會觸發accept,直到有數據發送,或者超時時纔會觸發。 tcp_defer_accept => 5
日誌文件路徑 log_file 指定swoole錯誤日誌文件。在swoole運行期發生的異常信息會記錄到這個文件中。默認會打印到屏幕。 log_file => ‘/data/log/swoole.log’
數據buffer open_eof_check package_eof buffer主要是用於檢測數據是否完整,如果不完整swoole會繼續等待新的數據到來。直到收到完整的一個請求,纔會一次性發送給worker進程。這時onReceive會收到一個超過SW_BUFFER_SIZE,小於$serv->setting[‘package_max_length’]的數據。目前僅提供了EOF檢測、固定包頭長度檢測2種buffer模式。open_eof_check => true打開buffer package_eof => “\r\n\r\n” 設置EOF open_eof_check => true package_eof => “\r\n\r\n”
心跳檢測機制 heartbeat_check_interval heartbeat_idle_time heartbeat_check_interval 每隔多少秒檢測一次,單位秒,Swoole會輪詢所有TCP連接,將超過心跳時間的連接關閉掉。heartbeat_idle_time TCP連接的最大閒置時間,單位s , 如果某fd最後一次發包距離現在的時間超過heartbeat_idle_time會把這個連接關閉。heartbeat_idle_time必須大於或等於heartbeat_check_interval heartbeat_check_interval => 30 heartbeat_idle_time => 60
worker進程數據包分配模式 dispatch_mode 1平均分配,2按FD取模固定分配,3搶佔式分配,默認爲取模(dispatch=2) dispatch_mode=>1

簡單TCP 客戶端實現

Client.php

<?php
$client = new swoole_client(SWOOLE_SOCK_TCP); // 同步阻塞

$ret = $client->connect('127.0.0.1', 9906);
if (!$ret) {
    exit("Connect Server fail.errCode={$client->errCode}");
}

fwrite(STDOUT, '請輸入:');
$msg = trim(fgets(STDIN));
$client->send($msg);
$result = $client->recv();
echo $result;
$client->close();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章