線上支付公司Stripe的服務發現架構設計過程分享

banq發表於2016-11-01
本文介紹Consul如何在Stripe公司扮演服務發現功能的。主要談論三個方面:
1.什麼是服務發現和Consul是什麼。
2.Stripe是如何管理關鍵軟體的部署風險。
3.遭遇的挑戰和應對措施。

Stripe是一家類似支付寶、Paypal的網上支付平臺,Stripe不僅需要處理交易,還需要考慮退款,小費,額外收費,貨幣匯兌等一系列問題。

什麼是服務發現?
負載平衡器將請求分發到任何一個不同的API伺服器,在Stripe在成千上萬的伺服器上執行各種服務。哪一個是API伺服器?API執行在哪個埠?關於使用AWS一個令人驚奇的地方是:我們Stripe伺服器例項可以在任何時候當機。因此對下面情況有所準備:
1.任何時候API伺服器會丟失
2.如果我們需要增加容量,只需要增加額外伺服器.

跟蹤哪一個盒子(伺服器)是否可用,這就是服務發現。我們使用Consul實現服務發現。

其實我們的伺服器任何時候都會當機,這還是有好處的,這是對我們基礎設施進行定期檢驗,它們會自動化處理這些問題,當業務真正發生問題,它也很容易處理故障。

Consul介紹
它是個服務發現工具,服務會註冊其中以便需要呼叫時能夠發現服務,他是將執行的服務儲存在資料庫,他有一個客戶端軟體,專門將資訊放入資料庫,其他客戶端軟體則是從資料庫中讀取。

Consul重要的元件是資料庫,資料庫包含資訊諸如:api-service執行在IP為10.99.99.99的埠12345,目前可用。

獨立的盒子(伺服器)將資訊傳送給Consul說: 我執行在api-service的埠12345,我是處於執行狀態。

如果你要和api服務互動,你首先向Consul請求1:哪個api-service執行正常?它會給你一串IP地址列表和埠。

Consul是一個分散式系統,使用共識演算法Raft進行資料庫同步。

Consul在Stripe初期
起初我們只是在伺服器啟動正常後將資料寫入Consul,並沒有使用服務發現,編寫了一些 Puppet配置設定,不是很難。

這種方式,有助於我們發現數千臺帶有Consul客戶端的伺服器執行中潛在的問題,他沒有使用它進行服務發現。

這個過程中發現什麼問題?
我們發現了Consul存在記憶體洩漏,現在這個問題已經fix。很慶幸我們沒有開始使用它用於服務發現。

一旦我們對Consul執行在我們的基礎設施變得更加有信心,開始增加新客戶端,用這兩種方式降低風險:
1.在少數一些地方使用Consul
2.保持一個後備系統,防止功能中斷。

在這個過程中,遭遇了Consul很多坑,當然並不是抱怨,而是強調在使用新技術的時候,重要的是要慢慢的謹慎的推進。

解決了這麼多問題以後,開始實現服務發現,但是Consul伺服器會響應慢或者沒有響應。

大部分是raft故障轉移或不穩定時發生這些情況,Consul有強一致性儲存,所以它的可用性弱一些。Consul起初這種當機情況可以使用DNS硬編碼修改克服,但是隨著應用廣泛,就不怎麼可行了。

詢問Consul哪個服務是可用的這個過程是不可靠的,如果不使用Consul的API而需要從其得到哪個服務是否正常,可以嗎?

Consul會將名稱如monkey-srv翻譯成一個或多個IP地址,它是從哪裡將名稱翻譯成IP地址呢?DNS伺服器,這樣我們使用DNS伺服器替代Consul, Consul Template 是一個從Consul資料庫中產生靜態配置檔案的Go程式。

我們開始使用Consul Template為Consul服務產生DNS記錄,如果monkey-srv執行在IP 10.99.99.99,產生DNS記錄:
monkey-srv.service.consul IN A 10.99.99.99

模版配置有點複雜:

{{range service $service.Name}}
{{$service.Name}}.service.consul. IN A {{.Address}}
{{end}}
<p class="indent">


但是DNS記錄只能提供一個ip地址,你還需要知道服務執行的伺服器的埠?DNS SRV 記錄則提供伺服器埠,使用Consul Template也可產生SRV記錄。

如果我們的Consul伺服器當機,我們內部的DNS伺服器仍然有其記錄!記錄可能有點老了,但那可用。關鍵是我們的dns伺服器不是一個花俏的分散式系統,意味著它是一個非常簡單的軟體,根本不可能自身分裂變得不穩定。這意味著,我可以查詢monkey-srv.service.consul獲得一個IP地址,並用它來與我的服務交談!

由於DNS是一個共享的最終一致性的系統,我們可以複製和快取它,我們有5個DNS伺服器,每個伺服器都有一個本地DNS快取和知道如何跟任何5個伺服器交談。因此,它的基本上比Consul更具彈性。

DNS記錄更新是每60秒讀取一次Consul,但是如果API伺服器當機了,我們還是要將請求發到這個IP直到DNS伺服器記錄更新?使用HAProxy。

HAproxy是一個負載平衡器,對每個服務是傳送請求檢查健康,它可以確保你的後端正常執行!我們所有的API請求實際上經過HAProxy。這裡的它是如何工作:

1. 每60秒,Consul模版會寫一個HAProxy配置檔案。
2.這意味著HAProxy基本與後端情況精確一致。
3.如果一臺機器當機,HAProxy會很快意識到出錯1(因為它每2秒進行一次健康檢查)

我們是每隔60秒重啟一次HAProxy,當我們重啟HAProxy時是丟掉它的連線嗎?不,使用的是HAProxy的優雅重啟特性,雖然可能丟失一些,但是大部分能夠保留。

幾乎每個伺服器都有/healthcheck這個端點用於檢查健康,如果正常返回200,有一個標準很重要,因為它意味著我們可以很容易地配置HAProxy檢查服務健康。

當Consul當機,HAProxy只會有一個陳舊的配置檔案,這將保持繼續工作。

開始我們的系統是一個高一致性的資料庫,最終我們引人了DNS伺服器,資料可能有幾分鐘的滯後,我們放棄高一致性要求,獲得了更高的可用性,Consul當機基本對我們服務發現沒有影響、

從中獲得一個重要的教訓是,高一致性從來不是免費!你必須願意支付可用性的成本,因此,如果你要使用一個強一致的系統,重要的是要確保這是你真正需要的東西。

總結一下Stripe流程:
當你訪問 https://stripe.com/, 請求經過以下步驟:
1.首先請求來到一個公用的負載平衡器,其執行HAProxy

2.Consul Template已經倒入一堆伺服器列表在/etc/haproxy.conf配置檔案

3.HAProxy 每60秒重新整理配置檔案

4.HAProxy 傳送你的請求到stripe.com一個伺服器,確保其執行正常。

當我們開啟或關閉伺服器,Consul負責從HAProxy自動輪換中刪除它們。沒有手工工作要做。

Stripe並不需要處理如同Twitter 或 Facebook一樣多流量請求, 但我們很關心每筆交易的極端可靠性,部署一個穩定的,優秀的解決方案才是取勝關鍵,不一定是新技術。

Service discovery at Stripe

相關文章