構建可靠的系統

2022-08-11 06:12:13 字數 2072 閱讀 5075

區分可靠和不可靠的操作,是編寫可靠**的基本要求。只有理解了什麼是可靠與不可靠才能做出正確的應對,使可靠的**簡潔,不可靠的**健壯,例如從快取中獲取資料,更新資料庫,這些就是不可靠的操作,可能因為網路,軟體,硬體等各種原因失敗,**需要根據不同的情況記錄異常或者進行重試等操作,因為更新資料庫可能失敗,需要在有一致性要求的情況加上事務。除了第三方不可靠之外,**在不同的環境也可能是不可靠的,例如單執行緒安全的**在多執行緒可能就是不可靠的,序列訪問可靠的**在併發時可能就是不可靠的,單機可靠的**在分布式環境可能就是不可靠的,小資料量時可靠的**在資料量變大時可能就是不可靠的。知道了遇到的是老虎還是hello kitty,才知道是要逃還是微笑。

fail fast做為乙個設計開發原則往往和我們的直覺背道而馳,為了系統的健壯性我們往往將錯誤自動處理掉,希望系統進行執行下去,減少錯誤的產生。其實這種做法往往會滋生出隱藏很深的bug,編寫很多magic code,導致維護**和查詢錯誤都很困難。快速失敗的原則讓錯誤盡早被發現,避免導致更大的錯誤,有人覺得程式有很多assert語句和丟擲異常很不安全,事實上fail fast不會導致系統的crash,反而因為出現什麼bug和bug在**都一目了然增加了系統的健壯性,fail fast就像創業一樣快速的試錯,如果發現方向不可行就趕緊打住避免更大的損失。比較典型的fail fast使用就是介面入參時的各種assert和呼叫第三方時的超時設定,這樣即使第三方出現故障也不會導致執行緒打滿拖垮我們的系統。

提到了快速失敗就不能不說兜底,快速失敗是為了盡快的發現錯誤,避免錯誤的隱藏和擴大。兜底是為了錯誤容忍,避免因為非核心流程的失敗導致整體功能的不可用。例如我們在獲取商品詳情時,不能因為獲取商品評價資訊失敗就導致整個商品詳情失敗;獲取某些配置資訊時本地也要有乙份兜底配置,避免因為配置資訊獲取不到導致核心業務的失敗。如果說兜底是在錯誤發生時的被動防禦,那麼降級就是對錯誤的主動預防了,同樣以商品詳情為例,在某次活動期間流量暴增,那麼可以主動放棄獲取商品評價資訊,展示商品是否有庫存代替具體的庫存數量,減小伺服器的鴨梨,加快響應速度。

設計乙個良好的api從來都不是件容易的事情,設計乙個良好的rpc呼叫的api就更加困難。假設有乙個通過商品id獲取商品詳情的需求。

最開始我們的api可能是這樣的

item getitembyid(long id)
因為是rpc呼叫,當返回是null的時候呼叫方懵逼了,這啥情況,是出錯了?是超時?是沒有商品?,於是對返回的物件進行一次封裝,api變成介樣

rpcresultgetitembyid(long id)
後面產品狗說需要批量獲取商品,於是變成批量查詢,api變成介樣

rpcresultgetitemsbyids(listids)
後面有個2b呼叫方一次性傳了10w個id過來,幾十秒也沒能查出來,於是限制最多一次傳100個避免長時間執行,api變成介樣。

rpcresultgetitemsbyidswithlimit(long id)
可見良好的rpc的api設計需要考慮

返回值需要包含錯誤碼,是業務異常還是網路異常,是否可以重試。

減少業務方的呼叫,將業務方多次呼叫才能完成的事情封裝成乙個介面。

api的命名和注釋要規範,畢竟呼叫方不清楚實現細節,能夠直**到就是api和注釋。

系統不是只執行一次,人生也不是賭博,不要總想著all in。一般對於無狀態的就採用多活方案,對於任務排程這種只有乙個能執行的可以考慮redis,zookeeper做鎖控制,某些系統也會採用一台伺服器執行,一台standby的方案,通過心跳檢查的方式發現執行的主機掛掉後拉起備機的方案。

考慮到業務的發展,流量爆發的突然性,業界有著系統架構支援10倍增長,系統設計支援5倍增長,系統實現支援2倍增長的說法。資料儲存,服務規劃這些改動比較麻煩的事情最好在設計之初的考慮清楚,隨著業務的發展也要

做好提前量,不要等到服務不可用了才想到堆機器。

除了設計和實現時遵循良好的原則規範,平滑發布也是需要考慮的一點,發布過程的相容,穩定,可回滾都是在開發之時就要考慮清楚的。除了發布過程之外,還需要考慮發布後活動前的預熱,需要通過預熱請求提高快取的命中率,保證熱點資料都在快取中,系統沒有經過預熱,大促活動來臨之時請求瞬間就擊穿了空空如也的快取直接擊垮了資料庫。

面對軟體錯誤構建可靠的分布式系統 筆記07

4 程式設計技術 4.1抽象並出發 eg thesis server1.erl module thesis server1 export start 3,stop 1,rpc 2 start name,f,state register name,spawn fun loop name,f,state...

使用redis構建可靠分布式鎖

關於分布式鎖的概念,具體實現方式,直接參閱下面兩個帖子,這裡就不多介紹了。分布式鎖的多種實現方式 分布式鎖總結 對於分布式鎖的幾種實現方式的優劣,這裡再列舉下 1.資料庫實現方式 優點 易理解 缺點 運算元據庫消耗較大,效能較低。為了處理一些異常,會使得整個方案越來越複雜 2.快取實現方式 優點 效...

系統可靠性計算

系統可靠性計算 系統可靠性計算是軟考考試的乙個重點,近些年幾乎每次考試都會考到,但這個知識點的難度不高,了解基本的運算公式,即可輕鬆應對。可靠性計算主要涉及三種系統,即串聯系統 併聯系統和冗餘系統,其中串聯系統和併聯系統的可靠性計算都非常簡單,只要了解其概念,公式很容易記住。冗餘系統要複雜一些。在實...