只有累積,沒有奇蹟

2023年1月15日 星期日

[.NET] Quartz.NET 排程執行異常 - All triggers of Job class set to ERROR state.

問題 
最近因為新專案需求是定期到資料庫檢查會員的資料,因此使用 ASP.NET Core Hosting 服務 +  Quartz.NET 作為工作排程器使用,在開發完畢要啟動 Job 驗證正確性時意外跳出異常訊息,錯誤訊息為  Quartz.Simpl.RAMJobStore | All triggers of Job GroupName.ClassName set to ERROR state. ,這篇就針對此案例作簡單紀錄與分享若是有不清楚或是錯誤的地方歡迎討論予糾正

解決方法 
首先先看一下案發現場的錯誤 log 如下
上面可以看到當程式啟動時所紀錄的 Log 資訊,像是有紀錄目前所使用的版本為 3.0.7 版,預設 ThreadPool 為 10 條,但一到 QuartzScheduler 啟動之後下一個 Log 就直接紀錄執行異常 ( ERROR STATE ),搜尋相關異常訊息發現以下資訊
It should be extremely rare for this method to throw an exception - basically only the case where there is no way at all to instantiate and prepare the Job for execution. When the exception is thrown, the Scheduler will move all triggers associated with the Job into the state, which will require human intervention (e.g. an application restart after fixing whatever configuration problem led to the issue with instantiating the Job).
可能問題為 Quartz.NET 啟動此 Trigger 當下發生錯誤,有可能是因為沒有辦法實例化或是準備執行 Job 發生異常,當執行拋出異常時會將有關聯的作業關閉,會自動更新異常 TRIGGER_STATE 狀態為 ERROR state,需要人工進行修復,修復完畢後再重新啟用應用程式。因此下一步是了解啟動時發生的錯誤資訊,為了得到相關錯誤訊息,調整既有的代碼將  JobExecutionException  資訊紀錄在 log.Error 中,
  1. class SomeJob : IJob
  2. {
  3. private readonly ILogger _logger;
  4. private readonly IMemberService _service;
  5.  
  6. public SomeJob(IMemberService service, ILogger logger)
  7. {
  8. this._service = service;
  9. this._logger = logger;
  10. }
  11. public Task Execute(IJobExecutionContext context)
  12. {
  13. try
  14. {
  15. // todo something
  16. }
  17. catch (Exception e)
  18. {
  19. JobExecutionException je = new JobExecutionException(e);
  20. je.RefireImmediately = true; //do something with the exception
  21.  
  22. _logger.Error(je);
  23. return Task.FromResult(0);
  24. }
  25.  
  26. return Task.FromResult(0);
  27. }
  28. }
接著重新執行應用程式,並觀察 Log 資訊
果不其然,透過 Log 可以發現是在 Service 的建構子 ctor 注入時發生錯誤,所以才會在排程要啟動時異常
停止此 Job 的執行動作,在往下追發現是其 interface 存取修飾子設定異常 ( 應該要是 public 實際卻是 internal ),修正後在重新執行可以看到下列 Log,
  1. Quartz.Core.QuartzSchedulerThread|Batch acquisition of 1 triggers |url: |action:
執行正常,宣告結案 !

參考
Recover from trigger ERROR state after Job constructor threw an exception?

Related Posts:

  • [AWS] 使用 AWS SDK上傳檔案到 AWS S3前言 最近在與第三方做串接時,有個需求是要將圖片存起來放在 Application Server 上,與同事討論建議將圖片放在AWS S3 上,多年前有微軟剛推出 Azure 時有接觸過一些,但這幾年隨著年紀增長早已忘光光,這篇簡單紀錄 C# 透過 AWS SDK 將圖片上傳到 AWS S3 上的步驟與要注意的細節 AWS S3  Amazon Simple Storage Service 功能簡稱 S3,是Amazon的物件儲存服務,… Read More
  • [.NET] 無法載入檔案或組件 'Newtonsoft.Json' 或其相依性的其中之一 (發生例外狀況於 HRESULT: 0x80131040)問題 接獲同事報案,反應在測試環境出現以下錯誤訊息 無法載入檔案或組件 'Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' 或其相依性的其中之一。 找到的組件資訊清單定義與組件參考不符。 (發生例外狀況於 HRESULT: 0x80131040) ,實際專案底下 bin 資料夾該 dll 是存在的,心想這問題… Read More
  • [.NET] 伺服器認可通訊協定違規. Section=ResponseHeader Detail=CR 必須在 LF 之前問題 公司某個專案是使用 RestSharp 套件進行發送 Request 呼叫第三方的動作,今天在使用時忽然出現沒看過的錯誤訊息 伺服器認可通訊協定違規. Section=ResponseHeader Detail=CR 必須在 LF 之前 ,開發這麼多年來第一次看到此錯誤,筆記一下解決此問題的過程以表示對這問題的重視 處理方式 還原現場  先還原現場 Code 頗單純的,SendRequest 方法使用… Read More
  • [.NET] 如何取得 Enum 的 Description 描述字串前言  列舉類型 Enum 在 C# 很常用的一種類型,所允許的型別必須是byte、sbyte、short、ushort、int、uint、long、ulong,在使用上沒特別指定的話基本類型是 int,對我自己來說在程式中使用 Enum 而不用 int 的好處是 Code 閱讀上比較清晰,舉例來說在閱讀代碼時第一段代碼使用 Enum 更容易讓人好懂些 if (code == ResponseCode.OK) //… Read More
  • [CheatSheets] ASP.NET 狀態比較表 ASP.NET 狀態比較表 幸運的找到一張圖說明ASP.NET的各種狀態(ASP.NET State Management)比較表,透過這張圖表可以更詳細的瞭解各狀態之間的關係比較 圖表來源 Bubblog,如有侵權或是不妥請告知 … Read More

0 意見:

張貼留言

Copyright © 2025 m@rcus 學習筆記 | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com