1.高可用
容錯和降級。
容錯級別上,忽略次要 error < 服務降級 。程式中部分error是可以忽略處理的,或者打個日誌標記下,而不用結束整個執行流程。服務降級是指,當依賴的非核心模組出問題時,可以選擇不請求或者熔斷式請求(過載保護),資料可以不吐給客戶端,這就要求對資料或者服務進行級別劃分,優先保證使用者的基礎體驗。如果對實時性要求不是特別高的,可以將上次請求的資料快取下來做災備資料,這個做法在聚合類介面提供系統可用性上非常有幫助。
容災 通常就包括機器的容災和機房的容災。如果是http server,一般slb這裡會有ping check,如果某台機器掛掉slb會切掉這台機器。如果是rpc server,節點掛掉也會自動摘掉這個節點。機房容災也是很有必要的,也許突然某個時候機房的網線電纜被挖斷了呢!相比於機器容災,機房容災的成本也是比較高的。前期技術成本考慮,傾向於一主一備,畢竟雙寫的技術要求是比較高的。
隔離 隔離包括邏輯隔離和物理隔離,邏輯隔離是指多程序隔離啊、不同mysql例項啊、業務拆分隔離啊、docker化等等,還有包括cache、db、檔案儲存系統等都需要做隔離。而物理隔離一般指機器隔離部署、多機房方案等,它和邏輯隔離互為補充的。還有一種架構上的隔離,比如幾個大的核心業務同時依賴基礎核心資料cache,那麼這個cache也可以做多份隔離。隔離是避免因為其他業務的突發流量或者異常訪問或者無法預期的問題,從而引起影響整個系統甚至影響所有業務。我們的微服務系統採用group化進行隔離和擴容。
快取 通常考慮兩種場景。第一種,資料是本身的,比如是業務本身的db資料,所以要給自己加cache,通常能擋90%以上的讀流量,這樣相對於只訪問資料來源則多了一種可靠方案。另一種場景,a模組依賴b模組的資料,很多時候a還要作一層甚至兩層cache。比如a做乙個local cache,配置成unix sock方式(更甚一步是放記憶體裡),過期時間比較短,以滿足業務上的實時性要求(或者配置時間長,通過訂閱事件去更新)。另外還會加乙個remote cache,過期時間很久。當local cache沒有命中時會訪問資料來源b,而當b掛掉的時候,我們可以讀remote cache,相當於降級處理,因此能提高系統的可用性。這裡a和b的cache操作是幾乎一樣的,實現成本很低。
限流 任何乙個服務端系統總是也承載上限的,與其忽略這個問題,不如給系統做壓測設上限,在流量突發時能至少保證系統不掛。觸發限流的原因有很多,有時是業務突發**,有時是前端bug,有些是非同步任務堆積,甚至有時是受到人為攻擊。通常整個**的入口slb並非能準確限制某個業務的流量,所以各個業務自身也要考慮限流。從閘道器到業務模組到資料模組,整個鏈路全部都要做限流!否則瞬時的流量峰值可能會把系統的某個節點打掛,從而影響整個系統,甚至很可能引發雪崩效應。我司的限流也是在基礎框架做的,使用的令牌桶演算法,業務**只要註冊下要限流的介面即可。同時作為client,也要做限流保護後端,比如熔斷降級、請求合併等。
弱化核心依賴 乙個系統如果沒有核心依賴就無敵了,當然現實中很難避免,通常要做的是弱化或者隔離分散壓力。舉個工作中的例子。業務很多介面都依賴使用者身份校驗或者介面簽名校驗,而檢驗是走帳號**的rpc介面做的。帳號**除了做校驗,還是個基礎服務,經常要做功能或技術迭代,所以也大大小小出了幾次小故障。但是卻影響了幾乎所有的模組!所以要隔離,不過我們做的更徹底,沒有拆成服務,而是以基礎庫的方式,業務自己直接訪問認證cache和校驗,同時快取也做了隔離。這次幾乎看不到校驗的邏輯了,再也沒出過問題。還有個例項,我們業務cache之前都是走tw集群**,但是因為各種原因tw集群本身出過幾次問題,於是我們將tw本地化,做徹底隔離,穩定性好很多,當然配置變更會麻煩一些。
2.高效能
高效能體現在兩個方面,乙個是低延時,乙個是高併發。怎麼做到呢?
怎麼降低延時呢?快取+非同步+並行+超時 快取就不用說了,記憶體比io快是肯定的。能非同步的盡量非同步,比如更新cache、事件通知;並行對於資料聚合介面也是很有效的,尤其有時候要訪問幾個甚至更多依賴服務的時候,同步的序列訪問耗時是非常大的,golang可以參考下errgroup這個庫。超時更是降低延時的一大利器,通常超時的時間是基於依賴模組的統計確定的,而且不能過於妥協。
**質量把關。這個點非常廣,簡單談談。一般有減少大鎖(大拆小、用cas);盡量使用批量協議(規避小包),比如redis的pipeline,包括業務協議上也需要支援批量;盡量使用指標或者引用傳遞變數以避免無意義的大記憶體拷貝;程式的邏輯框架的合理性,比如如何擴充套件支援併發擴充套件等;golang這塊還要考慮盡量不要濫用goroutine、盡量復用物件來減少gc(比如sync.pool)、少用defer、少用反射(耗效能)。
配置引數。程式依賴的各種資源的配置要適當。通常涉及時間的有dial timeout、read timeout、write timeout、idle timeout,具體依賴實際的服務端場景、物理環境和統計資料,時間太短會很敏感,讀寫超時時間一般略大於server端處理的最大時間,比如cache超時時間加db超時時間。涉及連線池的有最大活躍、最大空閒,配置太小可能導致高峰期滿足不了併發量,配置太大可能導致資源濫用影響服務端甚至影響其他業務。還有就是機器部署上的配置,容量上的配置還有cpu記憶體資源等都要充足,至少要有50%的冗餘。不確定的都檢查下吧。
壓測和線上資料分析。我相信絕大多數的業務場景,無論是吃cpu的、吃io的、吃記憶體的、各種業務**質量、bug,通常都能通過壓測表現出來。我傾向於線上環境壓測或者觀察高峰期資料,**「壓爆了」就從**找問題優化,或者觀察高峰期**容易抖動或者**吃最大的cpu或者記憶體都可以作為分析點。
3.易擴充套件
擴充套件性,對業務伺服器來說,一般來說主要就是盡量做到無狀態,如果確實有狀態資料,可以放到更高可用的系統裡,比如zookeeper、redis等,筆者之前參與開發的小檔案系統就是將儲存節點的相關元資料放到zookeeper裡,這樣排程節點就非常輕量級接近無狀態。另外就是服務需要支援健康檢查、自動註冊和發現,比如rpc server可以直接註冊到zookeeper實現自動擴容等等。
4.合適的架構
沒有最好的,只有最合適的。在技術選型上也是如此。比如落地儲存有些寫量大的用hbase還是mysql呢?如果沒有牛x的hbase維護還是用mysql吧。又比如cache集群用官方的集群還是tweproxy**呢,還是超級client,得看公司運維的水平或者人力投入。再比如要不要做cache,要看是否有很高的命中率以及對資料的實時性要求,或者快取更新通道是否穩定等等,當然一般這些是要解決來滿足cache的。還有諸如機房容災要不要做,是做成雙主還是一主一從,資料庫分表是雜湊硬編碼還是使用中介軟體等等,總之,技術選型一定要考慮到業務場景(業務需求)、運維資源和水平、開發投入、穩定性和擴充套件等各方面,一味的追求牛x的架構不一定合適。
HTTP服務端JSON服務端
最後更新日期 2014 5 18 author kagula 內容簡介 cppcms是個開源web開發框架,通過它可以很容易實現http服務和json服務,這裡介紹cppcms開發環境的搭建。寫乙個cppcms測試程式,它建立http服務,向瀏覽器返回hello,world頁面。cppcms依賴的一...
服務端測試
首先服務端的測試包含哪些東西呢?實際上,服務端的測試簡單來說就是除了前端以外的的測試,總的來說可以分為以下兩類 1.web或者的提供業務邏輯的服務端介面測試 介面測試佔據工作工作中的80 介面測試的重點是要檢查資料的交換,傳遞和控制管理過程,以及系統間的相互邏輯依賴關係等。下面粗略的列舉出測試的幾個...
TeamTalk服務端分析之服務端以及客戶端流程
原文 www.bluefoxah.org teamtalk server flow.html 服務端的啟動沒有嚴格的先後流程,因為各端在啟動後會去主動連線其所依賴的服務端。不過在此,如果是線上環境,還是建議按照如下的啟動順序去啟動 也不是唯一的順序 1 啟動db proxy。2 啟動route se...