來自京東、宅急送對微服務編排、API網關、持續集成的實踐分享(下)

架構師小組交流會:每期選一個時下最熱門的技術話題進行實踐經驗分享。nginx

第三期:微服務。微服務架構以其高度的彈性、靈活性和效率的巨大提高,快速受到各領域架構師和技術決策者的關注。它的基本理念是將一個肥大的系統拆分紅若干小的服務組件,組件之間的通信採用輕量的協議完成。咱們本期小組交流會來探討一下,如今互聯網公司的微服務實踐狀況。redis

嘉賓:京東章耿、宅急送石廷鑫、七牛陳愛珍
本文是對這次交流的整理,分了上下兩篇文章。算法

第二輪:話題交流
主持人:API 網關是怎麼設計的?
京東章耿:
咱們有個 HTTP 的網關,但不是一個對外網服務的一個網關。對外的話業務本身都有一些網關,例如無線有本身的網關,網站有本身的網關,而另一個公共的開放的是一個叫京東開放平臺的網關。而後咱們的網關幹嗎用的?主要作的就是一個跨語言支持用的,協議轉發和限流。這個網關存在的意義,主要是爲了讓有的調用端不用傑夫協議,或者不依賴服務端的狀況下,來調服務端的服務。spring

最主要就是剛纔說那個 HTTP 轉成內部協議的一個轉發的功能,其次咱們在上面作了一個接口級隔離,不要一個接口就把網關搞掛。還有一個就是限流,每分鐘調多少次。還有受權,之前的網關轉發的作法,通常是好比說相似於一個 VIP,而後前面掛個域名。而後那個虛 IP 後面掛的服務列表通常都是要手動維護上。而咱們的網購自動就掛到這個網關上面,就是一個服務發現,還有就是咱們的結果,統計方面,咱們會統一包裝一下,咱們的網關主要是作這個功能,如今一天應該是幾十億的調用量,九十臺,差很少這些。數據庫

服務發現是到數據庫裏面去讀服務列表,從註冊中心讀出來之後會推給咱們的網關。網關跟調用者是相似的。它其實也是一個調用者,只不過它是一個代理的調用者。它的服務列表,也是從咱們的註冊中心訂閱的,不直接連數據庫,能夠認爲本身是調用者。網關第一次去註冊中心去讀,後面的話咱們能夠推變化的部分。好比說你原來 1000 臺,你要是加了一臺,按之前拉的思路你會拉 1001 臺,而後你本身比較一下,多了哪一臺。但咱們如今不是,咱們如今是反向給他推加一臺。這樣的話,大量的減小那個,還有網絡 IO 的推送。安全

京東章耿:咱們想用 nginx+luaw 作一個 HTTP 轉咱們內部 JSF 協議的,但不是 worker 就是一個進程。會產生不少長連接,因此咱們後來就放棄了,咱們如今是基於 nitty 作了一個轉發,就是對外是 HTTP,對內就 JSF 協議。也作了一些受權,限流,還有服務之間的線程隔離,服務發現,還有一個是結果的包裝,包裝成標準的 HTTP 的響應。由於像對外網的那些其實都是有本身的系統,無論你是無線,仍是 PC 他都有本身的系統,那個不須要咱們作。對第三方的話,它也有其中京東一個開發平臺,還有更嚴格的那個驗證,咱們這個主要仍是作協議轉換的 API 網關。restful


主持人:大家怎麼驗證請求的合法性的,大家採用什麼方法?就是就那種效率與安全性的這種平衡大家怎麼作的?網絡

京東章耿:咱們是有個受權,就是有個應用 ID,京東是每一個啓動的都有個應用 ID,帶着那個應用 ID 過來,咱們也能夠支持頭上帶 token。京東開放的那種是對外比較嚴格,咱們這個不須要那麼嚴格,反正就看你對象,就看你的網關給誰用了。

主持人:大家如今有兩種類型,一種是內部之間調用的,另一部分是外部調用內部的調用大家系統。
京東章耿:
那個是開放服務,有些供應商內部的系統,想要調京東的系統,那種就是京東開放服務,是須要 Oauth 認證。架構

京東章耿:HTTP+keepalive 也挺快的,由於它無非就是頭上大一點,HTTP 的頭大了一點。但若是後臺是調 redis 那就比較明顯的感受,那若是後臺是一個有個幾百毫秒的,那你感受不到那麼明顯。若是後臺,你這就是讀不取一下,讀一下 redis,你感受比較明顯。咱們這邊是用 netty 作的 HTTP 跟二進制都是在同一個端口支持的。微服務


主持人:你怎麼劃分,哪些用二進制的,那些用 restful 協議的呢?

京東章耿:那個咱們沒有強制要求,業務它本身想用什麼用什麼。

京東章耿:對咱們來講,它一啓動端線口它就支持這兩種協議。啓動同一個端口,兩種協議都支撐的。

主持人:大家是怎麼區分一種端口種協議的呢?

