剑网3指尖江湖职业推荐 www.1468054.com

從目前可以得到的信息來看,對分布式服務化架構實踐最早的應該是亞馬遜。因為早在 2002 年的時候,亞馬遜 CEO 杰夫·貝索斯(Jeff Bezos)就向全公司頒布了下面的這幾條架構規定(來自《Steve Yegge 對 Google 平臺吐槽》一文)。

  1. 所有團隊的程序??槎家ü?Service Interface 方式將其數據與功能開放出來。
  2. 團隊間程序??櫚男畔⑼ㄐ?,都要通過這些接口。
  3. 除此之外沒有其它的通信方式。其他形式一概不允許:不能直接鏈結別的程序(把其他團隊的程序當做動態鏈接庫來鏈接),不能直接讀取其他團隊的數據庫,不能使用共享內存模式,不能使用別人??櫚暮竺?,等等。唯一允許的通信方式是調用 Service Interface。
  4. 任何技術都可以使用。比如:HTTP、CORBA、Pub/Sub、自定義的網絡協議等。
  5. 所有的 Service Interface,毫無例外,都必須從骨子里到表面上設計成能對外界開放的。也就是說,團隊必須做好規劃與設計,以便未來把接口開放給全世界的程序員,沒有任何例外。
  6. 不這樣做的人會被炒魷魚。

這應該就是 AWS(Amazon Web Service)出現的基因吧。當然,前面說過,采用分布式系統架構后會出現很多的問題。比如:

  • 一個線上故障的工單會在不同的服務和不同的團隊中轉過來轉過去的。
  • 每個團隊都可能成為一個潛在的 DDoS 攻擊者,除非每個服務都要做好配額和限流。
  • 監控和查錯變得更為復雜。除非有非常強大的監控手段。
  • 服務發現和服務治理也變得非常復雜。

為了克服這些問題,亞馬遜這么多年的實踐讓其可以運維和管理極其復雜的分布式服務架構。我覺得主要有以下幾點。

  1. 分布式服務的架構需要分布式的團隊架構。在亞馬遜,一個服務由一個小團隊(Two Pizza Team 不超過 16 個人,兩張 Pizza 可以喂飽的團隊)負責,從前端負責到數據,從需求分析負責到上線運維。這是良性的分工策略——按職責分工,而不是按技能分工。
  2. 分布式服務查錯不容易。一旦出現比較嚴重的故障,需要整體查錯。出現一個 S2 的故障,就可以看到每個團隊的人都會上線。在工單系統里能看到,在故障發生的一開始,大家都在簽到并自查自己的系統。如果沒問題,也要在線待命(standby),等問題解決。(我在《故障處理最佳實踐:應對故障》一文中詳細地講過這個事)。
  3. 沒有專職的測試人員,也沒有專職的運維人員,開發人員做所有的事情??⑷嗽弊鏊惺慮櫚暮么κ恰宰約旱墓妨福‥at Your Own Dog Food) 最微觀的實踐。自己寫的代碼自己維護自己養,會讓開發人員明白,寫代碼容易維護代碼復雜。這樣,開發人員在接需求、做設計、寫代碼、做工具時都會考慮到軟件的長期維護性。
  4. 運維優先,崇尚簡化和自動化。為了能夠運維如此復雜的系統,亞馬遜內部在運維上下了非常大的功夫。現在人們所說的 DevOps 這個事,亞馬遜在 10 多年前就做到了。亞馬遜最為強大的就是運維,拼命地對系統進行簡化和自動化,讓亞馬遜做到了可以輕松運維擁有上千萬臺虛機的 AWS 云平臺。
  5. 內部服務和外部服務一致。無論是從安全方面,還是接口設計方面,無論是從運維方面,還是故障處理的流程方面,亞馬遜的內部系統都和外部系統一樣對待。這樣做的好處是,內部系統的服務隨時都可以開放出來。而且,從第一天開始,服務提供方就有對外服務的能力??梢韻胂?,以這樣的標準運作的團隊其能力會是什么樣的。

在進化的過程中,亞馬遜遇到的問題很多,甚至還有很多幾乎沒有人會想到的非常生僻的東西,它都一一學習和總結了,而且都解決得很好。

構建分布式系統非常難,充滿了各種各樣的問題,但亞馬遜還是毫不猶豫地走了下去。這是因為亞馬遜想做平臺,不是“像淘寶這樣的中介式流量平臺”,而是那種“可以對外輸出能力的平臺”。

