介紹
在這篇文章中,我們將學習如何使用supervisord來處理symfony指令的執行。基本上,supervisord 將允許我們:
- 自動啟動指令
- 自動重新啟動指令
- 指定我們希望主管啟動的進程數。
問題
有時我們會使用 unix crontab 來自動執行進程。這可能在大多數情況下有效,但在某些情況下可能會導致問題。
假設我們有一個記錄使用者通知的資料庫表。此表儲存以下資訊:
- 使用者
- 文字
- 頻道
- 狀態(等待,已發送)
- 創建於
- 更新於
另一方面,我們編寫了一個命令,其執行遵循以下步驟:
- 查詢最近的WAITING通知
- 循環查詢的通知並:
- 將每一個傳送給對應的使用者。
- 將通知狀態從 WAITING 更新為 SENT
我們在 Linux crontab 中設定此命令每隔一段時間運行一次(1 分鐘、2 分鐘等)。到目前為止一切順利。
現在假設當前進程已查詢 500 個通知,當發送 400 個通知時,一個新進程啟動。這意味著新進程將查詢上一個進程尚未更新的 100 條通知以及新的通知:
這可能會導致這 100 個通知發送兩次,因為兩個進程都查詢了它們。
解決方案
作為解決方案,我們可以求助於使用supervisor。它將保持我們的進程運行並在需要時重新啟動它。這樣,我們只保留一個進程並避免重疊。讓我們來分析一下指令應該是什麼樣子:
#[AsCommand( name: 'app:notification' )] class NotificationCommand extends Command { private bool $forceFinish = false; protected function configure(): void { $this ->addOption('time-limit', null, InputOption::VALUE_OPTIONAL, 'Max time alive in seconds') ->addOption('time-between-calls', null, InputOption::VALUE_OPTIONAL, 'Time between every loop call') ; } protected function execute(InputInterface $input, OutputInterface $output): int { $this->forceFinish = false; pcntl_signal(SIGTERM, [$this, 'signalHandler']); pcntl_signal(SIGINT, [$this, 'signalHandler']); $timeLimit = $input->getOption('time-limit'); $timeBetweenCalls = $input->getOption('time-between-calls'); $dtMax = (new \DateTimeImmutable())->add(\DateInterval::createFromDateString("+ {$timeLimit} seconds")); do{ // Here we should execute a service to query and send notifications // ...... sleep($timeBetweenCalls); $dtCurrent = new \DateTimeImmutable(); }while($dtCurrent forceFinish); return Command::SUCCESS; } public function signalHandler(int $signalNumber): void { echo 'Signal catch: ' . $signalNumber . PHP_EOL; match ($signalNumber) { SIGTERM, SIGINT => $this->forceFinish = true, default => null }; } }
讓我們一步一步解釋一下指令:
-
configure 方法宣告輸入選項:
- 時間限制:命令進程可以存活的最長時間。之後,它將完成,主管將重新啟動它。
- time- Between-calls:每次循環迭代後的睡眠時間。此循環呼叫處理通知的服務,然後在此期間休眠。
-
execute 方法的行為如下:
- 將 forceFinish 類別變數設為 true
- 使用 PHP pnctl 函式庫註冊方法 signalHandler 來處理 Unix SIGTERM 和 SIGINT 訊號。
- 取得輸入選項值並計算指令可以有效的最大日期,直到使用時間限制選項值。
- do-while 循環執行所需的程式碼來取得通知並發送通知(它沒有放在命令中,而是有註解)。然後,它會休眠由 time- Between-calls 選項建立的時間,然後再繼續。
- 如果當前日期(在每次循環迭代中計算)低於最大日期並且 forceFinish 為 false,則循環繼續。否則命令完成。
signalHandler 函式擷取 SIGTERM 和 SIGINT Unix 訊號。 SIGINT是當我們按下Ctrl+C時發送的訊號,SIGTERM是當我們使用kill指令時的預設訊號。當signalHandler 函數偵測到它們時,它會將forceFinish 變數設為true,這樣,當當前循環完成時,命令將完成,因為forceFinish 變數為不再虛假。這允許用戶終止進程,而不必等到最大日期完成。
配置主管
到目前為止,我們已經建立了命令。現在是時候設定主管了,以便它可以處理它。在開始設定之前,我們必須安裝supervisor。您可以執行以下命令來完成此操作:
sudo apt update && sudo apt install supervisor
安裝後,您可以透過執行以下命令來確保supervisor正在運行:
sudo systemctl status supervisor
Supervisor 設定檔放置在下列資料夾中:/etc/supervisor/conf.d。讓我們建立一個名為 notif.conf 的檔案並貼上以下內容:
command=php <your_project_folder>/bin/console app:notifications --time-limit=120 --time-between-calls=10 user=<your_user> numprocs=1 autostart=true autorestart=true process_name=%(program_name)s_%(process_num)02d </your_user></your_project_folder>
讓我們解釋一下每個鍵:
- 指令:啟動指令
- user:執行指令的unix使用者
- numprocs:要運行的進程數
- autostart:是否自動啟動指令
- autostart:是否自動重啟指令
- process_name:指令unix行程名稱格式。
使用此配置,app:notifications 命令將運行最多 120 秒,並且在每次循環後它將休眠 10 秒。經過 120 秒或快取 unix 訊號後,該指令將退出循環並完成。然後,主管將再次啟動。
結論
我們已經學會如何使用supervisor來保持命令運行而無需使用crontab。當 crontab 啟動的進程可能重疊並導致資料損壞時,這會很有用。
在我寫的上一本書中,我展示瞭如何使用 Supervisor 來保持 symfony Messenger Worker 的運作。如果您想了解更多信息,可以在這裡找到這本書:使用 PHP 和 Symfony 框架構建面向操作的 Api:分步指南
以上是使用 Supervisor 處理 Symfony 指令執行的詳細內容。更多資訊請關注PHP中文網其他相關文章!

