雖然有很多開源工具通過外掛程式或其它方式可以監測這些開源組件提供的內在效能(所謂內在效能就是這些開源組件提供的類STAT命令擷取到的資料),但是不管是部署還是擴充都很麻煩,其實花1-2天時間完全可以實現一個這樣的工具,並且擴充起來也很方便。
比如mongodb的:
又比如redis的:
這個工具實現的功能如下:
1)只需要簡單配置(在DEMO代碼裡我寫入程式碼了,您完全可以改為通過配置)就可以實現監控redis、mongodb、kt和memcached,之所以只有這些因為我們用到的只有這些,其實擴充一下也很方便,特別是有.NET用戶端的組件。
2)監控粒度可以選擇,不同的監控粒度在一頁上顯示的時間段也不一樣,大致確保一頁100個點左右。
3)為了簡單,分頁只是做了下拉,您完全可以修改為拖動或分頁控制項。
這個工具實現的原理如下:
1)利用mongodb儲存大量資料,為了效能使用了mongodb的Capped集合,而且這樣也無需考慮曆史資料的移除。
2)10秒的監控粒度是原始收集資料的粒度,通過收集器定時收集資料,直接寫入Mongodb。
3)其它監控粒度是基於未經處理資料的彙總,彙總器定時彙總資料,也是使用Capped集合,不過集合大小會小一點。
4)值的類型如下:
public enum ItemValueType { TextValue, StateValue, TotalValue, ExpressionValue, }
對於StateValue也就是狀態值直接存入資料庫,對於TotalValue也就是總數值,會在記憶體中儲存上一個值然後下一個值收集到之後會進行相減擷取到差值,對於TextValue始終儲存最新的值,對於ExpressionValue暫時沒有做處理,您可以自己實現,對於Mongodb來說我們選擇監測這些資料:
private static Dictionary<string, ComponentItem> items = new Dictionary<string, ComponentItem> { { "version", new ComponentItem("其它", "版本號碼", ItemValueType.TextValue) }, { "mem.resident", new ComponentItem("記憶體", "使用的實體記憶體大小", ItemValueType.StateValue) }, { "mem.virtual", new ComponentItem("記憶體", "使用的虛擬記憶體大小", ItemValueType.StateValue) }, { "mem.mapped", new ComponentItem("記憶體", "映射的記憶體大小", ItemValueType.StateValue) }, { "mem.mappedWithJournal", new ComponentItem("記憶體", "具有日誌的映射的記憶體大小", ItemValueType.StateValue) }, { "extra_info.page_faults", new ComponentItem("記憶體", "載入磁碟內容時發生頁錯誤的次數", ItemValueType.TotalValue) }, { "connections.current", new ComponentItem("串連", "當前串連數", ItemValueType.StateValue) }, { "connections.available", new ComponentItem("串連", "可用串連數", ItemValueType.StateValue) }, { "network.bytesIn", new ComponentItem("網路", "網路讀取位元組數", ItemValueType.TotalValue) }, { "network.bytesOut", new ComponentItem("網路", "網路發送位元組數", ItemValueType.TotalValue) }, { "network.numRequests", new ComponentItem("網路", "網路請求數", ItemValueType.TotalValue) }, { "opcounters.insert", new ComponentItem("運算元", "insert數", ItemValueType.TotalValue) }, { "opcounters.query", new ComponentItem("運算元", "query數", ItemValueType.TotalValue) }, { "opcounters.update", new ComponentItem("運算元", "update數", ItemValueType.TotalValue) }, { "opcounters.delete", new ComponentItem("運算元", "delete數", ItemValueType.TotalValue) }, { "opcounters.getmore", new ComponentItem("運算元", "遊標getmore數", ItemValueType.TotalValue) }, { "opcounters.command", new ComponentItem("運算元", "其它運算元", ItemValueType.TotalValue) }, { "indexCounters.btree.accesses", new ComponentItem("索引", "訪問索引次數", ItemValueType.TotalValue) }, { "indexCounters.btree.hits", new ComponentItem("索引", "記憶體命中索引次數", ItemValueType.TotalValue) }, { "indexCounters.btree.misses", new ComponentItem("索引", "記憶體不命中索引次數", ItemValueType.TotalValue) }, { "indexCounters.btree.resets", new ComponentItem("索引", "索引計數器重設次數", ItemValueType.TotalValue) }, { "indexCounters.btree.hits * 100 / indexCounters.btree.accesses", new ComponentItem("索引", "hitsratio ", ItemValueType.ExpressionValue) }, };
5)用戶端很簡單,使用了highchart+ajax,直接和wcf的服務端互動擷取jsonp資料來源。
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="ServiceBehaviour" > <serviceDebug includeExceptionDetailInFaults="true"/> <serviceMetadata /> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="HttpBehaviour"> <webHttp defaultBodyStyle="Wrapped" defaultOutgoingResponseFormat="Json" helpEnabled="true" /> <enableWebScript /> </behavior> </endpointBehaviors> </behaviors> <bindings> <webHttpBinding> <binding name="webHttpBindingJsonP" crossDomainScriptAccessEnabled="true"/> </webHttpBinding> </bindings> <services> <service name="Adhesive.ComponentPerformance.Core.Service" behaviorConfiguration="ServiceBehaviour" > <endpoint address="http://localhost:8888/" binding="webHttpBinding" bindingConfiguration="webHttpBindingJsonP" behaviorConfiguration="HttpBehaviour" contract="Adhesive.ComponentPerformance.Core.Service" /> <endpoint address="http://localhost:8888/mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> </system.serviceModel>
話不多說,點擊這裡下載DEMO代碼,在使用前建議你修改如下地方:
1)完善記錄日誌的地方
2)把配置改為你自己的佈建服務
3)完善其它需要監測的開源組件
4)完善網站的分頁等功能
最後預祝大家新年快樂!