亞馬遜覺得自己沒有像史蒂夫·喬布斯(Steve Jobs)這樣的牛人,不可能做出像 iPhone 這樣的爆款產品,而且用戶天生就是眾口難調,與其做一個大家都不滿意的軟件,還不如把一些基礎能力對外輸出,引入外部的力量來一起完成一個用戶滿意的產品。這其實就是在建立自己的生態圈。雖然在今天看來這個事已經不稀奇了,但是貝索斯早在十五年前就悟到了,實在是個天才。

所以,分布式服務架構是需要從組織,到軟件工程,再到技術上的一個大的改造,需要比較長的時間來磨合和改進,并不斷地總結教訓和成功經驗。

分布式系統中需要注意的問題

我們再來看一下分布式系統在技術上需要注意的問題。

問題一:異構系統的不標準問題

這主要表現在:

  • 軟件和應用不標準。
  • 通訊協議不標準。
  • 數據格式不標準。
  • 開發和運維的過程和方法不標準。

不同的軟件,不同的語言會出現不同的兼容性和不同的開發、測試、運維標準。不同的標準會讓我們用不同的方式來開發和運維,引起架構復雜度的提升。比如:有的軟件修改配置要改它的.conf 文件,而有的則是調用管理 API 接口。

在通訊方面,不同的軟件用不同的協議,就算是相同的網絡協議里也會出現不同的數據格式?;褂?,不同的團隊因為用不同的技術,會有不同的開發和運維方式。這些不同的東西,會讓我們的整個分布式系統架構變得異常復雜。所以,分布式系統架構需要有相應的規范。

比如,我看到,很多服務的 API 出錯不返回 HTTP 的錯誤狀態碼,而是返回個正常的狀態碼 200,然后在 HTTP Body 里的 JSON 字符串中寫著個:error,bla bla error message。這簡直就是一種反人類的做法。我實在不明白為什么會有眾多這樣的設計。這讓監控怎么做???現在,你應該使用 Swagger 的規范了。

再比如,我看到很多公司的軟件配置管理里就是一個 key-value 的東西,這樣的東西靈活到可以很容易地被濫用。不規范的配置命名,不規范的值,甚至在配置中直接嵌入前端展示內容……

一個好的配置管理,應該分成三層:底層和操作系統相關,中間層和中間件相關,最上面和業務應用相關。于是底層和中間層是不能讓用戶靈活修改的,而是只讓用戶選擇。比如:操作系統的相關配置應該形成模板來讓人選擇,而不是讓人亂配置的。只有配置系統形成了規范,我們才 hold 得住眾多的系統。

再比如:數據通訊協議。通常來說,作為一個協議,一定要有協議頭和協議體。協議頭定義了最基本的協議數據,而協議體才是真正的業務數據。對于協議頭,我們需要非常規范地讓每一個使用這個協議的團隊都使用一套標準的方式來定義,這樣我們才容易對請求進行監控、調度和管理。

這樣的規范還有很多,我在這就不一一列舉了。

問題二:系統架構中的服務依賴性問題

對于傳統的單體應用,一臺機器掛了,整個軟件就掛掉了。但是你千萬不要以為在分布式的架構下不會發生這樣的事。分布式架構下,服務是會有依賴的,于是一個服務依賴鏈上,某個服務掛掉了,會導致出現“多米諾骨牌”效應,會倒一片。

所以,在分布式系統中,服務的依賴也會帶來一些問題。

  • 如果非關鍵業務被關鍵業務所依賴,會導致非關鍵業務變成一個關鍵業務。
  • 服務依賴鏈中,出現“木桶短板效應”——整個 SLA 由最差的那個服務所決定。

這是服務治理的內容了。服務治理不但需要我們定義出服務的關鍵程度,還需要我們定義或是描述出關鍵業務或服務調用的主要路徑。沒有這個事情,我們將無法運維或是管理整個系統。

這里需要注意的是,很多分布式架構在應用層上做到了業務隔離,然而,在數據庫結點上并沒有。如果一個非關鍵業務把數據庫拖死,那么會導致全站不可用。所以,數據庫方面也需要做相應的隔離。也就是說,最好一個業務線用一套自己的數據庫。這就是亞馬遜服務器的實踐——系統間不能讀取對方的數據庫,只通過服務接口耦合。這也是微服務的要求。我們不但要拆分服務,還要為每個服務拆分相應的數據庫。

問題三:故障發生的概率更大