京東章耿:每一個數據包括頭上前兩位不是模數位嗎?它們都有本身的模數位。而後咱們本身協議有本身的模數位,你 HTTP 就是那幾個打頭的 H,而後咱們的 decode 是自動裝載的,它不是說你能夠一開始裝載一個什麼那是適配器 decode。當你請求來的時候,你再自動裝載量,由於咱們是超連接,無論你是 HTTP,咱們通常都默認開啓 keepalive 也是個超連接。其實,你能夠知道這個長連接對應的是什麼協議。


主持人:它通常保持穩定的一個超連接,確定是一種協議持續下去,不可能說動態的變質。

京東章耿:是,看效率要求,其實 HTTP keepalive 也還能夠,性能也還能夠,若是不是那種調量特別特別大的話,它效率也仍是能夠的。而後 debug 的時候可能可讀性會好一點。二進制最大問題仍是比較麻煩,特別是,咱們如今用 message pack,而後會生成一堆的代理類,模板類,反正問題也比較麻煩。

宅急送石廷鑫:咱們都用 Spring cloud 的那一套,而後自個改了一部分東西。像 Consul 好像也和 Zookeeper 同樣的問題,因此說後邊都改造數據庫了。我如今用的是開源的 eureka,只是後邊從屬變了。目前來講還沒發現問題,由於我沒有跨機房的問題。若是是跨機房的話,基本上都是數據庫同步,兩個數據之間同步的問題。

京東章耿:通常咱們是有一個功能服務降級,其實最主要仍是業務部門本身的代碼實現,那咱們其實有提供一個 mok 功能,就是那在咱們配置這邊直接配上一個,若是這個接口不可用返回的什麼東西有沒有開關,這也是能夠。可是這個用起來比較少,通常他們本身在業務代碼上也是容錯的,就是沒有說從平臺這種角度去搞,通常都是本身考慮。

而後若是是有一個目視跟蹤系統的話,就通常的也能夠跟蹤整個調用鏈,就會看出來這個。好比說這個接口它依賴其餘的接口,而後京東實際上是沒有投資這麼細,由於目前咱們分公司跟蹤尚未上,咱們如今主要是依賴咱們內部的一個應用管理系統,咱們叫 JOne,有點像自動部署。咱們每一個進程啓動的時候都會帶上這個應用 ID,在咱們管理端是能看到這個接口是屬於哪一個應用的,咱們只能看到應用級別的,這個應用調了哪些接口?哪些接口依賴?調的那些接口還被誰調用了?到這個級別。

宅急送石廷鑫:咱們用 Springcloud,熔斷機制的降級處理的話,它有一個統計的接口,基本上按那個規則來作。調用關係的話,一個是咱們作了一個 trace ID,就是 google zipkin,它自己有自帶的工具。還有一部分就是服務的排層,咱們如今就是用 camel 來作的,把這個業務整個來排層次作,大致是這樣。目前來講,大的狀況就是監控時會有一些出常常會出現一些抖動。就比方說 trace ID 那部分,不能用它自帶的 stream 的模式。咱們如今仍是用 elk 來作,而後把 trace ID 打出來,而後作了一套簡單的監控,相似於模仿它整個 trace 的路徑。固然不要用 google 自帶的監控,咱們發現機器多了自帶的監控不太可靠。咱們都是作到日誌裏面,而後用 elk 收集起來。提及來自個作一個監控的調用量,這個就是稍微有點延遲。

京東章耿:咱們這邊最近正在作,而後咱們的思路是這樣的。有個包放在應用裏面,它會輸出日誌,而後咱們有一個日誌收集,原來就有日誌收集的咱們只是擴展了一下。在每臺機子上把它收到一個 kafka 裏面,而後後面是用一個 storm 去把它讀出來,寫到 H base 裏作分析,而後咱們是有個採樣率的一個概念,好比說一千次,才寫一次,或者是一萬次才寫一次,作個採樣率。而後最終咱們如今是分兩部分,剛纔說寫 H base 是一個離線數據,其實咱們還有一些簡單例子,就是直接作一些統計,實時的,大概延遲在一分鐘左右。

主持人:關於服務的 Docker 化有什麼進展?

京東章耿:咱們主要仍是應用級別的 Docker。如今只是說,可能這種發佈模式會改一下。如今是基於一個 Docker VM,好比說你起來之後,其實整個鏡像文件都在那裏。而後你彈的時候其實仍是比較慢的。好比我要擴的話,得先建立一個 Docker 的 VM,再把那些東西複製進去,纔能有個裝機的過程。就是比較慢一點,可能得分鐘級別才能把它給提起來。可是將來咱們但願把它改用鏡像的那種形式,就你上線完成之後,生成一個鏡像。每次上線,你只須要布一臺機器,後面全是複製的一個過程。將來會改爲這樣,估計今年開發,明年推。如今至關於要布 20 個節點,那至關因而給你 20 個 Docker VM,你上線發佈 20 次,將來是但願給你一個,而後你發佈一次之後,系統自動給你複製 19 個。並且反正後面服務發現什麼這些都是原生的,都是無所謂的。

