愛油科技基於SpringCloud的微服務實踐(轉)

摘要

本次分享主要介紹了愛油科技基於Docker和Spring Cloud將總體業務微服務化的一些實踐經驗,主要包括:node

  • 微服務架構的分層和框架選型
  • 服務發現和配置管理
  • 服務集成和服務質量保證
  • 基於領域驅動設計
  • 實施DevOps

 

從單體應用到微服務

單體應用

對於單體應用來講,優勢不少,例如:git

  • 小而美,結構簡單易於開發實現
  • 部署門檻低,單個Jar包或者網站打包便可部署
  • 可快速實現多實例部署

然而隨着業務複雜性的上升,業務規模的擴大,缺點也顯現出來,例如:github

  • 隨着業務發展更多的需求被塞進系統,體系結構逐漸被侵蝕反應堆林立
  • 被技術綁架,難覺得特定業務選擇平臺或框架,儘管可能有更適宜的技術作這件事
  • 協做困難,不一樣業務的團隊在一個系統上進行開發相互衝突
  • 難以擴展,爲了熱點業務而不得不一樣時擴容所有業務,或者難以繼續擴容

所以微服務技術做爲一項對分佈式服務治理的架構模式,逐漸被你們認識了。算法

架構拆分

實施微服務,首先對咱們的架構進行了拆分:按行分層,按列分業務spring

在咱們的微服務體系中,全部的服務被劃分爲了三個層次:docker

  1. 基礎設施層:爲全部業務提供基礎設施,包括服務註冊、數據庫和NoSQL、對象存儲、消息隊列等基礎設施服務,這一層一般是由成熟組件、第三方服務組成。
  2. 業務服務層:業務微服務,根據業務領域每一個子域單獨一個微服務,分而治之。
  3. 接入層:直接對外提供服務,例如網站、API接口等。接入層不包含複雜的業務邏輯,只作呈現和轉換。

實踐中咱們主要關注業務服務層和接入層,對於沒有足夠運維力量的咱們,基礎設施使用雲服務是省事省力的選擇。數據庫

業務服務層咱們給他起名叫做Epic,接入層咱們起名Rune,創建之初便訂立了以下原則:json

  1. 業務邏輯層內全部服務徹底對等,可相互調用
  2. 業務邏輯層全部服務必須是無狀態的
  3. 接入層全部服務可調用業務邏輯層全部服務,但接入層內部同層服務之間不可調用
  4. 接入層不能包含業務邏輯代碼
  5. 全部微服務必須運行在Docker容器裏

業務邏輯層咱們主要使用使用Java,接入層咱們主要使用PHP或Node。後來隨着團隊的成長,逐步將接入層所有遷移至Node。後端

框架選型

愛油科技做爲一家成品油行業的初創型公司,須要面對很是複雜的業務場景,並且隨着業務的發展,變化的可能性很是高。因此在微服務架構設計之初,咱們就指望咱們的微服務體系能:api

  • 不綁定到特定的框架、語言
  • 服務最好是Restful風格
  • 足夠簡單,容易落地,未來能擴展
  • 和Docker相容性好

目前常見的微服務相關框架:

  • Dubbo、DubboX
  • Spring Cloud
  • Motan
  • Thrift、gRPC

這些常見的框架中,Dubbo幾乎是惟一能被稱做全棧微服務框架的「框架」,它包含了微服務所需的幾乎全部內容,而DubboX做爲它的加強,增長了REST支持。

它優勢不少,例如:

  • 全棧,服務治理的全部問題幾乎都有現成答案
  • 可靠,通過阿里實踐檢驗的產品
  • 實踐多,社區有許多成功應用Dubbo的經驗

不過遺憾的是:

  • 已經中止維護
  • 不利於裁剪使用
  • 「過於Java」,與其餘語言相容性通常

Motan是微博平臺微服務框架,承載了微博平臺千億次調用業務。

優勢是:

  • 性能好,源自於微博對高併發和實時性的要求
  • 模塊化,結構簡單,易於使用
  • 與其餘語言相容性好

