架構設計的原則
阿新 • • 發佈:2019-01-28
(1) N+1原則,即任何服務在部署時都要多部署一個冗餘服務,這即能防止服務出現單點部署(由於N>1,所以部署總數至少為2),也能防止故障發生時系統還能有一定的承載的能力;
(2) 回滾設計,確保每個升級的版本都要向後相容,即要相容以前的舊版本,這樣可以防止新版本故障時可以立即回滾;
(3) 禁用設計,當一個系統要另一個高風險模組或服務對接時,要能夠通過開關來禁用它,而且儘量減少對原有功能的影響,這樣一旦生成環境中高風險模組發生故障時,我們可以快速關閉它;
(4) 監控設計,尤其是針對分散式的微服務架構中,一個複雜的系統往往有多個功能獨立的服務來組合完成,這種分散的設計增加了故障發生的概率,而且一旦故障發生分析起來就相對困難,因此我們需要完善的監控設計,才能實施監控系統中各個服務的執行情況,一旦服務出現異常,系統應能提醒相關的運維、研發人員,如果可以它還可以自動恢復;監控設計時,要充分考慮通用監控系統、詳細監控功能、日誌分析系統等等,例如我們常用的nagios、zabbix等都是常用的通用監控系統,可以用於監控某個主機上的某個服務程序是否還存在;詳細監控功能可以監控到服務程序是否存在假死現象;日誌收集和分析系統不僅能協助相關人員事後分析、定位問題,而且通過對歷史日誌資訊的分析也能挖掘出一些潛在的風險點;
(5) 設計多活資料中心,這個對於大多數中小公司來說都用不上;
(6) 使用成熟的技術;在系統的關鍵位置一定使用成熟穩定的技術;在團隊開發過程中,大家經常熱衷於追求新技術,新框架,例如,我們在選用rpc框架時,就有采用thrift還是grpc的大討論,我們當時的原則選擇thrift,就是因為rpc框架是後臺業務的關鍵部分,thrift相對成熟、穩定,並且我們詳細分析、學習過它的原始碼,對它的掌握更充分,雖然grpc宣稱效率很高,而且採用新的go語言,但是我們還是不願意在生產環境上的主要服務中去做嘗試。對於新技術,可以先在對系統的可用性不高的新功能上,經過一段時間的驗證,等穩定了,大家對新技術的掌握程度足夠了,再將之推廣重點領域;
(7) 非同步設計,這一點也是大家在做分散式設計時經常採用的原則,一般情況下,同步實現簡單,非同步實現複雜;但是非同步會讓系統的耦合性降低,也會讓整個系統更加彈性、健壯;其實,也沒有多少更詳細的原則來說明什麼情況下應該用非同步,非同步應該如何設計?我們只能根據自己的業務來判斷,哪裡適合去做非同步;常見的非同步結構方式就是採用訊息佇列,例如RabbitMQ、Kafka等等;
(8) 無狀態系統,這個是後臺服務開發的基本原則之一,一般情況下,我們都要求所設計的服務無狀態,所有服務處理過程中需要儲存的資料都要存入到Redis、memched等第三方獨立快取中。
(9) 優先選擇水平擴充套件,無狀態是水平擴充套件的前提,只要能做到無狀態的服務基本都具備一定的水平擴充套件能力;一般情況下,服務的水平擴充套件比較容易,垂直擴充套件則涉及到分割業務、資料,實現起來相對複雜;
(10) 設計架構要有兩個步驟的前瞻性,這個比較難以把控,其實每個人在做架構設計時都會盡量考慮後續擴充套件性,個人認為除非很瞭解業務,否則不要做太遠的考慮,考慮的越遠,所考慮的事情被實現的可能性就越低;
(11) 非核心則購買;個人理解,國內大多數公司糾結的是自研還是開源,而非自研和購買,其實每個團隊的精力、能力都是有限的,把團隊的力量儘可能的放在核心業務上,非核心業務的地方則能採用開源就採用開源,能購買就購買,千萬不能為了一個小的非重點業務而投入團隊太多的人力;
(12) 小構建、小發布、快速試錯,這時開發過程中經常採用的快速迭代原則,這一點是大家公認的;因為改動越多,風險越大,出了問題就越難分析定位;
(13) 故障隔離,防止一個服務出現故障時對整個系統產生影響,就像電路設計裡面的短路保護,一旦一個電器發生短路,則系統馬上斷電,從而防止系統中其他電器被燒壞。不同的是一般家裡電路短路時;整個家裡的電就全短路,而我們設計系統時不能因為一個模組出現故障而讓整個系統出現停止服務的問題,因此就要對各個服務模組做好故障隔離,一旦本模組出現問題了不要將問題波及到其的服務;
(14) 自動化,這一點是所有團隊努力的目標,包括自動構建、自動化測試、自動化釋出、自動化監控等等各個系統,所有這些自動化的東西構建起來所需的東西非常多,好找各個部分的自動化中都有相應的開源軟體,我們只需要把這些開源軟體應用好,也能滿足一定的自動化要求。