京東章耿:京東的 Docker 主要解決資源調度的問題。就至關於如今部物理機,你可能本身要須要部署機器 。但 Docker 能夠把資源分配均勻一點,用算法給算出來,在分配時不會分到同一個機架上,不會分到同一個主機上,還有不會分到很繁忙的機器上。這些都會幫你考慮一下。

京東章耿:京東這邊是本身有一套部署系統,雖然他沒有像你說就鏡像這樣發佈,雖然沒這麼快,但對於咱們開發人員上線來講,實際上是同樣的,他只須要配一下,而後一點,他 24 臺自動就上去了,就是有一套工具,也很快。只不過,他須要提早建立好,好比說你剛纔說 20 個,你要提早建立 20 個 VM。就比鏡像的話確定是要慢在這一步,你鏡像的話,你直接拉下來一塊兒,而後能夠調度到哪臺機子上到個 Docker API 一調,他直接就提起來了,那也是咱們將來的改變方向。

七牛陳愛珍:咱們的數據處理系統系統上運行的都是 CPU 密集型的計算,獲取一個原文件,進行數據處理算法的執行,好比對一個視頻進行轉碼,而在轉碼的過程當中須要大量的 CPU 資源來進行處理,處理完後就能夠得到預設的文件樣式。不一樣的數據處理對資源的需求是不同的,好比獲取一個文件的 hash 值,這個處理邏輯很是簡單,也沒有大量的運算,配置的資源就相對小一些,而視頻轉碼則很是的複雜,配置的資源就會相對多一些。

如今在咱們的平臺上運行了數千種數據處理應用,每種處理的的請求量不同,好比有些圖片處理每秒能夠達到數十萬的請求量,而有一些則多是每秒幾萬的請求量,幾千種數據處理應用的高峯期也不同,有些可能在早上,有些可能在晚上,而且每種處理都會存在突發流量的狀況,好比一些電商型的客戶,在作大促銷時,就會致使圖片處理的請求量突增,而一些音視頻的客戶在會在一些活動時會忽然增加對音視頻的處理。

這個系統的核心問題是如何把硬件資源對每一種應用不一樣高峯期的請求量和突發流量作合理的資源分配,不合理的資源分配就可能會形成資源的浪費,或致使負載太重的機器會宕機,不能及時響應用戶的需求。原有的系統架構的資源是靜態規劃的,也就是把指定的資源給指定的應用使用,而這種資源的分配每每是按照每一個應用的業務高峯進行規劃的,爲了應對突發的流量並會預設必定的冗餘,那麼這樣就會須要準備不少的資源。後來咱們使用容器,由於容器能夠封裝環境,動態遷移,底層使用 Mesos 作資源的調度,這就能夠對整個環境按需動態分配,很好的解決了資源利用率的問題。


主持人:關於服務測試、持續集成,你們分享一下實踐經驗吧。

京東章耿:持續集成咱們這邊其實在編譯環節就作了,上線咱們這邊是有一個灰度上線功能。咱們有一個預發佈環節,它能夠直接把它標記爲預發,而後有個測試平臺能夠對它進行一個服務的測試。那若是是正式環境的話,那就他就得本身想辦法,由於咱們如今這個環節是不能隨便測試的,由於我沒法判斷你這個是讀仍是寫,我不能讓你隨便測。

主持人:由於大家是把一個業務系統拆成了不少這種服務化的服務去跑,那確定是要涉及到這種單元測試、集成測試和業務流的這種測試,那這種測試的話大家都是怎麼作的呢?

京東章耿:這邊都是提早測的,就是你測都沒測,那你根本就提不到上線這一步。你上線的時候必須有一個測試審批經過,其實他其實就是已經在線下就測過了。

七牛陳愛珍:咱們是基於 Jenkins 作的持續集成,把代碼上傳到 Github 後,會作自動的代碼靜態檢查和單元測試,再作自動的集成測試。這樣的好處是開發只須要開發代碼,不須要構建環境,都是自動完成的,並且反饋的速度也會很是快速。

宅急送石廷鑫:測試環境是由開發人員去部署,線上正式環節,是從這個測試環境把報測試經過去的,直接拷貝過去。我以爲 Docker 是解決整個配置的問題,由於生產環境測試環境和開發環境不同。配置環境這個東西很難很麻煩作的,儘量就是 UAT 的環境和測試環境,就是用戶測試的環境和線上的環境儘可能是同樣。如今不是有配置管理嗎?這三個環境能來回切換。比方說 spring boot 這種,實際上就是一個 Jar 包命令。Jar 包命令惟一不一樣的就是它的配置問題,你只要一上線,那邊一監控就能夠看到。由於你啓動時候他有註冊,註冊基本上他要調哪些東西就能看到他註冊的配置。

京東章耿:京東測試環境,預發,線上都是從源碼庫裏編譯爲準。主幹編譯爲準,因此說代碼應該是同樣的。線上配置咱們是管理在配置中心,可是目前咱們測試環境就沒有這個東西。預發,線上有配置中心,這個配置中心也集成到咱們那個發佈平臺 JOne 上。

相關文章
相關標籤/搜索