不過:

  • 爲「短平快」業務而生,即業務簡單,追求高性能高併發。

Apache Thrift、gRPC等雖然優秀,並不能算做微服務框架,自身並不包括服務發現等必要特性。

若是說微服務少不了Java,那麼必定少不了Spring,若是說少不了Spring,那麼微服務「官配」Spring Cloud固然是值得斟酌的選擇。

Spring Cloud優勢:

  • 「不作生產者,只作搬運工」
  • 簡單方便,幾乎零配置
  • 模塊化,鬆散耦合,按需取用
  • 社區背靠Spring大樹

固然它有不少不足之處,例如:

  • 輕量並不是全棧
  • 沒解決RPC的問題
  • 實踐案例少

根據咱們的目標,咱們最終選擇了Spring Cloud做爲咱們的微服務框架,緣由有4點:

  1. 雖然Dubbo基礎設施更加完善,但結構複雜,咱們很難吃得下,容易出坑;
  2. 基於Apache ThriftgRPC自研,投入產出比不好;
  3. 不想過早引入RPC以防濫用,Restful風格自己就是一種約束;
  4. 作選擇時,Motan尚未發佈。

所以Spring Cloud成爲了理性的選擇。

Spring Cloud

Spring Cloud是一個集成框架,將開源社區中的框架集成到Spring體系下,幾個重要的家族項目:

  • spring-boot,一改Java應用程序運行難、部署難,甚至無需Web容器,只依賴JRE便可
  • spring-cloud-netflix,集成Netflix優秀的組件Eureka、Hystrix、Ribbon、Zuul,提供服務發現、限流、客戶端負載均衡和API網關等特性支持
  • spring-cloud-config,微服務配置管理
  • spring-cloud-consul,集成Consul支持

固然,SpringCloud下子項目很是多,這裏就不一一列出介紹了。

服務發現和配置管理

Spring Cloud Netflix提供了Eureka服務註冊的集成支持,不過沒選它是由於:

  • 更適合純Java平臺的服務註冊和發現
  • 架構中仍然須要其餘分佈式KV服務,沒解決咱們的核心問題

Docker做爲支撐平臺的重要技術之一,Consul幾乎也是咱們的必選服務。所以咱們以爲一事不煩二主,理所應當的Consul成爲咱們的服務註冊中心。

Consul的優點:

  • 使用Raft一致性算法,能保證分佈式集羣內各節點狀態一致
  • 提供服務註冊、服務發現、服務狀態檢查
  • 支持HTTP、DNS等協議
  • 提供分佈式一致性KV存儲

也就是說,Consul能夠一次性解決咱們對服務註冊發現、配置管理的需求,並且長期來看也更適合跟不一樣平臺的系統,包括和Docker調度系統進行整合。

最初打算本身開發一個Consul和Spring Cloud整合的組件,不過幸運的是,咱們作出這個決定的時候,spring-cloud-consul剛剛發佈了,咱們能夠拿來即用,這節約了不少的工做量。

所以藉助Consul和spring-cloud-consul,咱們實現了

  • 服務註冊,引用了srping-cloud-consul的項目能夠自動註冊服務,也能夠經過HTTP接口手動註冊,Docker容器也能夠自動註冊
  • 服務健康狀態檢查,Consul能夠自動維護健康的服務列表
  • 異構系統能夠直接經過Consul的HTTP接口拉取並監視服務列表,或者直接使用DNS解析服務
  • 經過分佈式一致性KV存儲進行微服務的配置下發
  • 爲一些業務提供選主和分佈式鎖服務

固然也踩到了一些坑:

spring-cloud-consul服務註冊時不能正確選判本地ip地址。對於咱們的環境來講,不管是在服務器上,仍是Docker容器裏,都有多個網絡接口同時存在,而spring-cloud-consul在註冊服務時,須要先選判本地服務的IP地址,判斷邏輯是以第一個非本地地址爲準,經常錯判。所以在容器中咱們利用entrypoint腳本獲取再經過環境變量強制指定。

