国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

有大佬實現過不阻塞的定時器服務嗎

lcmg

問題描述

比如我有很多定時器,有指定時間執(zhí)行的比如每天0點28分執(zhí)行【28 0 】,有固定間隔時間段執(zhí)行的比如每五分鐘執(zhí)行異常【0 /1 】,還可以動態(tài)的添加管理這些定時器

為此你搜索到了哪些方案及不適用的原因

有參考過插件市場的yzh52521/webman-task,啟動兩個服務,一個提供http請求處理添加刪除操作,一個啟動自定義進程來實現定時任務的執(zhí)行,在內部http和自定義進程通訊來進行數據交互
但是原生的Crontab定時任務是阻塞執(zhí)行的,如果有一個執(zhí)行很久會導致剩下的不能再對應時間執(zhí)行,阻塞期間http服務與自定義進程之間的通訊還會掛起
然后試過使用swoole做事件循環(huán),在new Crontab的callback中使用go(function(){}),這樣確實可以實現不阻塞的執(zhí)行定時程序,也不會阻塞自定義進程的通訊服務,但是隨著定時程序的數量、耗時增多,后面查看日志會發(fā)現時不時的exit with status 11、exit with status 65280報錯,然后進程自動重啟,在runtimes下面也看不到具體的報錯日志
截圖

后面又試過直接使用swoole開啟tcp服務,在workerStart里面初始化定時器,在receive里面接受http的請求來管理定時器執(zhí)行,因為swoole不支持linux的crontab表達式,webman的實現是生成一個回調函數,拿到下一分鐘要執(zhí)行的定時任務依次Timer::add生成定時器,我把Timer::add替換成\Swoole\Timer::after就可以在swoole中使用crontab表達式,執(zhí)行的時候也是Co::create()執(zhí)行的,然后發(fā)現定時器可以正常按時間執(zhí)行,但是定時器執(zhí)行后tcp服務就被掛起了,無法和http交互
截圖

請問各位大佬有類似實現過對應功能嗎,怎么解決支持秒級的定時器執(zhí)行,并且可以進行通訊、定時任務執(zhí)行期間不阻塞服務的

1189 5 0
5個回答

six

架構一般是一個定時進程,一堆http業(yè)務進程。
定時進程負責定時觸發(fā)任務,使用workerman/http-client異步調用,這樣定時進程不會有任何阻塞操作。
http業(yè)務進程負責處理具體的定時任務,任務本身是否阻塞沒有太大影響,只要http進程足夠就行。

  • 暫無評論
小Z先生

可以考慮使用隊列進行業(yè)務邏輯處理,定時器只用于發(fā)送隊列消息,這樣就不需要考慮定時器的阻塞問題了

  • 暫無評論
軟飯工程師

使用php協程,參考文檔
http://www.wtbis.cn/a/1723
https://ripple.cloudtay.com/docs/basic/defer/
在定時器里面用協程執(zhí)行任務,定時器會立即返回,開始執(zhí)行下一個定時器,并不會阻塞,這樣解決了多個定時器互相阻塞的問題

  • latin 2024-09-09

    協程還是當前進程執(zhí)行,定時任務里如果是阻塞調用,整體進程還是阻塞的。這樣就協程沒有作用

  • 胡桃 2024-09-09

    Fiber/Revolt 那一套遇到死循環(huán)確實只能傻眼,但是 Swoole 有搶占式調度。

  • lcmg 2024-09-09

    后續(xù)還是用swoole實現了,swoole開啟的tcp服務設置運行協程和一鍵協程化之后,tcp的通訊服務和定時任務就互不阻塞了。其中最主要的問題還是用swoole作為webman的eventloop之后,看起來是互相沖突導致webman子進程重啟,沒這個問題的話兩個一起用還是挺方便的
    $server = new Server($host, (int)$port, SWOOLE_PROCESS);
    // 設置服務器為異步非阻塞模式
    $server->set([
    'worker_num' => 1,
    'enable_coroutine' => true,
    'max_coroutine' => 3000,
    'daemonize' => true,
    'log_file' => runtime_path() . '/logs/swoole.log',
    'log_date_format' => '%Y-%m-%d %H:%M:%S',
    'log_rotation' => SWOOLE_LOG_ROTATION_DAILY,
    'display_errors' => true,
    'hook_flags' => SWOOLE_HOOK_ALL,
    ]);
    // 當有客戶端數據到達時
    $server->on('receive', function (Server $server, $fd, $reactor_id, $data) {
    Co::create(function () use ($server, $fd, $data) {
    // echo "Received data from client {$fd}: {$data}\n";
    try {
    $data = json_decode($data, true);
    $method = $data['method']?:'';
    $args = $data['args']?:[];
    $res = $this->onReceive($method,$args);
    $server->send($fd,$res);
    }catch (\Exception $exception){
    $server->send($fd,json_encode(['code' => 0, 'msg' => $exception->getMessage() ]));
    }
    });
    });

efnic

