swoft2 自定義用戶進程來定期執行用戶自定義任務
swoft2 支持進程池解決多進程並發執行用戶自定義任務
swoft2 進程詳解
多進程程序設計能解決很多有意義的問題,程序的主進程運行核心任務,一些輔助進程解決一些例如消息隊列的處理,后台定期執行的任務處理,文件監控,定期日志上報等相關功能.每個進程都有獨立的上下文,進程之間互不干擾.
功能的相關配置選項
- 用戶進程的配置一般需要在 bean.php 里注冊,系統會自動加載用戶配置的自定義進程
- 進程池的配置也需要在 bean.php 配置進程池配置項,但進程池不會自動加載,需要手動執行命令來啟動用戶進程
用戶進程配置簡單示例
修改 bean.php
'httpServer' => [
'class' => HttpServer::class,
'port' => 18306,
'listener' => [
'rpc' => bean('rpcServer')
],
'process' => [
'crontab' => bean(CrontabProcess::class)
'log' => bean(\App\Process\LogProcess::class)
],
],
上面的配置是 WEB服務器 的應用配置 如果是 WebSocket服務器 寫在wsServer配置項里,定義 process 屬性就好.
注意process的值是一維數組,其中key你可以自己定義,只要合法且不重復即可,值則為你定義的進程類,請用工廠函數 bean 加載.
進程池的配置簡單示例
修改 bean.php
'processPool' => [
'class' => \Swoft\Process\ProcessPool::class,
'workerNum' => 12
]
上面的配置定了進程池,且分配了12個可用工作進程,實際生產中根據你的項目需求自行修改配置項.
進程 workerid 的初始值是0,所以這里的 workerid 有效訪問是0-11,請注意
簡單的示例
用戶進程代碼預覽
namespace App\Process;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Log\Helper\CLog;
use Swoole\Coroutine;
use Throwable;
use Swoft\Process\Process;
use Swoft\Process\UserProcess;
/**
* Class LogProcess
*
* @since 2.0
*
* @Bean()
*/
class LogProcess extends UserProcess
{
/**
* @param Process $process
*
* @throws Throwable
*/
public function run(Process $process): void
{
$process->name('swoft-monitor'); //設置用戶進程名
while (true) {
CLog::info('用戶進程,每隔3秒輸出一次');//需要處理的工作
Coroutine::sleep(3);//休眠3秒
}
}
}
- 注意事項
- 自定義進程類需要打上 Bean 注解
- 用自定義進程類必須繼承 Swoft\Process\UserProcess
- 用戶自定義進程類的 run 方法是具體的任務執行代碼
- 用戶進程需要while循環來防止進程執行完畢后退出
- 休眠函數請使用 Coroutine::sleep(3) 參數根據項目實際情況配置,單位是秒.支持傳小數,如果傳入參數0.5,則代表每 500ms 執行一次
- 在run方法里不使用 while(true) 而使用 \Swoft\Timer::tick ,也是可以的,但tick更多的用於解決周期性任務,該函數需要維護更多的調用棧,並且觸發 swoft 的內置事件,所以它更消耗性能,一般在執行頻率要求不高的場景下使用,如果一些執行頻率較高的任務推薦使用 while(true)
控制台打印
進程池代碼預覽
namespace App\Process;
use Swoft\Log\Helper\CLog;
use Swoft\Process\Annotation\Mapping\Process;
use Swoft\Process\Contract\ProcessInterface;
use Swoole\Coroutine;
use Swoole\Process\Pool;
use Throwable;
/**
* Class Worker2Process
*
* @since 2.0
*
* @Process(workerId={0,1})
*/
class Worker2Process implements ProcessInterface
{
/**
* @param Pool $pool
* @param int $workerId
*
* @throws Throwable
*/
public function run(Pool $pool, int $workerId): void
{
while (true) {
CLog::info('worker-' . $workerId.' context='.context()->getWorkerId());
Coroutine::sleep(3);
}
}
}
注意事項
- 進程池進程類需要打上 Process 注解 且參數是 workerId 值為分配的進程池work進程的id數組.
- 進程池進程類需要實現 Swoft\Process\Contract\ProcessInterface 接口.
- 進程池 Process 注解的 workerId 不是越多越好,需要根據你的需要設置,設置的越多占用的內存越多.
- 每個 workerid 只允許分配一次,如果分配多個系統會拋出異常.
- workerid的取值范圍是 0 到 bean.php 配置的 workerNum-1 本文的例子是 0-11
啟動說明
前台啟用進程
php bin/swoft process:start
后台啟動進程
php bin/swoft process:start -d
重啟所有 worker 進程
php bin/swoft process:reload
重新啟動
php bin/swoft process:restart
停止服務
php bin/swoft process:stop
控制台打印
以上內容希望幫助到大家,很多PHPer在進階的時候總會遇到一些問題和瓶頸,業務代碼寫多了沒有方向感,不知道該從那里入手去提升,對此我整理了一些資料,包括但不限於:分布式架構、高可擴展、高性能、高並發、服務器性能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階干貨需要的可以免費分享給大家,需要的可以加入我的官方群點擊此處。