事故發生10天之後,微軟於3/9/2012對Windows Azure Service Down掉給出了總結,具體見這裡:http://blogs.msdn.com/b/windowsazure/archive/2012/03/10/summary-of-windows-azure-service-disruption-on-feb-29th-2012.aspx
從中可以看到事件的大概過程:
1. Application VM guest agent因為閏年bug無法產生certificate
2. Host OS agent發現VM guest agent無法重啟成功,會重試3次去啟動VM
3. 3次重試之後,Host OS 發現VM還是無法啟動成功
4. Host OS agent沒有收到VM guest agent發出的任何有意義的錯誤報表,於是其認為機器hardware出問題了
5. Host OS 上報Fabric Controller,認為該台機器已經無法使用,需要人工檢修
6. Fabric Controller將VM的建立轉交給其他機器,上述的流程在每個機器上重現,於是很快所有的機器都被認為是hardware出問題
7. 當所有機器都被Fabric Controller認為有問題之後,整個叢集甚至資料中心都無法提供服務了
從上述事件發生的chain來看,至少有兩點是設計時候應該考慮的:
1. 一個機器是否應該被移除的條件:上面Host OS僅僅重試三次無法初始化VM,就認為機器hareware有問題,這是有些粗暴的,沒有考慮到VM本身的bug或者Application對VM的攻擊。
2. 機器在短時間內大批量被認為hardware有問題進而導致下線,Fabric Controller沒有迅速警示:上面的summary裡面提到了當可用機器減少70%的時候,Fabric Controller會警示,這個值顯然太高了,而且沒有將時間的因素考慮進去,如果按照單位時間內機器下線率計算,我認為5%的機器出問題就足以警示了。
上述事件看起來就像一個狀態機器一樣,在設定的狀態下轉到下一個狀態,並作出相應的動作,我想如果在設計的時候清晰的描繪出這樣的狀態機器,那麼開發人員能否意識到“在一個狀態機器中,某些狀態是比另外的狀態更加重要的,某些路徑的代價是比另外的路徑的代價更大的?”,這樣的話,也許上面的bug在開發review的階段能夠被發現。
推此即彼,編程也是一樣的,一個程式從main開始執行就在做狀態轉換,那麼我們是否能將其中比較high level的狀態轉換清晰的畫出來並且仔細甄別哪些狀態更重要?哪些路徑要更加小心?也許這樣,是降低大bug的一個很好的辦法。