在分布式系統中,因為使用的機器和服務會非常多,所以,故障發生的頻率會比傳統的單體應用更大。只不過,單體應用的故障影響面很大,而分布式系統中,雖然故障的影響面可以被隔離,但是因為機器和服務多,出故障的頻率也會多。另一方面,因為管理復雜,而且沒人知道整個架構中有什么,所以非常容易犯錯誤。

你會發現,對分布式系統架構的運維,簡直就是一場噩夢。我們會慢慢地明白下面這些道理。

  • 出現故障不可怕,故障恢復時間過長才可怕。
  • 出現故障不可怕,故障影響面過大才可怕。

運維團隊在分布式系統下會非常忙,忙到每時每刻都要處理大大小小的故障。我看到,很多大公司,都在自己的系統里拼命地添加各種監控指標,有的能夠添加出幾萬個監控指標。我覺得這完全是在“使蠻力”。一方面,信息太多等于沒有信息,另一方面,SLA 要求我們定義出“Key Metrics”,也就是所謂的關鍵指標。然而,他們卻沒有。這其實是一種思維上的懶惰。

但是,上述的都是在“救火階段”而不是“防火階段”。所謂“防火勝于救火”,我們還要考慮如何防火,這需要我們在設計或運維系統時都要為這些故障考慮,即所謂 Design for Failure。在設計時就要考慮如何減輕故障。如果無法避免,也要使用自動化的方式恢復故障,減少故障影響面。

因為當機器和服務數量越來越多時,你會發現,人類的缺陷就成為了瓶頸。這個缺陷就是人類無法對復雜的事情做到事無巨細的管理,只有機器自動化才能幫助人類。 也就是,人管代碼,代碼管機器,人不管機器!

問題四:多層架構的運維復雜度更大

通常來說,我們可以把系統分成四層:基礎層、平臺層、應用層和接入層。

  • 基礎層就是我們的機器、網絡和存儲設備等。
  • 平臺層就是我們的中間件層,Tomcat、MySQL、Redis、Kafka 之類的軟件。
  • 應用層就是我們的業務軟件,比如,各種功能的服務。
  • 接入層就是接入用戶請求的網關、負載均衡或是 CDN、DNS 這樣的東西。

對于這四層,我們需要知道:

  • 任何一層的問題都會導致整體的問題;
  • 沒有統一的視圖和管理,導致運維被割裂開來,造成更大的復雜度。

很多公司都是按技能分工是,把技術團隊分為產品開發、中間件開發、業務運維、系統運維等子團隊。這樣的分工導致各管一攤,很多事情完全連不在一起。整個系統會像 “多米諾骨牌”一樣,一個環節出現問題,就會倒下去一大片。因為沒有一個統一的運維視圖,不知道一個服務調用是如何經過每一個服務和資源,也就導致我們在出現故障時要花大量的時間在溝通和定位問題上。

之前我在某云平臺的一次經歷就是這樣的。從接入層到負載均衡,再到服務層,再到操作系統底層,設置的 KeepAlive 的參數完全不一致,導致用戶發現,軟件運行的行為和文檔中定義的完全不一樣。工程師查錯的過程簡直就是一場惡夢,以為找到了一個,結果還有一個,來來回回花了大量的時間才把所有 KeepAlive 的參數設置成一致的,浪費了太多的時間。

分工不是問題,問題是分工后的協作是否統一和規范。這點,你一定要重視。

小? ?結

好了,我們來總結一下今天分享的主要內容。首先,我以亞馬遜為例,講述了它是如何做分布式服務架構的,遇到了哪些問題,以及是如何解決的。我認為,亞馬遜在分布式服務系統方面的這些實踐和經驗積累,是 AWS 出現的基因。隨后分享了在分布式系統中需要注意的幾個問題,同時給出了應對方案。

我認為,構建分布式服務需要從組織,到軟件工程,再到技術上的一次大的改造,需要比較長的時間來磨合和改進,并不斷地總結教訓和成功經驗。

余下全文(1/3)

本文最初發表在微信公眾號,文章內容屬作者個人觀點,不代表本站立場。

分享這篇文章:

請關注我們:

《左耳朵耗子:從亞馬遜的實踐,談分布式系統的難點》有1個想法

  1. Two Pizza Team 不超過 16 個人,兩張 Pizza 可以喂飽的團隊. 你媽的你的披薩有鍋盔那么多大?還是你們團隊的16個人都是在減肥?兩個披薩怎么喂飽16個人,我自己一個就能吃一張披薩。亂尼瑪的瞎扯。

發表評論

電子郵件地址不會被公開。 必填項已用*標注