咱們的容器運行在Rancher中,因此能夠利用Rancher的metadata服務來獲取容器的IP地址,再經過SPRING_CLOUD_CONSUL_DISCOVERY_HOSTNAME環境變量來設置服務發現的註冊地址。基於其餘容器調度平臺也會很類似。

服務集成

爲了方便開發人員使用,微服務框架應當簡單容易使用。對於不少微服務框架和RPC框架來講,都提供了很好的機制。在Spring Cloud中經過OpenFeign實現微服務之間的快速集成:

服務方聲明一個Restful的服務接口,和普通的Spring MVC控制器幾乎別無二致:

客戶方使用一個微服務接口,只須要定義一個接口:

在須要使用UserClient的Bean中,直接注入UserClient類型便可。事實上,UserClient和相關VO類,能夠直接做爲公共接口封裝在公共項目中,供任意須要使用的微服務引用,服務方Restful Controller直接實現這一接口便可。

OpenFeign提供了這種簡單的方式來使用Restful服務,這大大下降了進行接口調用的複雜程度。

對於錯誤的處理,咱們使用HTTP狀態碼做爲錯誤標識,並作了以下規定:

  • 4xx用來表示因爲客戶方參數錯誤、狀態不正確、沒有權限、操做衝突等種種緣由致使的業務錯誤。
  • 5xx用來表示因爲服務方系統異常、沒法服務等緣由服務不可用的錯誤。

對於服務器端,只須要在一個異常類上添加註解,便可指定該異常的HTTP響應狀態碼,例如:

對於客戶端咱們實現了本身的FeignClientExceptionErrorDecoder來將請求異常轉換爲對於的異常類,示例以下:

須要注意的是,decode方法返回的4xx狀態碼異常應當是HystrixBadRequestException的子類對象,緣由在於,咱們把4xx異常視做業務異常,而不是因爲故障致使的異常,因此不該當被Hystrix計算爲失敗請求,並引起斷路器動做,這一點很是重要

UserClient.findOne方法的調用代碼中,便可直接捕獲相應的異常了:

try {
    User user = this.userClient.findOne(new UserId(id));
} catch(NotFoundException ex) {
    ...
}

經過OpenFeign,咱們大大下降了Restful接口進行服務集成的難度,幾乎作到了無額外工做量的服務集成。

服務質量保證

微服務架構下,因爲調用須要跨系統進行遠程操做,各微服務獨立運維,因此在設計架構時還必須考慮伸縮性和容錯性,具體地說主要包括如下幾點要求:

  • 服務實例能夠平滑地加入、移除
  • 流量能夠均勻地分佈在不一樣的實例上
  • 接口應當資源隔離,防止由於個別接口調用時間過長致使線程池被佔滿而致使整個服務不可用
  • 能支持接口降級並隔離故障節點,防止集羣雪崩
  • 服務能進行平滑升級

spring-cloud-netflix和相關組件爲咱們提供了很好的解決方案:

  • Hystrix – 實現了斷路器模式,幫助控流和降級,防止集羣雪崩,就像汽車的避震器
  • Ribbon – 提供了客戶端負載均衡器
  • Zuul – API網關模式,幫助實現接口的路由、認證等

下面主要介紹一下,各個組件在進行服務質量保證中是如何發揮做用的。

Consul

Consul中註冊了一致性的可用的服務列表,並經過健康檢查保證這些實例都是存活的,服務註冊和檢查的過程以下:

  • 服務啓動完成,服務端口開始監聽時,spring-cloud-consul經過Consul接口發起服務註冊,將服務的/health做爲健康檢查端點;
  • Consul每隔5秒訪問/health,檢查當前微服務是否爲UP狀態;
  • /health將會收集微服務內各個儀表收集上來的狀態數據,主要包括數據庫、消息隊列是否連通等;
  • 若是爲UP狀態,則微服務實例被標記爲健康可用,不然被標記成失敗;
  • 當服務關閉時,先從Consul中取消服務註冊,再優雅停機。

