javascript
基于 Spring Cloud 的服务治理实践
http://www.infoq.com/cn/articles/spring-cloud-based-service-governance
大家好,我是來自貝殼金控的趙文樂,目前主要從事架構方面的工作。今天我想跟大家分享《基于 Spring Cloud 的服務治理實踐》。我先簡單向大家介紹一下服務治理的概念,然后介紹實際案例中的實踐。
服務治理的范圍及原因
上圖是我簡單制作的「服務治理實踐過程中遇到的問題和解決方法」,不是非常完全,但也可以代表服務治理的大致范圍。
服務治理的范圍
在服務治理方面,我們需要解決四個方面的問題:
為什么要進行服務治理?
- 當服務越來越多時,過去簡單記錄服務的?end point就越來越復雜。所以注冊中心是我們需要做的第一步,在這之后,才是服務發現和客戶端定制;
- 當服務開始越來越復雜,我們就要依賴于管理服務。如果架構師不了解系統里所有服務之間的依賴關系,則需要借助框架自動畫出依賴關系并予以管理;
- 當調用越來越多時,我們需要增加監控、容量規劃以及度量;
- 當依賴變得復雜時,除了了解服務的依賴關系,還要動態的察覺依賴;
- 一般情況下,下層服務如果反調上層服務,會造成循環依賴,需要SOA做到服務之間互相溝通,使管理更加容易;
- 如果想要防止文檔變得混亂,就需要更集中化的文檔管理,讓大家能夠搜到、看到所有的服務的文檔;
- 如果大家都可以公開調用內部服務,那么就會出現安全問題;
- 質量問題也會難以保障,需要有非常好的服務監控;
- 當調用多個服務時,需要做服務聚合。特別是當我們依賴于服務編排時,如果用框架來做會更方便。
服務拆分和治理的原則
服務拆分的原則
當我們在說微服務時,我們是在說:到底微服務的顆粒度要做到多細或多粗。這就需要我們先定義服務的不同分類,可以按照不同的維度來做。如服務業務、服務流程或不同的業務域,這是第一種流程服務,即滿足最高層服務的流程。在流程服務下還會出現組合服務,會調用多個其他服務進行封裝組合。再下面還會有平臺服務 —— 在某業務域下的核心服務。最后是基礎服務,它通常沒有特別的業務含義,是比較通用的服務。
同時,我們也可以根據服務的屬性來分類:
所以,我們可以按照以上原則做系統分解:
- 不同的業務域劃分大的業務系統,每個業務調用數據量最大的需要拆分;
- 風險高、頻率高、經常更新的需要拆分的;
- 經常會被復用的底層服務需要拆分;
- 服務需要專業技能、專業團隊,特別是技術棧不統一時進行拆分。
服務設計原則
服務設計原因包括:
- 服務無狀態,冪等性。在設計微服務時,一般都會從領域模型。基于這些領域來驅動微服務REST API的設計;
- 服務業務隔離,領域驅動( Domain Driven Design );
- 服務契約驅動( Design by Contract )。先定義接口,再去做服務的實現;
- 服務資源隔離(數據庫,線程池等)。如果不隔離服務的數據庫,就很難知道有沒有其他服務在調用我們的數據庫,至少數據庫的用戶是需要隔離,不同用戶要有不同的權限;
- 故障可隔離(熔斷機制)。Spring Cloud里有Hystrix框架就可以很好的解決這個問題。
服務治理原則包括:
- 服務SLA;
- 服務需自治;
- 服務可開關,降級,限流,動態調整負載路由;
- 服務可監控,可統計,提供Metrics和Health Check( Metrics Driven Design );
- 服務文檔和版本管理;
- 服務權限控制;
- 服務調用鏈可監控。
Spring Cloud的服務治理
Spring Cloud 組件
上圖中比較核心的組建包括:
- 服務注冊提供很多選型。默認是Eureka,還支持Consul和Zookeeper服務注冊;
- 服務調用,REST API通常用Feign Client做服務調用,集成客戶端的負載均衡,所以Feign Client在服務治理中非常重要;
- 服務路由和服務過濾,在Spring Cloud提供的route API、gateway之類的工具;
其他還包括:
- 服務監控,在?Spring Cloud環境下用的較多的是Hystrix —— 監控控制臺,集成的Turbine可以做跨集群的監控;
- 配置中心,Spring Cloud默認提供的配置管理是通過地址文件進行管理,也支持諸如Zookeeper之類配置中心;
- 安全控制集成SpringSecurity,它本身不是屬于Spring Cloud的范疇,但會提供SpringSecurity Starter,幫助我們快速的建立權限管理;
- 用?Spring Cloud Sleuth做分布式的鏈路監控,集成Zipkin之類的框架。
Spring Cloud 存在的問題和痛點
如何改善
更換配置中心。攜程的Apollo是一個更好的選擇。它里面的很多功能都是原生Spring Cloud配置中心不支持的。所以建議大家嘗試一下比較成熟的配置中心。
因為?API Gateway在Spring Cloud中沒有操作界面,所以我們就為之定制了專屬界面,讓它能夠管理不同的路由規則。我們還開發了一系列Filter,可以在API Gateway里做簽名檢查和解密。同時,我們還集成了自己的賬戶系統和單點登錄,支持不同的登錄方式。
除此之外,我們集成了用戶中心( Accountservice )。因為當?API Gateway開放給渠道用戶或合作伙伴用戶時,通常沒有交互,所以我們就需要通過參數的自動抓取匹配用戶,據此判斷這個用戶是否已經注冊。如果還未注冊,我們就會自動注冊。同時,當一個潛在用戶使用我們系統、調用API時,我們就可以通過這種方式把硬件指紋記錄下來,后臺會給這些用戶打標簽,我們就可以針對這些用戶做push等營銷手段。
最后,還有一些前置Filter用于抽取數據。當API請求時,會異步通過日志抽取報文做數據清洗,通過ETL寫到數據倉庫里。
API gateway的動態路由
舉個例子,比如我們把年齡小于30歲的男性路由到一個不同的endpoint ,我們在這過程中會在請求頭、請求參數或請求頭中通過Json Parse抽取參數和數據轉換。我們可以從body里第一個customer對象的ID得到uid,之后保存到上下文中,輸出到output,當我們指定endpoint為另外一個URL時把UID這個參數傳過去。
還有一種是報文的轉換,即Payload Transformation。這個技術其實在很久以前就已經存在了,在ESB、SOAP時代,我們通常會利用XML來做報文的轉換。所以現在通常用來做報文轉換的工具是Json、Json Paser、Velocity Template、FreeMarker等。還有一些協議的轉換,我們內部有很多API都是基于dubbo或者是其他的一些RPC協議。所以當收到外部REST API請求時,我們會做一個協議、格式的轉換。
在上圖中,入參是比較復雜的Json,我們通過Input Mapping模板上邏輯輸出變量,嵌入到另外的Json對象中。如果我們在內部有一套比較標準的API,可以通過這種方式適配到外部不同的API。這樣便集成了規則引擎,可以做一些比較基本的服務編排。
一體化的服務監控和跟蹤
在Spring Cloud里提供了很多不同的服務監控工具,利用這些工具可以做服務的業務監控和埋點,來收集各種Metrics。當我們發送消息時,我們會在適當的地方做埋點,收集數據,最后再把這些集成起來,做報表展示和告警。所以整個這套服務監控和跟蹤都是一體化的。
我們在做中間件埋點時,可以有許多的選擇,比如JDK proxy、http client、Servlet filters、Spring MVC handler都可以添加埋點,但我們更多會在Feign Client提供一些攔截器,當服務調用時,會有一些不同的event。
在DB里,我們用的比較多的是Druid datasource filter,它提供了很多擴展,我們可以在這里邊做SQL查詢的埋點,記錄每條SQL的響應時間和調用頻次。同時,Mybatis也可以做埋點,定制一些插件。
服務監控的整體架構
過去我們使用日志做服務監控的數據收集,大家都知道也有不少的服務監控都是基于上報的API。但我們通過日志的方式收集數據對應用的性能比較友好,不會因為我們埋點影響到業務。同時,耦合度也比較低,只是分析度量數據。通過不同的Instruments寫到日志里。最后通過Logstash到Kafka進入ElasticSearch,基于這些查詢可以快速生成簡單的報表。
以上所說的內容,如果都只是停留在框架級別,用戶和程序員根本看不到服務治理的概念。所以我們做了一套服務治理平臺,可以看到所有服務治理內容。同時,我們還把配置中心嵌到了服務治理平臺中,將服務網關管理、Rabbit MQ消息隊列管理、通過消息隊列業務ID查詢消息軌跡以及一些項目管理相關的離線服務治理等功能集成在一起。
Q & A
問:下層服務和上層服務指的是什么?
答:所謂的下層服務,就是底下平臺級的服務。比如你有一個發短信的服務,如果這個服務跟你的賬戶體系耦合在一起,它就是反向調用,如果在短信服務里需要到會員中心獲取手機號,這就是不合理的設計,就是下層服務調上層服務的例子。
問:服務調用是每個服務各自寫一個FeignClient,還是由服務方提供統一的jar包?
答:我們現在做法是:在定義服務接口時,這個服務接口就是FeignClient,然后把服務接口和它領域的對象封裝成統一的jar包,作為服務方提供。之后,客戶端用它來調用就可以了。在調用過程中,框架里的攔截器會做埋點、注入及監控的工作。
問:老的服務如何調用FeignClient?
答:用延伸注解來實現。FeignClient在Spring Cloud用的是比較新的OpenFeign注解,支持一些特殊功能。比如插入自己的http client和做很多攔截器,老的FeignClient不是很友好,而且它跟Spring mvc的注解也不一致,但是作為一個很老的服務,如果要調用FeignClient的話,我們通常會把所有FeignClient用到的class打成一個大的jar包,為這些老的服務實現調用。
問:如果有機會是不是直接選擇自研好一點?
答:作為開發人員或架構師,每個人都想自研,確實也有很多團隊自己做自研框架。但自研的問題是從入門到融會貫通的時間。雖然Spring Cloud現在十分簡陋,但上手就可以用。如果在整個團隊里都用Spring Cloud,可以很快地做一些簡單的服務治理,然后再慢慢的優化這個過程。還有一個原因,Spring Cloud在行業里的接受度比較高,大家的學習曲線比較短,通常自研的框架很多工程師可能不太接受或不太信任。
轉載于:https://www.cnblogs.com/davidwang456/articles/9274139.html
總結
以上是生活随笔為你收集整理的基于 Spring Cloud 的服务治理实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 酷狗音乐的大数据实践
- 下一篇: 微服务的容错模式