APScheduler定時任務不執(zhí)行?

? ? ? ?不知你有沒有遇到APScheduler定時任務部分未執(zhí)行的情況,我反正是遇到了,任務隨機性的不執(zhí)行,一看官網(wǎng)文檔,才知道是自己的使用方法不對。

? ? ? ?當前網(wǎng)上的大多數(shù)文章都只說了基本的使用方法,沒說注意事項。我在這里整理一下:

1. Executor 是默認大小為10的ThreadPoolExecutor。

原文:

from apscheduler.schedulers.background import BackgroundScheduler

scheduler = BackgroundScheduler()

# This will get you a BackgroundScheduler with a MemoryJobStore named “default”
# and a ThreadPoolExecutor named “default” with a default maximum thread count of 10.

? ? ? ?如果任務是CPU密集型,可以修改默認的Executor為ProcessPoolExecutor:

executors = {
    'default': ProcessPoolExecutor(5)
}
scheduler = BackgroundScheduler(executors=executors)

2. 任務未執(zhí)行的原因

? ? ? ?原因1:Executor如果是默認的10個線程池,恰好10個線程都在忙,恰好又有一個任務A該執(zhí)行了,由于沒有空閑線程來處理,這個任務A將被拋棄。
原文:

If the execution of a job is delayed due to no threads or processes being available in the pool, the executor may skip it due to it being run too late (compared to its originally designated run time)

? ? ? ?原因2:如果有個任務B的執(zhí)行時間是00:02,碰巧你的服務在00:00的時候宕機/重啟了,等服務恢復的時候,已經(jīng)過了00:02的執(zhí)行時間了,那么任務B也會被拋棄。
原文:

Sometimes the scheduler may be unable to execute a scheduled job at the time it was scheduled to run. The most common case is when a job is scheduled in a persistent job store and the scheduler is shut down and restarted after the job was supposed to execute.

3. 解決方法

job_defaults = {
    'coalesce': True,
    'misfire_grace_time': None
}
scheduler = BackgroundScheduler(job_defaults=job_defaults) # 全局設置misfire_grace_time
# 或者
scheduler.add_job(……, misfire_grace_time=None, coalesce=True) # 對單個任務設置 misfire_grace_time

? ? ? ?每個任務都有一個misfire_grace_time,單位:秒,默認是0秒。意思是 那些錯過的任務在有條件執(zhí)行時(有線程空閑出來/服務已恢復),如果還沒有超過misfire_grace_time,就會被再次執(zhí)行。如果misfire_grace_time=None,就是不論任務錯過了多長時間,都會再次執(zhí)行。
原文:

misfire_grace_time: seconds after the designated runtime that the job is still allowed to be run (or None to allow the job to run no matter how late it is)

? ? ? ?如果有個任務C是每2分鐘執(zhí)行一次的周期性任務,且設置了較長misfire_grace_time ,結果服務停了10分鐘,10分鐘后服務恢復,那么錯過的5個任務C都會執(zhí)行。這種情況下,如果你只想執(zhí)行1個任務C,可以設置coalesce = True。

原文:

When this happens, the job is considered to have “misfired”. The scheduler will then check each missed execution time against the job’s misfire_grace_time option (which can be set on per-job basis or globally in the scheduler) to see if the execution should still be triggered. This can lead into the job being executed several times in succession.

If this behavior is undesirable for your particular use case, it is possible to use coalescing to roll all these missed executions into one. In other words, if coalescing is enabled for the job and the scheduler sees one or more queued executions for the job, it will only trigger it once. No misfire events will be sent for the “bypassed” runs.

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容