這樣可以保證Consul中列出的全部微服務狀態都是健康可用的,各個微服務會監視微服務實例列表,自動同步更新他們。

Hystrix

Hystrix提供了斷路器模式的實現,主要在三個方面能夠說明:

圖片來自Hystrix項目文檔

首先Hystrix提供了降級方法,斷路器開啓時,操做請求會快速失敗再也不向後投遞,直接調用fallback方法來返回操做;當操做失敗、被拒或者超時後,也會直接調用fallback方法返回操做。這能夠保證在系統過載時,能有後備方案來返回一個操做,或者優雅的提示錯誤信息。斷路器的存在能讓故障業務被隔離,防止過載的流量涌入打死後端數據庫等。

而後是基於請求數據統計的斷路開關,在Hystrix中維護一個請求統計了列表(默認最多10條),列表中的每一項是一個桶。每一個桶記錄了在這個桶的時間範圍內(默認是1秒),請求的成功數、失敗數、超時數、被拒數。其中當失敗請求的比例高於某一值時,將會觸發斷路器工做。

最後是不一樣的請求命令(HystrixCommand)可使用彼此隔離的資源池,不會發生相互的擠佔。在Hystrix中提供了兩種隔離機制,包括線程池和信號量。線程池模式下,經過線程池的大小來限制同時佔用資源的請求命令數目;信號量模式下經過控制進入臨界區的操做數目來達到限流的目的。

這裏包括了Hystrix的一些重要參數的配置項:

參數 說明
circuitBreaker.requestVolumeThreshold 至少在一個統計窗口內有多少個請求後,才執行斷路器的開關,默認20
circuitBreaker.sleepWindowInMilliseconds 斷路器觸發後多久後才進行下一次斷定,默認5000毫秒
circuitBreaker.errorThresholdPercentage 一個統計窗口內百分之多少的請求失敗才觸發熔斷,默認是50%
execution.isolation.strategy 運行隔離策略,支持ThreadSemaphore,前者經過線程池來控制同時運行的命令,後者經過信號來控制,默認是Thread
execution.isolation.thread.interruptOnTimeout 命令執行的超時時間,默認1000毫秒
coreSize 線程池大小,默認10
keepAliveTimeMinutes 線程存活時間,默認爲1分鐘
maxQueueSize 最大隊列長度,-1使用SynchronousQueue,默認-1。
queueSizeRejectionThreshold 容許隊列堆積的最大數量

Ribbon

Ribbon使用Consul提供的服務實例列表,能夠經過服務名選取一個後端服務實例鏈接,並保證後端流量均勻分佈。spring-cloud-netflix整合了OpenFeign、Hystrix和Ribbon的負載均衡器,整個調用過程以下(返回值路徑已經省略):

在這個過程當中,各個組件扮演的角色以下:

  • Feign做爲客戶端工廠,負責生成客戶端對象,請求和應答的編解碼
  • Hystrix提供限流、斷路器、降級、數據統計
  • Ribbon提供負載均衡器

Feign負責提供客戶端接口收調用,把發起請求操做(包括編碼、解碼和請求數據)封裝成一個Hystrix命令,這個命令包裹的請求對象,會被Ribbon的負載均衡器處理,按照負載均衡策略選擇一個主機,而後交給請求對象綁定的HTTP客戶端對象發請求,響應成功或者不成功的結果,返回給Hystrix。

spring-cloud-netflix中默認使用了Ribbon的ZoneAwareLoadBalancer負載均衡器,它的負載均衡策略的核心指標是平均活躍請求數(Average Active Requests)。ZoneAwareLoadBalancer會拉取全部當前可用的服務器列表,而後將目前因爲種種緣由(好比網絡異常)響應過慢的實例暫時從可用服務實例列表中移除,這樣的機制能夠保證故障實例被隔離,以避免繼續向其發送流量致使集羣狀態進一步惡化。不過因爲目前spring-cloud-consul還不支持經過consul來指定服務實例的所在區,咱們正在努力將這一功能完善。除了選區策略外,Ribbon中還提供了其餘的負載均衡器,也能夠自定義合適的負載均衡器。

