做者: Alexsandro Souzagit
幾乎每一個人都在關注微服務架構,咱們也不例外。做爲一個與時俱進的程序員,我一直在努力瞭解這一架構,但願尋找一種經過Spring在Java中實現微服務架構的方法。程序員
咱們公司雖然很棒,但技術堆棧略顯過期,至今尚未使用Java 8或微服務,所以我須要從外部瞭解更多關於微服務架構的經驗和方法。我決定經過建立一個「to-do system」項目來梳理經驗以供未來參考。github
本文的目標是爲不一樣的微服務提供源代碼walkthrough,所以我不打算深刻概念和工具,而是提出一個包含用於開發微服務的模式、工具、技術的應用示例。spring
「to-do system」將由8個應用組成:數據庫
Reminder設計模式
User安全
Service Discovery System服務器
Mailer架構
OAuth Server併發
System Integration Test
API Gateway
Web Application Client
上圖未系統與微服務的交互。用戶訪問Angular2編寫的應用,該應用連接OAuth Authorization server,經過OAuth Authorization server分配用戶和權限。此server將返回一個Jason Web Token,其中包含有關客戶端及其權限的信息以及格式的範圍。當用戶認證經過並擁有token以後,Web應用能夠與API Gateway通訊。API Gateway將利用JWT驗證請求是否來自受權server,然後調用微服務並構建響應。
OAuth server經過User service獲取用戶權鑑細節,API Gateway從OAuth server獲取用戶信息。
Reminder service是安置ToDo功能的地方,ToDo服務按計劃檢查reminders並經過電子郵件通知用戶,電子郵件由Mail service發送,該事件由使用Kafka的事件提醒服務觸發。
System Integration Test是負責聯絡Reminder Service endpoints的Java應用。
在微服務架構中,咱們須要處理許多在不一樣IP和端口上運行的微服務。所以有必要找到一種無需硬編碼的方式來管理每一個地址。
Netflix Eureka是一種很好的解決方案,做爲客戶端服務發現,Eureka容許服務自動查找和相互通訊。咱們有必要理解eureka的工做原理,一邊瞭解REST服務在不一樣微服務之間的通訊。利用eureka來管理服務運行位置,咱們能夠添加instance,並經過負載均衡實如今微服務之間分配incoming application traffic。】
在咱們的系統中,使用Netflix Ribbon做爲客戶端負載均衡器,實現容錯並經過冗餘增長可靠性和可用性。咱們使用Netflix Feign編寫聲明性REST客戶端,並集成Ribbon和Eureka來提供負載平衡HTTP客戶端。
咱們正在使用Netflix Hystrix斷路器將咱們的應用程序與依賴性故障隔離開來。它有助於阻止cascading failure,並容許咱們快速恢復或添加fallbacks。Hystrix爲每一個依賴關係提供一個thread-pool。當thread-pool耗盡,hystrix將拒絕請求。Hystrix同時提供斷路器功能,能夠中止對依賴關係的全部請求,在請求失敗、拒絕或超時時,還能夠實現備用邏輯。
對於任何系統來講,安全性都是很是重要的,微服務架構也同樣。咱們經過OAuth2來保持微服務的安全性。OAuth2做爲一項知名Authorization,早已普遍應用於Google,Facebook和Github。
在咱們的這個項目中,同時還應用了Spring Security,並在安全問題上增長了一個元素:JSON Web Token(JWT)。
若是咱們僅使用OAuth,咱們將須要一個OAuth受權服務器來驗證用戶,生成令牌並充當資源服務器的endpoints,詢問該令牌是否有效以及受權的權限。與Authorization Server相比,這須要兩倍的請求。而JWT提供了一種在access token中傳輸權限和用戶數據的簡單方法。一旦全部數據都已經存在於token string中,資源服務器就不須要再請求令牌檢查。全部信息都被序列化爲JSON,用base64編碼,最後用私有RSA密鑰簽名。它假設全部資源服務器都將有一個公鑰,以檢查令牌是否爲適當的私鑰簽名,並對令牌進行反序列化以獲取信息。
在咱們的系統中,咱們有兩種交互方式:同步和異步。對於異步風格,咱們使用分佈式事件與Kafka,遵循模型發佈/訂閱。對於同步,咱們有支持JSON和XML的REST風格。
對於RESTful,有四個成熟級別。咱們的微服務處於2級,爲了簡單起見,我決定不使用HATEOAS設計模式實現超媒體控件。
由於咱們正在使用Spring Cloud,因此咱們要「out-of-box「一些可擴展性模式,把它們放在HTTP鏈接中,如斷路器、bulkhead、負載均衡、鏈接池、超時和重試。
如上所述,咱們經過使用Kafka將Reminder服務和Mailer服務之間的通訊異步地與其餘微服務進行通訊。在Reminder中,咱們有一個計劃任務來檢查提醒時間併發布RemainderFound事件。Mailer服務中將會有一個訂閱的事件,它將開始向用戶發送電子郵件的過程。我邀請您看看咱們如何進行這種整合,以及我如何在Kafka事件模塊中寫入發送到Kafka的數據的序列化/反序列化。
一體化應用通暢具備單個關係數據庫。咱們可使用ACID transaction。所以,若是出現問題,咱們的應用程序能夠簡單地開始一個transaction、更改多個行並提交transaction。但處理微服務架構中的數據訪問要複雜得多,這是由於數據分佈在不一樣的數據庫中。跨多個服務實施業務transactions是一個很大的挑戰。
在咱們的「To-Do system「中,咱們正在使用事件來處理跨多個服務的業務事務。您能夠查看在Mailer服務中應用的CQRS實施事件採購。您能夠看到如何分離讀和寫,使咱們可以輕鬆地縮放每一個部分。咱們使用關係數據庫做爲事件存儲,而後使用Kafka分發事件。咱們將須要使這兩個動做爲Atomic並避免存儲事件,這樣就不會發布最終的JVM崩潰。我不使用Kafka做爲事件存儲,由於從關係數據庫構建聚合更簡單。咱們正在努力使事情變得容易!
在To-Do-System已經包含許多微服務架構涉及到的方方面面,另外一方面也仍然存在諸多挑戰。咱們將來計劃在此項目基礎上增長更多東西,例如Spring雲配置、Docker容器、與Jenkins的持續集成、Spring Sleuth分佈式跟蹤、ELK日誌管理等等。
[開源項目:[雲框架]基於Spring Cloud的微服務架構](https://github.com/cloudframe...,提供Spring Cloud微服務架構最佳實踐,即插即用