除此以外,從業務邏輯來看SNMP Agent相對的穩定,由於它只是翻譯收到的SNMP消息並最終調用Box庫中的函數完成消息的處理,而Box庫會因業務的演進而頻繁地變更,於是Box庫出錯的可能性也更大。那如何經過設計來介定當堆棧被破壞這類嚴重的問題出現時,應當由哪一個團隊去負責追查問題的根源呢?或者說,SNMP Agent團隊如何經過設計來保護本身以避免「背黑鍋」呢?這種防範是有意義的,它不僅意味着問題出現時能快速的介定責任團隊,也能夠避免沒有必要的團隊扯皮,說到底就是能提升工做效率。
做者所提出來的第一個解決方案的思路是,可否經過設計一種方法記錄SNMP Agent程序當前正在運行哪一部分的代碼?固然,這種信息只要足於區分是運行Box庫中的代碼或是SNMP Agent中的就好了。最爲直觀的作法是,每調用Box庫中的函數時,在調用以前打印一行日誌,在調用返回後又打印一行日誌。這種方法在前面說起了,可能會存在必定的性能問題,但其思路仍是對的,只是須要採用其它的更爲高效的方式替代日誌記錄。做者想到了Linux中的共享內存!Linux中的共享內存有一個特色,一個程序若是分配了一塊共享內存,若是程序不主動對其刪除,則即便是程序出現了崩潰其中的內容也一直保存在那不會被更改,固然操做系統進行過了重啓的話則除外。
如此一來,經過設計能夠將調用Box函數以前和以後的信息經過使用一個×××變量的方式記錄程序是不是在調用Box庫,固然,這個×××變量是位於SNMP Agent所建立的共享內存中的。好比設置整型值3表示將要調用Box庫中的某一個函數,而在調用完了這一函數後將這一值設置成4。當SNMP Agent出現崩潰後,在其下一次啓動的初始化階段時(咱們的系統有進程管理程序,發現一個進程出現崩潰之後,又會自動重啓它),經過打開同一個共享內存塊就能夠知道上一次程序出錯時,是不是出如今調用Box庫其間,若是是則記錄一個錯誤日誌。好比,若是發現整型變量的值爲3說明崩潰是發生在Box庫內的,則記錄一條錯誤日誌。固然,設計考慮到了多線程的問題,且以線程爲單位來設計的。有了這種方法,當出現問題時,經過查看日誌就能很快地定位責任團隊,且幾乎徹底不失程序的執行效率。
這種設計方案在操做中存在必定的運做效率問題。好比,即便是Box庫的問題,這一問題一旦在測試部門發現,則必定會將缺陷提交給SNMP Agent團隊,SNMP Agent團隊在查看日誌後,發現是Box庫形成的問題,因而將缺陷轉交給了Box庫團隊。能不能又經過設計讓Box庫一出現問題就讓測試部門將缺陷提交給Box庫團隊呢?圖2展現了進一步的設計方案。
圖2
在這一方案中,增長了一個新的Proxy進程,這個進程的程序也是由SNMP Agent團隊開發的。SNMP Agent進程和Proxy進程之間採用了IPC(Inter-Process Communication,即進程間通信)進行通信,就是將前一方案中SNMP Agent直接調用Box庫函數的形式轉化成了經過進程間通信將這一調用發送給Proxy進程,Proxy進程再經過FDR接口調用Box案。固然上一方案中採用共享內存記錄哪一部分代碼正被調用的方法被運用到了Proxy進程上,以幫助介定問題是發生在Proxy進程自己仍是在Box庫內。在這種方案中,其中很重要的一個內容是,Proxy進程的邏輯很是的簡單,即接受來自SNMP Agent的消息而後調用Box庫函數並經過消息將Box庫函數所返回結果傳給SNMP Agent,其邏輯不會由於項目的不斷變化而變化,除非FDR發生了變化。可能這種方案剛開始部署時,Proxy會有必定的缺陷,但通過必定的時期穩定後,一旦出現Proxy崩潰的問題,則極有可能就是Box庫所引發的了,而這種情形下測試部門能夠直接將缺陷提交給Box庫團隊。
至此,相信讀者已明白了「保護本身」這一設計原則是如何起做用的了,可能有的讀者也會有一點靈感去解決本身項目中正面臨的相似惱人問題。另外,不知讀者注意到了沒有,這裏所談的共享內存方案,其實能夠做爲一種通機制去輔助縮小出現問題時程序的出錯範圍。前面也提到是經過一個位於共享內存中整型變量來記錄程序的運行點的,而這個變量能夠定義232個值用於表示程序的不一樣執行點,固然應用程序須要在合適的地方對其設置不一樣的值來指示程序運行到了什麼地方。