關於區域的支持,我提交的PR已經Merge到spring-cloud-consul項目中,預計下個版本將會包含這項特性。

總的來看,spring-cloud-netflix和Ribbon中提供了基本的負載均衡策略,對於咱們來講已經足夠用了。但實踐中,若是須要進行灰度發佈或者須要進行流量壓測,目前來看還很難直接實現。而這些特性在Dubbo則開箱即用。

Zuul

Zuul爲使用Java語言的接入層服務提供API網關服務,既能夠根據配置反向代理指定的接口,也能夠根據服務發現自動配置。Zuul提供了相似於iptables的處理機制,來幫助咱們實現驗證權鑑、日誌等,請求工做流以下所示:

圖片來自Zuul官方文檔。

使用Zuul進行反向代理時,一樣會走與OpenFeign相似的請求過程,確保API的調用過程也能經過Hystrix、Ribbon提供的降級、控流機制。

Hystrix Dashboard

Hystrix會統計每一個請求操做的狀況來幫助控制斷路器,這些數據是能夠暴露出來供監控系統熱點。Hystrix Dashboard能夠將當前接口調用的狀況以圖形形式展現出來:

圖片來自Hystrix Dashboard官方示例

Hystrix Dashboard既能夠集成在其餘項目中,也能夠獨立運行。咱們直接使用Docker啓動一個Hystrix Dashboard服務便可:

爲了實現能對整個微服務集羣的接口調用狀況彙總,可使用spring-cloud-netflix-turbine來將整個集羣的調用狀況聚集起來,供Hystrix Dashboard展現。

日誌監控

微服務的日誌直接輸出到標準輸出/標準錯誤中,再由Docker經過syslog日誌驅動將日誌寫入至節點機器機的rsyslog中。rsyslog在本地暫存並轉發至日誌中心節點的Logstash中,既歸檔存儲,又經過ElasticSearch進行索引,日誌能夠經過Kibana展現報表。

在rsyslog的日誌收集時,須要將容器信息和鏡像信息加入到tag中,經過Docker啓動參數來進行配置:

不過rsyslog默認只容許tag不超過32個字符,這顯然是不夠用的,因此咱們自定義了日誌模板:

在實際的使用過程當中發現,當主機內存負載比較高時,rsyslog會發生日誌沒法收集的狀況,報日誌數據文件損壞。後來在Redhat官方找到了相關的問題,確認是rsyslog中的一個Bug致使的,當開啓日誌壓縮時會出現這個問題,咱們選擇暫時把它禁用掉。

領域驅動設計

領域驅動設計可以很大程度上幫助咱們享用微服務帶來的優點,因此咱們使用領域驅動設計(DDD)的方法來構建微服務,由於微服務架構和DDD有一種自然的契合。把全部業務劃分紅若干個子領域,有強內在關聯關係的領域(界限上下文)應當被放在一塊兒做爲一個微服務。最後造成了界限上下文-工做團隊-微服務一一對應的關係:

  • 身份與訪問 – 團隊A – 成員微服務
  • 商品與促銷 – 團隊B – 商品微服務
  • 訂單交易 – 團隊C – 交易微服務

微服務設計

在設計單個微服務(Epic層的微服務)時,咱們這樣作:

  • 使用OOD方法對業務進行領域建模,領域模型應當是充血模型
  • 領域服務幫助完成多個領域對象協做
  • 事件驅動,提供領域事件,供內部或者其餘微服務使用
  • 依賴倒置,在適配器接口中實現和框架、組件、SDK的整合

這給咱們帶來了顯著的好處:

  • 服務開發時關注於業務,邊界合理清晰
  • 容易直接對領域模型進行單元測試
  • 不依賴特定組件或者平臺

事務問題

從單體應用遷移到微服務架構時,不得不面臨的問題之一就是事務。在單體應用時代,全部業務共享同一個數據庫,一次請求操做可放置在同一個數據庫事務中;在微服務架構下,這件事變得很是困難。然而事務問題不可避免,很是關鍵。