插件市場:http://www.wtbis.cn/app/view/cron
最關鍵的邏輯是使用composer require symfony/process

  • 冰冰不要 2024-09-18

    這是直接一個定時器跑了一個進程嗎?

  • efnic 2024-09-21

    執(zhí)行的時候使用proc_open 執(zhí)行一個命令,并且打開用來輸入/輸出的文件指針。

wzj177

你應該已經完成??吹竭@個想到上家公司自己做的定時調度,感覺也挺好。用ai把我記憶中上家公司的實現流程總結出來了。供參考:

你的方案是可行的,尤其是結合了多進程、定時調度、任務狀態(tài)管理以及異步執(zhí)行的設計,符合大多數任務調度系統(tǒng)的最佳實踐。以下是對你的方案的總結和優(yōu)化建議:

方案總結

1. 任務調度表設計

  • 你會維護一個數據庫表來記錄任務,每個任務包括:
    • 任務 ID、任務名稱、Crontab 表達式(用于控制任務的執(zhí)行時間)、執(zhí)行模式(單次、多次、循環(huán))、任務狀態(tài)(待執(zhí)行、執(zhí)行中、成功、失敗、超時)、任務超時時間日志關聯、上次執(zhí)行時間、下次執(zhí)行時間等。
  • 任務表會定期掃描以觸發(fā)符合條件的任務,保證在合適的時間點執(zhí)行。

2. 多進程調度

  • 使用 多進程(或進程池) 來處理多個任務的并發(fā)執(zhí)行。通過 symfony/process 啟動多個子進程,讓每個任務在獨立的進程中執(zhí)行,避免任務之間的相互阻塞或影響。
  • 對于并發(fā)量較大的場景,你可以通過 進程池 來控制并發(fā)量,保證資源的合理分配。

3. Crontab 表達式解析

  • 你計劃使用 composer 包(例如 mtdowling/cron-expression)來解析任務的 crontab 表達式,從而決定任務的下次執(zhí)行時間。這可以保證靈活的任務調度。

4. 協程與異步執(zhí)行

  • 使用 swoole 提供的協程來進一步優(yōu)化任務的異步執(zhí)行,尤其是涉及網絡請求、數據庫 I/O 等操作時,協程能有效提升任務的執(zhí)行效率,避免阻塞。
  • 你也可以通過消息隊列(如 RabbitMQ、Redis)進一步解耦任務調度和執(zhí)行,確保任務的異步處理和高效并發(fā)。

5. 任務鎖與并發(fā)控制

  • 在多進程并發(fā)執(zhí)行時,需要確保每個任務只會被一個進程獲取和執(zhí)行。你計劃使用鎖機制來防止重復執(zhí)行任務。
    • 推薦使用 Redis 分布式鎖:通過 SETNX 來加鎖任務,確保每個任務在同一時刻只會被一個進程處理。任務執(zhí)行完畢后,釋放 Redis 鎖。
    • 你還可以選擇使用數據庫行鎖(SELECT ... FOR UPDATE)或文件鎖(flock)來加鎖任務。

6. 任務超時與狀態(tài)管理

  • 每個任務有明確的執(zhí)行超時時間,使用 symfony/processswoole 的超時機制確保任務不會長時間占用資源,任務執(zhí)行時間超過設定的超時時間后自動終止,并標記為“超時”狀態(tài)。
  • 根據任務的執(zhí)行結果,更新任務狀態(tài)為 成功失敗超時,并在多次或循環(huán)任務的情況下恢復狀態(tài)為 待執(zhí)行

7. 任務日志記錄

  • 每個任務執(zhí)行過程中的輸出、執(zhí)行時間、狀態(tài)、錯誤信息等都需要記錄到日志中,以便追蹤和排查問題。日志表記錄可以與任務表建立關聯。

優(yōu)化建議

  1. 任務鎖定的策略

    • 建議使用 Redis 分布式鎖 實現任務鎖定,Redis 鎖更輕量級且能有效解決多進程下的任務競爭問題。確保鎖的過期時間適當設置,以防止死鎖。
  2. 負載均衡與擴展

    • 當任務量特別大時,可以考慮使用 消息隊列 來分發(fā)任務,并通過 分布式部署 的方式擴展任務處理能力,避免單一進程成為瓶頸。
  3. 監(jiān)控與告警

    • 可以集成監(jiān)控工具(如 Prometheus、Grafana)來監(jiān)控任務的執(zhí)行狀態(tài)與性能,尤其在任務超時、失敗等異常情況下,觸發(fā)告警通知以便及時處理。

總結

總體來說,你的方案充分考慮了定時調度、任務并發(fā)、異步執(zhí)行、任務狀態(tài)管理和日志記錄,具備較強的擴展性和魯棒性。通過適當的鎖機制、進程管理與協程結合,能夠實現一個高效、穩(wěn)定的任務調度系統(tǒng)。

  • 暫無評論
年代過于久遠,無法發(fā)表回答
??