1. 程式人生 > >Windows應用程式程序級別統一監控實踐

Windows應用程式程序級別統一監控實踐

        一般的系統級別指標監控,更多關注CPU、記憶體、磁碟、網路等執行情況,對應用程式執行時的程序指標關注不夠,導致不能深入瞭解系統執行狀態。本文根據筆者應用實踐,探討一下程序級別監控涉及到的監控內容以及監控方式,供感興趣的同行做參考。 

一、         監控內容

        眾所周知,應用軟體最終表現為應用程式,程式是指令、資料及其組織形式的描述,其本身沒有任何執行的含義,是一個靜態的概念;程序(Process)是計算機中的程式關於某資料集合上的一次執行活動,是程式的實體,是一個動態的概念。

程序的主要屬性有:程序ID、程序名稱、程序使用者名稱稱、程序狀態、程序優先順序、程序啟動時間、包含的執行緒、使用的CPU時間、使用的記憶體、控制代碼等。程序的屬性雖多,但根據筆者的應用實踐,只要重點監控幾個關鍵指標即可抓住程序的執行狀態,進而對應用程式的健康狀況做出正確的判斷,並在發生故障前快速採取止損措施。

  1. CPU

        CPU描述了程序佔用的計算資源,監控主要關注程序級別CPU的兩種場景:High CPU、Low CPU。

        當程序長時間處於High CPU狀態時,除了正常負載高的情況,程式內部可能:

        a.在不斷產生大量異常

        b.發生了死迴圈

        c.在頻繁做垃圾回收(Garbage Collection,GC)

        當程序長時間處於Low CPU狀態時,程式內部可能:

        a.發生了死鎖

        b.發生了阻塞

      2.記憶體

        記憶體描述了程序佔用的儲存資源,由於Windows資源分為託管資源和非託管資源,因此監控程序級別的記憶體,應該關注同時包含這兩種資源的提交記憶體(Commit Size)。

監控主要關注程序級別High Memory場景,當程序長時間處於High Memory狀態時,程式內部可能:

        a.發生了記憶體洩漏,物件一直被使用,無法及時釋放

        b.產生了記憶體碎片,導致記憶體溢位(Out Of Memory,OOM)

        3.埠數

        埠數描述了程序佔用的網路資源,通過命令“netstat -ano”可以獲得整個機器的網路埠數佔用情況,但無法直接獲得每個程序的網路埠數佔用情況,因此需要對“netstat -ano”輸出的程序ID做分組彙總,以便獲得每個程序佔用的埠數,從而對程序的監控深入一個層次。

當程序佔用的埠數過高時,程式內部可能發生了埠洩漏。

        4.活躍執行緒數

        程序是執行緒的容器,一個程序可以包括多個執行緒,程序和執行緒都是CPU工作時間段的描述。執行緒具有生命週期,因此具有很多狀態(新建、就緒、執行、阻塞、死亡),從Windows工作管理員看到的某個程序包含的執行緒數,是所有狀態的執行緒數,監控粒度比較粗。

        程序級別的執行緒監控,應該關注活躍執行緒數,也就是真正在執行的執行緒數,這可以通過如下方法得到:

private int GetActiveThreadCount()

{

int MaxWorkerThreads, miot, AvailableWorkerThreads, aiot;

ThreadPool.GetMaxThreads(out MaxWorkerThreads, out miot);

AvailableWorkerThreads = aiot = 0;

    ThreadPool.GetAvailableThreads(out AvailableWorkerThreads, out aiot);

    return MaxWorkerThreads - AvailableWorkerThreads;

}

        當程序包含的活躍執行緒數過高時,程式內部可能發生了執行緒洩漏。

        5.同一程序組流量分佈

        前面的幾個指標關注的是單一程序,當不同機器上的程序組成一個叢集時,需要同時關注這些程序組間的指標,比如流量分佈。

當一個叢集負載均衡的處理請求時,流量應該是均分到每一個處理程序的,如果監控到某一個程序處理的TPS遠小於整個叢集的平均TPS時,該程序很可能發生了阻塞或宕機

        6.可用性指標

        可用性指標是指可以作為度量系統死活點(Dead Live Point,DLP)的指標,一般關注兩個方面:程序可用性、程序上執行的服務可用性。

        程序可用性主要判斷程序是否仍然存活,可以通過呼叫系統介面判斷程序是否存在,也可以通過程序埋點上報心跳資訊。

        程序上執行的服務可用性主要關注服務執行的成功率或失敗率,因此涉及到的業務因素比較多,限於篇幅不再展開。如果整個系統基於微服務框架,比如高速服務框架(High Speed Framework,HSF),則可以對服務呼叫進行統一監控,從而可以統一計算服務可用性。

二、         監控方式

        對程序級別的監控由於比較底層,一般採用兩種手段:監控主動收集、程序埋點上報。

  1. 監控主動收集

        主動收集又分為兩種方式:通過系統介面獲得機器上所有程序資訊、通過效能計數器獲得程序級別監控指標,兩種方式都是非侵入式的,不會影響程序的正常執行,是首要考慮的監控方式。

        2.程序埋點上報

        埋點是一種常見的資料採集方式,在要精準獲得程序級別監控資料時,程式碼埋點可能是最好的選擇。比如前面提到的獲得程序包含的活躍執行緒數,以及可用性指標,都需要程序埋點上報才能獲得比較精確的監控指標。當然程序埋點並不需要對每個程序都做埋點開發,可以在框架層面進行統一埋點,從而降低埋點開發及實施成本。

三、         總結

        只有深刻認識到程序級別監控涉及的監控內容及監控方式,才能更深入的掌握系統執行狀態,並在系統開始惡化前針對不同程序指標快速做出點殺動作(比如通過自動運維進行有順序的程序重啟),從而做到及時止損。