雖然有很多開源工具通過插件或其它方式可以監測這些開源組件提供的內在性能(所謂內在性能就是這些開源組件提供的類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)完善網站的分頁等功能
最后預祝大家新年快樂!