Spring Cloud 微服務的那點事
什麼是微服務
微服務的概念源於2014年3月Martin Fowler所寫的一篇文章“Microservices”。
微服務架構是一種架構模式,它提倡將單一應用程式劃分成一組小的服務,服務之間互相協調、互相配合,為使用者提供最終價值。每個服務執行在其獨立的程序中,服務與服務間採用輕量級的通訊機制互相溝通(通常是基於HTTP的RESTful API)。每個服務都圍繞著具體業務進行構建,並且能夠被獨立地部署到生產環境、類生產環境等。另外,應儘量避免統一的、集中式的服務管理機制,對具體的一個服務而言,應根據業務上下文,選擇合適的語言、工具對其進行構建。
微服務是一種架構風格,一個大型複雜軟體應用由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是鬆耦合的。每個微服務僅關注於完成一件任務並很好地完成該任務。在所有情況下,每個任務代表著一個小的業務能力。
微服務架構優勢
複雜度可控:在將應用分解的同時,規避了原本複雜度無止境的積累。每一個微服務專注於單一功能,並通過定義良好的介面清晰表述服務邊界。由於體積小、複雜度低,每個微服務可由一個小規模開發團隊完全掌控,易於保持高可維護性和開發效率。
獨立部署:由於微服務具備獨立的執行程序,所以每個微服務也可以獨立部署。當某個微服務發生變更時無需編譯、部署整個應用。由微服務組成的應用相當於具備一系列可並行的釋出流程,使得釋出更加高效,同時降低對生產環境所造成的風險,最終縮短應用交付週期。
技術選型靈活:微服務架構下,技術選型是去中心化的。每個團隊可以根據自身服務的需求和行業發展的現狀,自由選擇最適合的技術棧。由於每個微服務相對簡單,故需要對技術棧進行升級時所面臨的風險就較低,甚至完全重構一個微服務也是可行的。
容錯:當某一組建發生故障時,在單一程序的傳統架構下,故障很有可能在程序內擴散,形成應用全域性性的不可用。在微服務架構下,故障會被隔離在單個服務中。若設計良好,其他服務可通過重試、平穩退化等機制實現應用層面的容錯。
擴充套件:單塊架構應用也可以實現橫向擴充套件,就是將整個應用完整的複製到不同的節點。當應用的不同元件在擴充套件需求上存在差異時,微服務架構便體現出其靈活性,因為每個服務可以根據實際需求獨立進行擴充套件。
什麼是Spring Boot
Spring Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。用我的話來理解,就是Spring Boot其實不是什麼新的框架,它預設配置了很多框架的使用方式,就像maven整合了所有的jar包,Spring Boot整合了所有的框架(不知道這樣比喻是否合適)。
Spring Boot簡化了基於Spring的應用開發,通過少量的程式碼就能建立一個獨立的、產品級別的Spring應用。 Spring Boot為Spring平臺及第三方庫提供開箱即用的設定,這樣你就可以有條不紊地開始。Spring Boot的核心思想就是約定大於配置,多數Spring Boot應用只需要很少的Spring配置。採用Spring Boot可以大大的簡化你的開發模式,所有你想整合的常用框架,它都有對應的元件支援。
Spring Cloud都做了哪些事
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的開發便利性巧妙地簡化了分散式系統基礎設施的開發,如服務發現註冊、配置中心、訊息匯流排、負載均衡、斷路器、資料監控等,都可以用Spring Boot的開發風格做到一鍵啟動和部署。Spring並沒有重複製造輪子,它只是將目前各家公司開發的比較成熟、經得起實際考驗的服務框架組合起來,通過Spring Boot風格進行再封裝遮蔽掉了複雜的配置和實現原理,最終給開發者留出了一套簡單易懂、易部署和易維護的分散式系統開發工具包
以下為Spring Cloud的核心功能:
-
分散式/版本化配置
-
服務註冊和發現
-
路由
-
服務和服務之間的呼叫
-
負載均衡
-
斷路器
-
分散式訊息傳遞
我們再來看一張圖:
通過這張圖,我們來了解一下各元件配置使用執行流程:
-
1、請求統一通過API閘道器(Zuul)來訪問內部服務.
-
2、閘道器接收到請求後,從註冊中心(Eureka)獲取可用服務
-
3、由Ribbon進行均衡負載後,分發到後端具體例項
-
4、微服務之間通過Feign進行通訊處理業務
-
5、Hystrix負責處理服務超時熔斷
-
6、Turbine監控服務間的呼叫和熔斷相關指標
Spring Cloud體系介紹
上圖只是Spring Cloud體系的一部分,Spring Cloud共集成了19個子專案,裡面都包含一個或者多個第三方的元件或者框架!
Spring Cloud 工具框架
1、Spring Cloud Config 配置中心,利用git集中管理程式的配置。
2、Spring Cloud Netflix 整合眾多Netflix的開源軟體
3、Spring Cloud Bus 訊息匯流排,利用分散式訊息將服務和服務例項連線在一起,用於在一個叢集中傳播狀態的變化
4、Spring Cloud for Cloud Foundry 利用Pivotal Cloudfoundry整合你的應用程式
5、Spring Cloud Cloud Foundry Service Broker 為建立管理雲託管服務的服務代理提供了一個起點。
6、Spring Cloud Cluster 基於Zookeeper, Redis, Hazelcast, Consul實現的領導選舉和平民狀態模式的抽象和實現。
7、Spring Cloud Consul 基於Hashicorp Consul實現的服務發現和配置管理。
8、Spring Cloud Security 在Zuul代理中為OAuth2 rest客戶端和認證頭轉發提供負載均衡
9、Spring Cloud Sleuth SpringCloud應用的分散式追蹤系統,和Zipkin,HTrace,ELK相容。
10、Spring Cloud Data Flow 一個雲本地程式和操作模型,組成資料微服務在一個結構化的平臺上。
11、Spring Cloud Stream 基於Redis,Rabbit,Kafka實現的訊息微服務,簡單宣告模型用以在Spring Cloud應用中收發訊息。
12、Spring Cloud Stream App Starters 基於Spring Boot為外部系統提供spring的整合
13、Spring Cloud Task 短生命週期的微服務,為SpringBooot應用簡單宣告新增功能和非功能特性。
14、Spring Cloud Task App Starters
15、Spring Cloud Zookeeper 服務發現和配置管理基於Apache Zookeeper。
16、Spring Cloud for Amazon Web Services 快速和亞馬遜網路服務整合。
17、Spring Cloud Connectors 便於PaaS應用在各種平臺上連線到後端像資料庫和訊息經紀服務。
18、Spring Cloud Starters (專案已經終止並且在Angel.SR2後的版本和其他專案合併)
19、Spring Cloud CLI 外掛用Groovy快速的建立Spring Cloud元件應用。
當然這個數量還在一直增加...
三者之間的關係
微服務是一種架構的理念,提出了微服務的設計原則,從理論為具體的技術落地提供了指導思想。Spring Boot是一套快速配置腳手架,可以基於Spring Boot快速開發單個微服務;Spring Cloud是一個基於Spring Boot實現的服務治理工具包;Spring Boot專注於快速、方便整合的單個微服務個體,Spring Cloud關注全域性的服務治理框架。
Spring Boot/Cloud是微服務實踐的最佳落地方案。
實戰經歷
遇到問題,尋找方案
2015年初的時候,因為公司業務的大量發展,我們開始對原有的業務進行拆分,新上的業務線也全部使用獨立的專案來開發,專案和專案之間通過http介面進行訪問。15年的業務發展非常迅速,專案數量也就相應急劇擴大,到了15底的時候專案達60多個,當專案數達到30幾個的時候,其實我們就遇到了問題,經常某個專案因為擴充套件增加了新的IP地址,我們就需要被動的更新好幾個相關的專案。服務越來越多,服務之間的呼叫關係也越來越複雜,有時候想畫一張圖來表示專案和專案之間的依賴關係,線條密密麻麻無法看清。網上有一張圖可以表達我們的心情。
這個時候我們就想找一種方案,可以將我們這麼多分散式的服務給管理起來,到網上進行了技術調研。我們發現有兩款開源軟體比較適合我們,一個是Dubbo,一個是Spring Cloud。
其實剛開始我們是走了一些彎路的。這兩款框架我們當時都不熟悉,當時國內使用Spring Cloud進行開發的企業非常的少,我在網上也幾乎沒找到太多應用的案例。但是Dubbo當時在國內的使用還是挺普遍的,相關的資料各方面都比較完善。因此在公司擴充套件新業務線眾籌平臺的時候,技術選型就先定了Dubbo,因為也是全新的業務沒有什麼負擔,這個專案我們大概開發了六個月投產,上線之初也遇到了一些問題,但最終還比較順利。
在新業務線選型使用Dubbo的同時,我們也沒有完全放棄Spring Cloud,我們抽出了一兩名開發人員學習Spring Boot我也參與其中,為了驗證Spring Boot是否可以到達實戰的標準,我們在業餘的時間使用Spring Boot開發了一款開源軟體雲收藏,經過這個專案的實戰驗證我們對Spring Boot就有了信心。最重要的是大家體會到使用Spring Boot的各種便利之後,就再也不想使用傳統的方式來進行開發了。
但是還有一個問題,在選擇了Spring Boot進行新業務開發的同時,並沒有解決我們上面的那個問題,服務於服務直接呼叫仍然比較複雜和傳統,這時候我們就開始研究Spring Cloud。因為大家在前期對Spring Boot有了足夠的瞭解,因此學習Sprig Cloud就顯得順風順水了。所以在使用Dubbo半年之後,我們又全面開始擁抱Spring Cloud。
為什麼選擇使用Spring Cloud而放棄了Dubbo
可能大家會問,為什麼選擇了使用Dubbo之後,而又選擇全面使用Spring Cloud呢?其中有幾個原因:
1)從兩個公司的背景來談:Dubbo,是阿里巴巴服務化治理的核心框架,並被廣泛應用於中國各網際網路公司;Spring Cloud是大名鼎鼎的Spring家族的產品。阿里巴巴是一個商業公司,雖然也開源了很多的頂級的專案,但從整體戰略上來講,仍然是服務於自身的業務為主。Spring專注於企業級開源框架的研發,不論是在中國還是在世界上使用都非常廣泛,開發出通用、開源、穩健的開源框架就是他們的主業。
2)從社群活躍度這個角度來對比,Dubbo雖然也是一個非常優秀的服務治理框架,並且在服務治理、灰度釋出、流量分發這方面做的比Spring Cloud還好,除過當當網在基礎上增加了rest支援外,已有兩年多的時間幾乎都沒有任何更新了。在使用過程中出現問題,提交到github的Issue也少有回覆。
相反Spring Cloud自從發展到現在,仍然在不斷的高速發展,從github上提交程式碼的頻度和釋出版本的時間間隔就可以看出,現在Spring Cloud即將釋出2.0版本,到了後期會更加完善和穩定。
3) 從整個大的平臺架構來講,dubbo框架只是專注於服務之間的治理,如果我們需要使用配置中心、分散式跟蹤這些內容都需要自己去整合,這樣無形中使用dubbo的難度就會增加。Spring Cloud幾乎考慮了服務治理的方方面面,更有Spring Boot這個大將的支援,開發起來非常的便利和簡單。
4)從技術發展的角度來講,Dubbo剛出來的那會技術理念還是非常先進,解決了各大網際網路公司服務治理的問題,中國的各中小公司也從中受益不少。經過了這麼多年的發展,網際網路行業也是湧現了更多先進的技術和理念,Dubbo一直停滯不前,自然有些掉隊,有時候我個人也會感到有點可惜,如果Dubbo一直沿著當初的那個路線發展,並且延伸到周邊,今天可能又是另一番景象了。
Spring 推出Spring Boot/Cloud也是因為自身的很多原因。Spring最初推崇的輕量級框架,隨著不斷的發展也越來越龐大,隨著整合專案越來越多,配置檔案也越來越混亂,慢慢的背離最初的理念。隨著這麼多年的發展,微服務、分散式鏈路跟蹤等更多新的技術理念的出現,Spring急需一款框架來改善以前的開發模式,因此才會出現Spring Boot/Cloud專案,我們現在訪問Spring官網,會發現Spring Boot和Spring Cloud已經放到首頁最重點突出的三個專案中的前兩個,可見Spring對這兩個框架的重視程度。
總結一下,dubbo曾經確實很牛逼,但是Spring Cloud是站在近些年技術發展之上進行開發,因此更具技術代表性。
如何進行微服務架構演進
當我們將所有的新業務都使用Spring Cloud這套架構之後,就會出現這樣一個現象,公司的系統被分成了兩部分,一部分是傳統架構的專案,一部分是微服務架構的專案,如何讓這兩套配合起來使用就成為了關鍵,這時候Spring Cloud裡面的一個關鍵元件解決了我們的問題,就是Zuul。在Spring Cloud架構體系內的所有微服務都通過Zuul來對外提供統一的訪問入口,所有需要和微服務架構內部服務進行通訊的請求都走統一閘道器。如下圖:
從上圖可以看出我們對服務進行了分類,有四種:基礎服務、業務服務、組合服務、前置服務。不同服務遷移的優先順序不同
-
基礎服務,是一些基礎元件,與具體的業務無關。比如:簡訊服務、郵件服務。這裡的服務最容易摘出來做微服務,也是我們第一優先順序分離出來的服務。
-
業務服務,是一些垂直的業務系統,只處理單一的業務型別,比如:風控系統、積分系統、合同系統。這類服務職責比較單一,根據業務情況來選擇是否遷移,比如:如果突然有需求對積分系統進行大優化,我們就趁機將積分系統進行改造,是我們的第二優先順序分離出來的服務。
-
前置服務,前置服務一般為服務的接入或者輸出服務,比如網站的前端服務、app的服務介面這類,這是我們第三優先順序分離出來的服務。
-
組合服務,組合服務就是涉及到了具體的業務,比如買標過程,需要呼叫很多垂直的業務服務,這類的服務我們一般放到最後再進行微服務化架構來改造,因為這類服務最為複雜,除非涉及到大的業務邏輯變更,我們是不會輕易進行遷移。
在這四類服務之外,新上線的業務全部使用Sprng Boot/Cloud這套技術棧。就這樣,我們從開源專案雲收藏開始,上線幾個Spring Boot專案,到現在公司絕大部分的專案都是在Spring Cloud這個架構體系中。
經驗和教訓
架構演化的步驟
-
在確定使用Spring Boot/Cloud這套技術棧進行微服務改造之前,先梳理平臺的服務,對不同的服務進行分類,以確認演化的節奏。
-
先讓團隊熟悉Spring Boot技術,並且優先在基礎服務上進行技術改造,推動改動後的專案投產上線
-
當團隊熟悉Spring Boot之後,再推進使用Spring Cloud對原有的專案進行改造。
-
在進行微服務改造過程中,優先應用於新業務系統,前期可以只是少量的專案進行了微服務化改造,隨著大家對技術的熟悉度增加,可以加快加大微服務改造的範圍
-
傳統專案和微服務專案共存是一個很常見的情況,除非公司業務有大的變化,不建議直接遷移核心專案。
服務拆分原則
服務拆分有以下幾個原則和大家分享
橫向拆分。按照不同的業務域進行拆分,例如訂單、營銷、風控、積分資源等。形成獨立的業務領域微服務叢集。
縱向拆分。把一個業務功能裡的不同模組或者元件進行拆分。例如把公共元件拆分成獨立的原子服務,下沉到底層,形成相對獨立的原子服務層。這樣一縱一橫,就可以實現業務的服務化拆分。
要做好微服務的分層:梳理和抽取核心應用、公共應用,作為獨立的服務下沉到核心和公共能力層,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求
服務拆分是越小越好嗎?微服務的大與小是相對的。比如在初期,我們把交易拆分為一個微服務,但是隨著業務量的增大,可能一個交易系統已經慢慢變得很大,並且併發流量也不小,為了支撐更多的交易量,我會把交易系統,拆分為訂單服務、投標服務、轉讓服務等。因此微服務的拆分力度需與具體業務相結合,總的原則是服務內部高內聚,服務之間低耦合。
微服務vs傳統開發
使用微服務有一段時間了,這種開發模式和傳統的開發模式對比,有很大的不同。
-
分工不同,以前我們可能是一個一個模組,現在可能是一人一個系統。
-
架構不同,服務的拆分是一個技術含量很高的問題,拆分是否合理對以後發展影響巨大。
-
部署方式不同,如果還像以前一樣部署估計累死了,自動化運維不可不上。
-
容災不同,好的微服務可以隔離故障避免服務整體down掉,壞的微服務設計仍然可以因為一個子服務出現問題導致連鎖反應。
給資料庫帶來的挑戰
每個微服務都有自己獨立的資料庫,那麼後臺管理的聯合查詢怎麼處理?這應該是大家會普遍遇到的一個問題,有三種處理方案。
1)嚴格按照微服務的劃分來做,微服務相互獨立,各微服務資料庫也獨立,後臺需要展示資料時,呼叫各微服務的介面來獲取對應的資料,再進行資料處理後展示出來,這是標準的用法,也是最麻煩的用法。
2) 將業務高度相關的表放到一個庫中,將業務關係不是很緊密的表嚴格按照微服務模式來拆分,這樣既可以使用微服務,也避免了資料庫分散導致後臺系統統計功能難以實現,是一個折中的方案。
3)資料庫嚴格按照微服務的要求來切分,以滿足業務高併發,實時或者準實時將各微服務資料庫資料同步到NoSQL資料庫中,在同步的過程中進行資料清洗,用來滿足後臺業務系統的使用,推薦使用MongoDB、HBase等。
三種方案在不同的公司我都使用過,第一種方案適合業務較為簡單的小公司;第二種方案,適合在原有系統之上,慢慢演化為微服務架構的公司;第三種適合大型高併發的網際網路公司。
微服務的經驗和建議
1、建議儘量不要使用Jsp,頁面開發推薦使用Thymeleaf。Web專案建議獨立部署Tomcat,不要使用內嵌的Tomcat,內嵌Tomcat部署Jsp專案會偶現龜速訪問的情況。
2、服務編排是個好東西,主要的作用是減少專案中的相互依賴。比如現在有專案a呼叫專案b,專案b呼叫專案c...一直到h,是一個呼叫鏈,那麼專案上線的時候需要先更新最底層的h再更新g...更新c更新b最後是更新專案a。這只是這一個呼叫鏈,在複雜的業務中有非常多的呼叫,如果要記住每一個呼叫鏈對開發運維人員來說就是災難。
有這樣一個好辦法可以儘量的減少專案的相互依賴,就是服務編排,一個核心的業務處理專案,負責和各個微服務打交道。比如之前是a呼叫b,b掉用c,c呼叫d,現在統一在一個核心專案W中來處理,W服務使用a的時候去呼叫b,使用b的時候W去呼叫c,舉個例子:在第三方支付業務中,有一個核心支付專案是服務編排,負責處理支付的業務邏輯,W專案使用商戶資訊的時候就去呼叫“商戶系統”,需要校驗裝置的時候就去呼叫“終端系統”,需要風控的時候就呼叫“風控系統”,各個專案需要的依賴引數都由W來做主控。以後專案部署的時候,只需要最後啟動服務編排專案即可。
3、不要為了追求技術而追求技術,確定進行微服務架構改造之前,需要考慮以下幾方面的因素:
1)團隊的技術人員是否已經具備相關技術基礎。
2)公司業務是否適合進行微服務化改造,並不是所有的平臺都適合進行微服務化改造,比如:傳統行業有很多複雜垂直的業務系統。
3)Spring Cloud生態的技術有很多,並不是每一種技術方案都需要用上,適合自己的才是最好的。