解決事務問題時,最早想到的解決方法一般是分佈式事務。分佈式事務在傳統系統中應用的比較普遍,主要基於兩階段提交的方式實現。然而分佈式事務在微服務架構中可行性並不高,主要基於這些考慮:

  • 分佈式事務須要事務管理器,對於不一樣語言平臺來講,幾乎沒有有一致的實現來進行事務管理;
  • 並不是全部的持久化基施都提供完整ACID的事務,好比如今普遍使用的NoSQL;
  • 分佈式事務存在性能問題。

根據CAP理論,分佈式系統不可兼得一致性、可用性、分區容錯性(可靠性)三者,對於微服務架構來說,咱們一般會保證可用性、容錯性,犧牲一部分一致性,追求最終一致性。因此對於微服務架構來講,使用分佈式事務來解決事務問題不管是從成本仍是收益上來看,都不划算。

對微服務系統來講解決事務問題,CQRS+Event Sourcing是更好的選擇。

CQRS是命令和查詢職責分離的縮寫。CQRS的核心觀點是,把操做分爲修改狀態的命令(Command),和返回數據的查詢(Query),前者對應於「寫」的操做,不能返回數據,後者對應於「讀」的操做,不形成任何影響,由此領域模型被一分爲二,分而治之。

Event Sourcing一般被翻譯成事件溯源,簡單的來講就是某一對象的當前狀態,是由一系列的事件疊加後產生的,存儲這些事件便可經過重放得到對象在任一時間節點上的狀態。

經過CQRS+Event Sourcing,咱們很容易得到最終一致性,例如對於一個跨系統的交易過程而言:

  • 用戶在交易微服務提交下單命令,產生領域事件PlaceOrderEvent,訂單狀態PENDING
  • 支付微服務收到領域事件進行扣款,扣款成功產生領域事件PaidEvent
  • 交易微服務收到領域事件PaidEvent,將訂單標記爲CREATED
  • 若支付微服務發現額度不足扣款失敗,產生領域事件InsufficientEvent,交易微服務消費將訂單標記爲CANCELED

咱們只要保證領域事件能被持久化,那麼即便出現網絡延遲或部分系統失效,咱們也能保證最終一致性。

實踐上,咱們利用Spring從4.2版本開始支持的自定義應用事件機制將本地事務和事件投遞結合起來進行:

  • 領域內業務過程會產生領域事件,經過Spring的應用事件機制進行應用內投遞;
  • 監聽相應的領域事件,在事務提交前投遞至消息隊列;
  • 以上全都沒有異常發生,則本地事務提交,若是出現異常,本地事務回滾。

一些小經驗

  • 使用Spring Configured實現非Spring Bean的依賴注入(本身new的對象也能夠注入了,對充血模型很是有用)
  • 使用Swagger UI實現自文檔的微服務,寫好接口即有文檔,便可調試

DevOps

到目前爲止咱們已經有數十個微服務運行於線上了,微服務數目甚至多過了團隊人數。若是沒有DevOps支持,運維這些微服務將是一場災難。
咱們使用Docker鏡像做爲微服務交付的標準件:

  • Gitlab管理團隊項目代碼
  • Gitlab-CI提供構建打包,你們提交的項目都要構建並跑通測試
  • 使用Rancher做爲Docker調度平臺,Merge後RC分支自動部署
  • 測試經過後統一上線發佈

因爲時間所限,這裏就不展開贅述了。

永不完美

基於spring-cloud-consul的配置管理仍然須要完善,對於大規模應用的環境中,配置的版本控制、灰度、回滾等很是重要。SpringCloud提供了一個核,可是具體的使用還要結合場景、需求和環境等,再作一些工做。

對於非JVM語言的微服務和基於SpringCloud的微服務如何協同治理,這一問題仍然值得探索。包括像與Docker編排平臺,特別是與Mesos協同進行伸縮的服務治理,還須要更多的實踐來支持。

