只要我們所有提交到執行緒池的任務,都用一個框架統一封裝的 RunnableWrapper 類,基於裝飾模式來進行包裝。
此時就可以得到執行緒任務的建立時間、開始時間、結束時間,接著就可以計算出這個任務的排隊耗時、執行耗時,透過監控系統進行上報。
此時我們透過在監控系統裡配置告警條件,就可以實現不同執行緒池的每個任務的耗時指標上報,同時如果有某個執行緒池的某個執行緒排隊耗時或者執行耗時超過了我們配置的閾值,就會自動告警。
// 執行緒任務包裝類,用了裝飾設計模式 public class RunnableWrapper implements Runnable { // 實際要執行的執行緒任務 private Runnable task; // 執行緒任務被建立出來的時間 private long createTime; // 執行緒任務被執行緒池執行的開始時間 private long startTime; // 執行緒任務被執行緒池執行的結束時間 private long endTime; // 當這個任務被建立出來的時候,就會設定他的建立時間 // 但是接下來有可能這個任務提交到執行緒池後,會進入執行緒池的佇列排隊 public RunnableWrapper(Runnable task){ this.task = task; this.createTime = new Date().getTime(); } // 當任務線上程池排隊的時候,這個run方法是不會被執行的 // 但是當任務結束了排隊,得到執行緒池執行機會的時候,這個方法會被呼叫 // 此時就可以設定執行緒任務的開始執行時間 public void run(){ this.startTime = new Date().getTime(); // 此處可以透過呼叫監控系統的API,實現監控指標上報 // 用執行緒任務的startTime-createTime,其實就是任務排隊時間 // monitor.report("threadName", "queueWaitTime", startTime-createTime); // 接著可以呼叫包裝的實際任務的run方法 task.run(); // 任務執行完畢以後,會設定任務執行結束的時間 this.endTIme = new Date().getTime(); // 此處可以透過呼叫監控系統的API,實現監控指標上報 // 用執行緒任務的endTime - startTime,其實就是任務執行時間 // monitor.report("threadName", "taskRunTime", endTime - startTime); } }