長URL(通常用關鍵字和跟踪參數都混亂)可以阻止訪問者。 URL縮短腳本提供了解決方案,創建了簡潔的鏈接,非常適合社交媒體和其他平台。 這些腳本對於單個網站很有價值

在Facebook在2012年通過Facebook備受矚目的收購之後,Instagram採用了兩套API供第三方使用。這些是Instagram Graph API和Instagram Basic Display API。作為開發人員建立一個需要信息的應用程序

Laravel使用其直觀的閃存方法簡化了處理臨時會話數據。這非常適合在您的應用程序中顯示簡短的消息,警報或通知。 默認情況下,數據僅針對後續請求: $請求 -

這是有關用Laravel後端構建React應用程序的系列的第二個也是最後一部分。在該系列的第一部分中,我們使用Laravel為基本的產品上市應用程序創建了一個RESTFUL API。在本教程中,我們將成為開發人員

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显著减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

PHP客戶端URL(curl)擴展是開發人員的強大工具,可以與遠程服務器和REST API無縫交互。通過利用Libcurl(備受尊敬的多協議文件傳輸庫),PHP curl促進了有效的執行

您是否想為客戶最緊迫的問題提供實時的即時解決方案? 實時聊天使您可以與客戶進行實時對話,並立即解決他們的問題。它允許您為您的自定義提供更快的服務

2025年的PHP景觀調查調查了當前的PHP發展趨勢。 它探討了框架用法,部署方法和挑戰,旨在為開發人員和企業提供見解。 該調查預計現代PHP Versio的增長


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

禪工作室 13.0.1
強大的PHP整合開發環境

SublimeText3漢化版
中文版,非常好用

SublimeText3 Linux新版
SublimeText3 Linux最新版

記事本++7.3.1
好用且免費的程式碼編輯器

Dreamweaver CS6
視覺化網頁開發工具