摘要:配置了參數后將會啟用功能,務必要注冊個事件回調函數。周期性定時器一次性定時器清除定時器定時器回調函數注意最大不得超過。進程中不能添加定時器。建議在回調里寫定時器。定時器示例防止重復每隔觸發一次后執行此函數
本文示例代碼詳見:https://github.com/52fhy/swoo...。
重新打開日志在1.8.11及之后版本支持重新打開日志:向Server主進程發送SIGRTMIN信號。假設主進程id是3427,那么我們可以:
kill -34 3427
注:SIGRTMIN信號的id是34。通過kill -l查看。
那么如何利用這個特征實現每天自動寫入新的日志文件里面呢?
假設日志文件是/log/swoole.log,我們可以在每天0點運行shell命令:
mv /log/swoole.log /log/$(date -d "-1 day" +%y-%m-%d).log kill -34 $(ps aux|grep swoole_task|grep swoole_task_matser|grep -v grep|awk "{print $2}") # 找到主進程,需要提前命名
我們也可以把master進程的PID寫入到文件:
$server->set(array( "pid_file" => __DIR__."/server.pid", ));
在Server關閉時自動刪除PID文件。此選項在1.9.5或更高版本可用。
信號管理Swoole支持的信號:
SIGKILL -9 pid 強制殺掉進程 SIGUSR1 -10 master_pid 重啟所有worker進程 SIGUSR2 -12 master_pid 重啟所有task_worker進程 SIGRTMIN -34 master_pid 重新打開日志(版本1.8.11+)
master_pid代表主進程pid。示例(假設主進程名稱是swoole_server,pid是3427):
# 殺掉進程swoole_server kill -9 $(ps aux|grep swoole_server|grep -v grep|awk "{print $2}") # 重啟swoole_server的worker進程 kill -10 $(ps aux|grep swoole_server|grep -v grep|awk "{print $2}") # 重新打開日志 kill -34 3427Task
我們可以在worker進程中投遞一個異步任務到task_worker池中。此函數是非阻塞的,執行完畢會立即返回。worker進程可以繼續處理新的請求。
通常會把耗時的任務交給task_worker來處理。
我們可以通過如下代碼判斷是Worker進程還是TaskWorker進程:
function onWorkerStart($serv, $worker_id) { if ($worker_id >= $serv->setting["worker_num"]) { //超過worker_num,表示這是一個task進程 } }
看一個示例:
set(array( "daemonize" => false, "reactor_num" => 2, "worker_num" => 1, "task_worker_num" => 1, )); $server->on("start", function ($serv){ swoole_set_process_name("swoole_task_matser"); //主進程命名 }); $server->on("connect", function ($serv, $fd){ echo "client connect. fd is {$fd} "; }); $server->on("receive", function ($serv, $fd, $from_id, $data){ echo sprintf("onReceive. fd: %d , data: %s ", $fd, json_encode($data) ); $serv->task(json_encode([ "fd" => $fd, "task_name" => "send_email", "email_content" => $data, "email" => "admin@qq.com" ])); }); $server->on("close", function ($serv, $fd){ echo "client close. fd is {$fd} "; }); $server->on("task", function (swoole_server $serv, $task_id, $from_id, $data){ echo $data; $data = json_decode($data, true); $serv->send($data["fd"], "send eamil to {$data["email"]}, content is : {$data["email_content"]} "); //echo "task finished"; //return "task finished"; $serv->finish("task finished"); }); $server->on("finish", function (swoole_server $serv, $task_id, $data){ echo "onFinish:" .$data; }); $server -> start();
這里新建了一個tcp服務器,參數里設置worker_num進程為1,task_worker_num為1。
配置了task_worker_num參數后將會啟用task功能,swoole_server務必要注冊onTask/onFinish2個事件回調函數。如果沒有注冊,服務器程序將無法啟動。
onTask回調接收4個參數,分別是serv對象、任務ID、自于哪個worker進程、任務的內容。注意的是,$data必須是字符串。我們可以在worker進程里使用`swoole_server->task
($data)`進行任務投遞。
onFinish回調用于將處理結果告知worker進程,此回調必須有,但是否被調用由OnTask決定。在OnTask里使用return或者finish()可以將處理結果發生到onFinish回調,否則onFinish回調是不會被調用的。也就是說:finish()是可選的。如果worker進程不關心任務執行的結果,不需要調用此函數。onFinish回調里的$data同樣必須是字符串。
我們新起一個窗口,使用telnet發送消息到服務端進行測試:
client端:
telnet 127.0.0.1 8088 Trying 127.0.0.1... Connected to 127.0.0.1. hhh send eamil to admin@qq.com, content is : hhh
server端:
client connect. fd is 1 onReceive. fd: 1 , data: "hhh " {"fd":1,"task_name":"send_email","email_content":"hhh ","email":"admin@qq.com"} onFinish:task finished
onFinish回調里不使用return或者finish(),我們將看不到server端最后一行輸出。
此時服務器進程模型:
pstree -ap | grep swoole | | `-php,3190 swoole_task.php | | |-php,3192 swoole_task.php | | | |-php,3194 swoole_task.php | | | `-php,3195 swoole_task.php
看到兩個worker進程,其中一個是worker進程,另外一個是task_worker進程。
定時器Swoole提供強大的異步毫秒定時器,基于timerfd+epoll實現。主要方法:
1、swoole_timer_tick:周期性定時器,類似于JavaScript里的setInterval() 。
2、swoole_timer_after:一次性定時器。
3、swoole_timer_clear:清除定時器。
# 周期性定時器 int swoole_timer_tick(int $ms, callable $callback, mixed $user_param); # 一次性定時器 swoole_timer_after(int $after_time_ms, mixed $callback_function, mixed $user_param); # 清除定時器 bool swoole_timer_clear(int $timer_id) # 定時器回調函數 function callbackFunction(int $timer_id, mixed $params = null);
注意:
$ms 最大不得超過 86400000。
manager進程中不能添加定時器。
建議在WorkerStart回調里寫定時器。
定時器示例:
$server->on("WorkerStart", function (swoole_server $server, $worker_id){ if ($server->worker_id == 0){//防止重復 //每隔2000ms觸發一次 swoole_timer_tick(2000, function ($timer_id) { echo "tick-2000ms "; }); //3000ms后執行此函數 swoole_timer_after(3000, function () { echo "after 3000ms. "; }); } });
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/23062.html
摘要:消息隊列更常見的用途是主進程分配任務,子進程消費執行。子進程前面加了個,這是為了防止父進程還未往消息隊列中加入內容直接退出。 前面幾節都是講解pcntl擴展實現的多進程程序。本節給大家介紹swoole擴展的swoole_process模塊。 swoole多進程 swoole_process 是swoole提供的進程管理模塊,用來替代PHP的pcntl擴展。 首先,確保安裝的swoole...
摘要:所以,我感覺學習,需要一個引導。學習參考鏈接喵星球特別厲害的一個官網的幾個框架文檔優勢先看一下的結構設計的應用場景的設計項目中引入一個簡易的具體參考一篇文章,集合和的簡易實例項目中引入結合致敬 前期學完了操作系統,特別是知道了進程,線程 調度的問題。回來看,發現了很多細節。第三次看文檔,最初經一個高手朋友的介紹,看swoole,說文檔寫的賊好。但是看的時候,也是很一頭霧水,只知道把de...
摘要:修復添加超過萬個以上定時器時發生崩潰的問題增加模塊,下高性能序列化庫修復監聽端口設置無效的問題等。線程來處理網絡事件輪詢,讀取數據。當的三次握手成功了以后,由這個線程將連接成功的消息告訴進程,再由進程轉交給進程。此時進程觸發事件。 本文示例代碼詳見:https://github.com/52fhy/swoo...。 簡介 Swoole是一個PHP擴展,提供了PHP語言的異步多線程服務器...
摘要:安裝準備或更高版本或更高版本安裝擴展配置支持編輯在其中加入擴展支持服務端代碼服務端客戶端代碼測試代碼在命令模式下輸入重新再開一個窗口可以用檢測如服務端客戶端如上,表示服務端啟動,客戶端連接服務端返回消息,一個閉環形成開發者頭條 1.安裝準備 php-5.3.10 // 或更高版本 gcc-4.4 //或更高版本 make autoconf 2.安裝swoole擴展 w...
摘要:配合模塊,創建的子進程可以異步的事件驅動模式。默認為阻塞讀取。函數用于將一個加入到的事件監聽中。為事件類型的掩碼,可選擇關閉開啟可讀可寫事件,如,,或者。在程序中使用,可以理解為在進程中將此注冊到事件中。 Process Process是swoole內置的進程管理模塊,用來替代PHP的pcntl擴展。 swoole_process支持重定向標準輸入和輸出,在子進程內echo不會打印屏...
閱讀 2597·2021-10-14 09:43
閱讀 3559·2021-10-13 09:39
閱讀 3289·2019-08-30 15:44
閱讀 3137·2019-08-29 16:37
閱讀 3702·2019-08-29 13:17
閱讀 2731·2019-08-26 13:57
閱讀 1825·2019-08-26 11:59
閱讀 1238·2019-08-26 11:46