總結

  • 是否選用微服務架構,應當根據業務實際狀況進行判斷,切勿跟風爲了微服務而微服務;
  • 目前來看尚未微服務全棧框架,Spring Cloud也未必是最優方案,技術選型仍是應當務實;
  • 微服務架構下,對於業務的理解拆分、領域建模等提出了更高的要求,相比框架,它們纔是微服務架構的基石;
  • DevOps是微服務實踐中的重要一環,不容小視。

Q&A彙總

Q:大家是部署在公有云,仍是託管機房。
A:咱們部署在阿里雲上,使用了不少阿里雲服務做爲基礎設施,這一點是爲了節約運維成本。

Q:怎麼解決服務過多依賴問題,開發也會有麻煩,由於要開發一個功能,爲了把服務跑起來,可能要跑不少服務。
A:在咱們的實際開發過程當中,也遇到了這個問題。主要的是經過部署幾個不一樣的仿真環境,一組開發者能夠共用這組環境。本地開發也很簡單,只須要把consul指向到這個集羣的consul上便可。

Q:大家微服務業務調用最深有幾層?restful接口調用鏈的效率如何?比單體結構慢多少?
A:通常不超過3層,這是領域驅動設計給咱們帶來的優點,單個服務幾乎本身就能完成職責範圍內的任務,沒有出現RPC災難,一個業務咱們也不傾向於拆分紅若干個遠程操做進行。

Q:你好 咱們單位從6月份 開始實施 微服務化(O2O業務),使用的是dubbo,使用事務型消息來作最終一致性,請問CQRS+Event Sourcing相對於事務型消息隊列來處理一致性問題 有什麼優點麼。
A:其實CQRS+Event Sourcing是一種觀念的轉變,落地仍是須要靠存儲和消息隊列,優點在於能夠消除系統中的鎖點,性能會更好。

Q:有沒有考慮過用kubernetes來實現微服務治理?
A:考慮過,可是咱們團隊規模有限,很難快速落地。

Q:其餘語言有沒有接入spring cloud config?例如PHP和node? 開發人員對微服務進行開發時,是用dockercompose吧服務都起起來,仍是要接入公共的rancher?
A:咱們沒有使用spring-cloud-config,目前有接入層的node服務在使用consul下發配置。開發時本機跑本身的服務,連Rancher環境的Consul。

Q:關於領域事件,若是本地事務提交後,下游的服務報錯,是否只能在業務層面再發起一個補償的事件,讓本地事務達到最終一致性呢?
A:若是下游服務報錯,那麼事件不會被消費。會以退避重試的方式重發事件。

Q:分享很棒,請問大家的docker的部署是基於原生的docker和swarm,仍是kubernetes來作的?
A:謝謝,咱們使用Rancher來管理集羣。沒選Kubernetes的緣由是由於團隊資源有限,Swarm最初試過,調度不夠完善。後來Docker 1.12之後的Swarmkit應該是更好的選擇。

Q:微服務開發測試用例相比於單體應用是否是更復雜一些?大家是怎樣保證測試覆蓋率的?
A:事實上對於單元測試來說,反而更容易進行了。由於系統拆分以後,把原來很難測試的一些節點給疏通了。

Q:你好請教一下,當微服務之間的依賴關係比較多,且層次比較深時,服務的啓動,中止,以及升級之間的關係如何處理?
A:目前還幾乎沒出現過須要完全冷啓動的狀況。並且啓動服務時並不須要依賴服務也啓動,只須要發生業務時,依賴服務啓動便可。

Q:有個問題, zuul作api網關時如何配置consul呢? 文章中貌似沒交待清楚
A:在網關服務中經過@EnableZuulProxy來啓用Zuul反向代理consul中已註冊的服務。也能夠同時經過配置來自定義,詳見http://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/1.2.4.RELEASE/文檔中的Embedded Zuul Reverse Proxy章節。

 

轉自:http://starlight36.com/post/spring-cloud-microservice

相關文章
相關標籤/搜索