微服務框架學習筆記

微服務框架

微服務

多年以來,咱們一直在尋找更好的方法來構建應用系統。咱們一直在學習已有的技術,嘗試新技術,使用不一樣的方式來構建IT應用系統,從而提升客戶滿意度和開發效率。html

Eric Evans的《領域驅動設計》一書幫助理解了用代碼呈現真實世界的重要性,而且告訴咱們如何更好地進行建模。持續交付理論告訴咱們如何更有效地發佈軟件產品,並指出保持每次提交都可發佈的重要性。基於對web的理解,咱們尋找到了機器與機器交互的更好方式。Alistair Cockburn的六邊形架構理論把咱們從分層架構中拯救出來,從而可以更好地體現業務邏輯。藉助虛擬化平臺,可以按需建立機器並調整其大小,藉助基礎設施的自動化,咱們也很容易從一臺機器擴展到多臺。前端

隨着領域驅動設計、持續交付、按需虛擬化、基礎設施自動化、小型自治團隊、大型集羣系統這些實踐的流行,微服務也應運而生。它並非被髮明出來的,而生從現實世界中總結出來的一種趨勢或模式。可是沒有前面體積的這些概念,微服務也很難出現。vue

不少組織發現細粒度的微服務架構能夠幫助他們更快地交付軟件,而且有更多機會嘗試新技術。微服務在技術決策上給咱們極大的自由度,使咱們可以更快地響應不可避免的變化。java

什麼是微服務?

微服務架構是一種架構模式,提倡將單一應用程序劃分紅一組小的服務,每一個服務運行在其獨立的進程中,服務間採用輕量級的通訊機制互相溝通(一般是基於HTTP協議的RESTful API)。每一個服務都圍繞着具體業務進行構建,而且可以被獨立的部署到生產環境,類生產環境等。react

很小、專一於作好一件事git

隨着新功能的增長,代碼庫會愈來愈大。時間久了代碼庫會很是龐大,以致於想要知道該在什麼地方作修改都很困難。儘管咱們想在巨大的代碼庫中作到清晰地模塊化,但事實上這些模塊之間的界限很難維護。類似的功能代碼開始在代碼庫中隨處可見,使得修復bug或實現更加困難。程序員

在單塊系統內,一般會建立一些抽象層或者模塊來保證代碼的內聚性,從而避免上述問題。 內聚性是指將相關代碼放在一塊兒在考慮使用微服務的時候,內聚性這一律念很重要。github

Robert C.Martin有一個對單一職責原則的論述:把因相同緣由而變化的東西聚合到一塊兒,而把因不一樣緣由而變化的東西分離開來。該論述很好的強調了內聚性這一律念。微服務將這個理念應用在獨立的服務上,根據業務的邊界來肯定服務的邊界,這些就很容易肯定某個功能代碼應該放在那裏。並且因爲該服務專一於某個邊界以內,所以能夠很好地避免因爲代碼庫過大衍生出的不少相關問題。web

微服務指導原則

微服務,最大的挑戰就是三個原則:不要太大,不要過小,不要太緊密耦合redis

微服務的定義

沒有規定的微觀概念,微服務不必定要小。

微服務架構風格是一種將單個應用程序開發爲一套小型服務的方法,每一個小型服務都在本身的流程中運行,並於輕量級機制(HTTP)進行通訊。

這些服務圍繞業務功能構建,能夠用全自動部署機制獨立部署。這些服務能夠進行集中管理,能夠用不一樣的編程語言編寫,並使用不一樣的數據庫存儲技術。

足夠小並且不過小,一旦一段代碼再也不感受到太大了,它可能足夠小了。

開發軟件更快

主要應用程序是一個大型代碼庫,幾個小型開發團隊試圖爲不一樣目的構建功能。意味着每一次變動都必須努力知足不一樣的羣體。

讓不一樣的開發人員團隊共享相同的代碼庫也意味着的代碼以難以想象的方式不斷變得更加複雜。隨着代碼庫變得愈來愈大,團隊中沒有人能夠擁有它而且確保全部部件都按照最佳方式進行組織和組合。

使得部署變得困難,對咱們的應用程序進行單行更改仍然須要部署整個過程以推進更改。因爲咱們的大型應用程序是高風險的,質量保證流程增加

經過微服務架構,但願可以將代碼分開,以便不一樣的開發團隊能夠徹底擁有它們。這將使團隊可以更快地進行建立,而無需繁瑣的設計,審查、部署流程。還但願經過減小開發人員處理較小的代碼庫,代碼庫將更容易開發,測試和保持良好的組織。

靈活應對技術選擇

經過微服務架構,但願將個別服務保持在較小狀態意味着用更好的實現來替換它們的成本將更容易管理。也但願可以爲每項工做選擇合適的工具,而不是一刀切的方法。能夠靈活地在咱們認爲合適的不一樣應用程序中使用多種技術。

微服務缺點

開發,託管和管理衆多服務須要大量開銷。在少數幾個進程上運行的單個總體能夠輕鬆地轉換爲幾個服務的幾十個進程,須要負載均衡器,消息傳遞層和羣集以實現彈性。

微服務涉及分佈式系統,這些系統引入了許多問題,例如:網絡延遲、容錯、事務、不可靠的網絡和異步性

單片應用 

構建爲統一單元。一般由三部分組成:數據庫、客戶端界面(HTML)、服務端應用。

服務端應用將處理HTTP請求,執行邏輯,從數據庫檢索和更新數據,以及填充要發送到瀏覽器的HTML視圖

一般是一個龐大的代碼庫。服務器端的應用邏輯,前端客戶端邏輯,後臺做業等都在同一個代碼庫定義。開發人員想要進行更改或更新,須要一次構建和部署整個堆棧

優勢: 

  • 更少的跨域問題
  • 減小操做開銷:只須要一個應用程序來設置日誌記錄、監視、測試。部署簡單
  • 更容易測試:自動化測試更易於設置和運行
  • 性能:與微服務相比,總體結構還具備性能優點。一般是本地調用而不是網絡API調用 

缺點:

  • 緊耦合:總體結構變得更大。服務隔離變得困難,獨立擴展和代碼維護變得困難
  • 更難理解:與微服務相比,單片應用更難理解。

微服務

微服務架構是指將單個應用程序開發爲一套小型服務的概念,而不是將它們開發爲一個大型的「總體」

每一個分解的個性化的服務都在本身的進程上運行,與輕量級機制(HTTP)進行通訊。徹底成熟的微服務可獨立部署,但必要時能夠協同工做

優勢:

  • 更好的組織:微服務架構一般組織的更好,由於每一個微服務都有很是特定的工做,不關心其餘工做
  • 解耦:更容易重構和從新配置,以知足不一樣應用程序的需求
  • 更少的錯誤

缺點:

  • 每項服務的跨領域關注:構建新的微服務架構時,可能會發現許多在設計時未預料到的跨域問題。須要爲每一個交叉問題產生單獨模塊的開銷,或交叉問題封裝在全部流量經過的另外一個服務層。
  • 更高的操做開銷:微服務常常部署在它們本身的虛擬機或容器上。 

如何選擇

考慮幾個關鍵因素,以下

  • 有沒有微服務經驗
  • 須要基於雲的基礎架構來使微服務適用於您的項目
  • 評估業務風險

適合使用單片應用

  • 團隊規模小,沒法解決更普遍和更高效的微服務架構
  • 正在構建未經正式的產品或概念
  • 沒有微服務經驗:是否能夠冒險去學習

適合微服務

  • 須要快速、獨立的服務交互
  • 一部分平臺須要很是高效:若是企業正在對數PB的日誌量進行密集處理,可能但願用C++構建服務
  • 計劃擴展團隊:您的團隊從一開始就習慣於在不一樣小團隊中進行開發,而且讓團隊按服務邊界分開,能夠輕鬆地擴展您的開發組織

微服務邊界的重要性

使用微服務開發新系統的核心好處之一是該架構容許開發人員獨立構建或修改單個組件時,當涉及最小化每一個API之間的回調數量時會出現問題

避免任意規則

設計和建立微服務時,不須要陷入使用任意規則的陷阱。下面的規則,並非肯定微服務邊界的正確方法

  • 微服務應該有X行代碼:微服務中多少代碼行沒有限制。關鍵是確保高內聚性
  • 將每一個功能轉變爲微服務:實際上取決於功能是什麼以及它如何爲整個系統服務 

精心設計的服務特色

高內聚,鬆耦合

高內聚是指一個軟件模塊是由相關性很強的代碼組成

特徵1:不與其餘服務共享數據庫表

若是多個服務引用相同的表,那麼在設計微服務時就不適合,由於可能意味着你的數據庫是耦合的來源。

開發新服務時使用的主要基本原則之一就是它們不該該跨越數據庫邊界。每一個服務都應該依賴於本身的一組底層數據存儲。這使得咱們能夠集中訪問控制,審計日誌記錄,緩存邏輯等

若是數據庫表的一個子集與數據集的其他部分沒有或不多有鏈接,那麼組件能夠唄隔離到一個單獨的API或單獨的服務中,這是一個強烈信號

每一個服務應該有本身的表和永遠不該該共享數據庫表

特徵2:具備最少許的數據庫表

微服務的理想大小應該足夠小,每一個數據庫表也是同樣的。最佳狀況是一個或兩個數據庫表

特徵3:考慮有狀態和無狀態

設計微服務時,須要考慮它是否須要訪問數據庫,或者它是否處理過TB級別數據的無狀態服務。

經過定義服務的輸入和輸出來定義服務的邊界。有時候服務是網絡API,但它也多是使用文件並在數據庫中生成記錄的進程

特徵4:考慮數據可用性需求 

設計微服務時,須要記住那些服務將依賴於此新服務,以及在該數據不可用時的整個系統的影響。

考慮到這一點,也能夠正確地設計此服務的數據備份和恢復系統

特徵5:單一的真實來源 

設計服務時,讓其稱爲系統中某些內容的惟一真實來源。

注意事項 

整個團隊能夠專門擁有服務,在肯定邊界時,組織性就會發揮做用。

還有兩個須要考慮的因素:獨立的發佈計劃不一樣的正常運行時間 

如何判斷服務是否過小或未正肯定義 

第一個指標是服務之間的任何過分依賴,若是兩個服務不斷地相互呼叫,那麼這是一個強烈的耦合指示和一個信號,可能會更好地組成一個服務

第二個,若是設置服務的開銷大於使其獨立的好處

#

JAVA微服務

框架介紹

使用Java搭建微服務框架語言

未使用微服務框架問題分析:

  1. 數據結構不一致,缺少統一標準
  2. 重複維護:各自進行維護,很難保證信息及時同步
  3. 沒法知足多彙報線的需求:一人多崗,一人多彙報線的狀況
  4. SOA(面向服務架構)建設過程必不可少的基礎服務:SOA架構是企業信息平臺化,標準化建設的最佳方案之一。組織機構與人員信息是各業務系統中必不可少的基礎組件與核心服務,在企業SOA建設中通常都是放在首要階段進行建設。
  5. 平臺化管理與統一受權的核心功能:實現各業務系統的統一受權,而統一的人員管理是實現這一點的基本要求

統一用戶認證平臺

統一用戶認證平臺用於集中管理組織與人員信息,提供統一標準的人員主數據。經過SOA服務總線與各業務系統進行集成,同時爲單點登陸提供統一的身份認證信息。

統一用戶認證平臺與企業郵箱,企業微信息,AD域進行集成。實現一個帳號,全網登陸

技術選擇

Spring Framework  基礎框架支持

Spring Boot  做爲服務的開發框架

Spring Cloud 進行微服務設計與開發

Spring Cloud Netflix 爲Spring Boot應用提供Netflix OSS集成

Eureka 做爲雲服務器中服務註冊與發現中心,實現負載均衡

Feign 進行服務訪問,簡化Eureka訪問參數

Ribbon 實現Eureka集羣的負載均衡

Hystrix 進行服務容錯處理,具有回退機制和斷路器功能的線程和信號隔離,請求緩存\打包以及監控和配置

Zuul 做爲服務網關

ZooKeeper 實現高度可靠的分佈式協調

Dubbo 阿里開源高性能優秀服務框架。

前端
AngularNg-zorro

VueJsElement

部署

Jenkins,GitLab CI 自動化部署

Docker 集裝箱部署

系統結構

 

技術點介紹

Spring Framework

爲現代基於Java語言的企業應用提供全面的編程和配置模型-在任何類型部署平臺上。

Spring的一個關鍵要素是應用程序級別的基礎架構支持:Spring專一於企業應用程序的管道,以便團隊能夠專一於應用程序級人物邏輯,而無需與特定部署環境創建沒必要要的聯繫。

特徵

  • 核心技術:依賴注入,事件,資源,i18n,驗證,數據綁定,類型轉換,SpEL,AOP。

  • 測試:模擬對象,TestContext框架,Spring MVC測試,WebTestClient

  • 數據訪問:事務,DAO支持,JDBC,ORM,編組XML。

  • Spring MVC和 Spring WebFlux Web框架。

  • 集成:遠程處理,JMS,JCA,JMX,電子郵件,任務,調度,緩存。

  • 語言:Kotlin,Groovy,動態語言。

#

Spring Boot

能夠輕鬆建立獨立的,生產級的基於Spring的應用程序。

爲Spring平臺及第三方庫提供開箱即用的設置。多數Spring應用只須要不多的配置。

特徵

  • 建立獨立的Spring應用程序
  • 直接嵌入Tomcat,Jetty或Undertow(無需部署WAR包)
  • 提供入門依賴項以簡化構建配置
  • 儘量自動配置Spring和第三方庫
  • 提供生產就緒功能,例如指標、運行情況檢查和外部化配置
  • 沒有代碼生成,也不須要XML配置

#

Spring Cloud

爲開發人員提供了快速構建分佈式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智能路由,微代理,控制總線,一次性令牌,全局鎖定,領導選舉,分佈式會話,集羣狀態)

使用Spring Cloud開發人員能夠快速搭建實現這些模式的服務和應用程序。適用於任何分佈式環境,包括開發人員本身的筆記本、數據中心和Cloud Foundry等託管平臺

特徵

Spring Cloud專一於爲典型用例提供良好的開箱即用體驗,併爲其餘用戶提供可擴展性機制

  • 分佈式/版本化配置
  • 服務註冊和發現
  • 路由
  • Service到Service Calls
  • 斷路器
  • 全局鎖
  • Leadership election and cluster state
  • 分佈式消息

採用了一種很是具備聲明性的方法,一般只須要更改類路徑和/或註釋便可得到大量內容

主要項目

Spring Cloud Config:git存儲庫支持的集中式外部配置管理。配置資源直接映射到Spring

Spring Cloud Netflix:與各類Netflix OSS組件集成(Eureka,Hystrix,Zuul,Archaius)

Spring Cloud Bus:用於將服務和服務實例與分佈式消息傳遞鏈接在一塊兒的事件總線,用於在羣集中傳播狀態更改

Spring Cloud Cloudfoundry:將應用程序與Prvotal Cloud Foundry集成。提供服務發現實現,還能夠輕鬆實現SSO和OAuth2保護的資源

Spring Cloud Open Service Broker:提供構建實現Open Service Broker API的服務代理的起點

Spring Cloud Cluster:領導者選舉和共同的狀態模式與Zookeeper,Redis,Hazelcast,Consul的抽象和實現

Spring Cloud Consul:Hashicorp Consul的服務發現和配置管理

Spring Cloud Security:Zuul代理中的負載均衡OAuth2 rest客戶端和身份驗證頭中繼續提供支持

Spring Cloud Sleuth:Spring Cloud應用程序的分佈式跟蹤,與Zipkin,HTrace和基於日誌的跟蹤兼容

Spring Cloud Data Flow:適用於現代運行時的可組合微服務應用程序的雲本機編排服務。

Spring Cloud Stream:輕量級事件驅動的微服務框架,可快速構建可鏈接到外部系統的應用程序。在應用程序之間使用Kafka或RabbitMQ發送和接受消息的簡單聲明模型

Spring Cloud Stream App Starters:基於Spring Boot的Spring Integration應用程序,可提供與外部系統的集成

Spring Cloud Task:用於快速構建執行有限數據處理的應用程序。嚮應用程序添加功能和非功能的簡單聲明

Spring Cloud Task App Starters:Spring Boot應用程序,多是任何進程,包括不能永遠運行的Spring Batch做業,在有限的數據處理後結束/中止

Spring Cloud Zookeeper:服務發現和配置管理

Spring Cloud AWS:與託管的Amazon Web Service輕鬆集成。

Spring Cloud Connectors:使各類平臺中的PaaS應用程序能夠輕鬆鏈接到數據庫和消息代理等後端服務

Spring Cloud Starters:能夠簡化Spring Cloud用戶的依賴管理

Spring Cloud CLI:用於在Groovy中快速建立Spring Cloud組件應用程序

Spring Cloud Contract:整體項目,包含幫助用戶成功實施消費者驅動合同方法的解決方案

Spring Cloud Gateway:基於Project Reactor的只能可編程路由器

Spring Cloud OpenFeign:自動配置和Spring環境以及其餘Spring編程模型習慣用法提供Spring Boot應用程序的集成

Spring Cloud Pipelines:固定部署管道,其中包含確保您的應用程序能夠熱部署而且輕鬆回滾出錯的步驟

Spring Cloud Function:支持無服務器提供商之間的統一編程模型

#

Spring Cloude Netflix

Netflix OSS指Netflix Open Source Software

關注點是OOS中的Common Runtime Services & Libraries,包括爲微服務提供支持的運行容器,類庫和服務

Netflix OOS是一組開源的框架和組件庫,是Netflix公司開發出來解決分佈式系統的一些有趣的可擴展類庫。對Java開發者來講,是在雲端環境中開發微服務的很是棒的工具代名詞。在服務發現,負載均衡,容錯等模式方面,都給出了很是重要的概念和解決方案。

組件和功能

Eureka:服務註冊和服務發現

Archaius:分佈式配置管理

Ribbon:客戶端負載均衡

Hystrix:斷路器,運行時提供延遲和容錯的隔離

Karyon:實現雲就緒Web服務的構建藍圖

Governator:擴展和實用程序庫,可經過@PostConstruct和@PreDestory加強Google Guice以提供注入生命週期以及對對象生命週期的支持

Pranae:使其易於與NetflixOSS服務繼承

Zuul:服務網關

Fenzo:Apache Mesos框架的調度程序Java庫,支持用於調度優化的插件並促進集羣自動擴展。

Spring Cloud Netflix

Spring Cloud Netflix經過自動配置和Spring環境以及其餘Spring編程模型習慣用法爲Spring Boot應用程序提供Netflix OSS集成。經過一些簡單的註釋,能夠快速啓用和配置應用程序內的常見模式,並使用通過實戰考研的Netflix組件構建大型分佈式系統。提供的模式包括服務發現(Eureka),斷路器(Hystrix),智能路由(Zuul),客戶端負載均衡(Ribbon)

特徵

服務發現:能夠註冊Eureka實例,客戶端可使用Spring管理的bean發現實例

服務發現:可使用聲明性Java配置建立嵌入式Eureka服務器

斷路器:Hystrix客戶端可使用簡單的註釋驅動方法裝飾器構建

斷路器:帶有聲明性Java配置的嵌入式Hystrix儀表板

聲明性REST客戶端:Feign建立使用JAX-RS或Spring MVC註釋修飾的接口的動態實現

客戶端負載均衡器:Ribbon

外部配置:從Spring Environment到Archaius的橋接(使用Spring Boot約定啓用Netflix組件的本機配置)

路由器和過濾器:Zuul過濾器的自動註冊,以及反向代理建立的配置方法的簡單約定

#

Eureka

一種基於REST的服務,用於發現定位服務,以實現中間層服務器的負載平衡和故障轉移。將此服務稱爲Eureka Server。

Eureka還附帶了一個基於Java的客戶端組件Eureka Client,使與服務的交互變得更加容易。客戶端還有一個內置的負載均衡器,能夠進行基本的循環負載均衡。在Netflix,一個更復雜的負載均衡器包裝Eureka,根據流量,資源使用,錯誤條件等多種因素提供加權負載平衡,以提供卓越的彈性。

簡單的多個服務,經過API調用會面臨如下幾個問題

  • api是寫死的,當調用api地址改變時,其餘程序也須要跟着改變
  • 服務的伸縮性比較差,對單個服務的依賴性較強
  • 每次新建一個服務都要配置api地址,很繁瑣

服務發現是基於微服務架構的關鍵原則之一。嘗試配置每一個客戶端或某種形式的約定可能很是困難,很是脆弱。Eureka能夠將服務器配置和部署爲高可用性,每一個服務器將註冊服務的狀態複製到其餘服務器。

使用服務發現框架Eureka能夠實現如下功能

  • 須要一個服務註冊器,能夠將提供服務的微服務註冊到註冊器中
  • 須要有服務發現機制,能夠經過客戶端方便的找到須要的服務
  • 容災能力,當服務註冊器掛掉以後還能保證服務之間交互正常

Eureka爲咱們提供了以上的解決方案,分別爲Eureka-server和Eureka-client兩個部分。

Eureka提供服務註冊服務發現功能,能夠部署爲Eureka-server集羣。

Eureka-client的主要功能是將服務註冊到Eureka-server,經過Eureka-server發現服務。

高可用性

Eureka服務器沒有後端存儲,可是註冊表中的服務實例必須發送心跳包以保持註冊更新,所以能夠在內存中完成。

Eureka客戶端還具備服務註冊表緩存,當客戶端獲取註冊表中的服務實例時,會從本身的緩存中獲取,客戶端的緩存會定時更新。

當Eureka服務掛了以後,並不會致使客戶端找不到須要請求的服務實例。可是當Eureka服務器掛掉以後,原來註冊表中的服務發生故障或更新,這是就會出現危險的狀況。

Eureka服務器同時也是一個客戶端,須要提供serviceUrl來同步註冊信息,若是不提供就會在日誌中出現大量錯誤。

Eureka服務器配置eureka.client.registerWithEureka=false,eureka.client.fetchRegistry=false

關閉了Eureka服務器之間的同步信息。爲了提升可用性,須要配置多個Eureka服務器,並讓它們之間互相同步註冊信息,當其中一個掛掉以後,Eureka客戶端會自動切換到另外的Eureka服務器。

#

Feign

Feign的第一個目標是下降將Denominator統一綁定到HTTP API的複雜性。

能夠解決API訪問中拼接字符串複雜繁瑣的問題。方便快捷的發送Eureka的REST請求。

#

Ribbon

Ribbon是一個基於HTTP和TCP客戶端的負載均衡器。提供如下功能

  • 負載均衡
  • 容錯
  • 異步和反應模型中的多協議支持(HTTP,TCP,UDP)
  • 緩存和批處理

Ribbon能夠在經過客戶端配置的ribbonServerList服務端列表去輪詢訪問以達到均衡負載的做用。

與Eureka聯合使用,能夠擴展成從Eureka註冊中心獲取服務端列表。

#

Hystrix

避免異常故障蔓延

一個延遲和容錯庫,在隔離對遠程系統,服務和第三方庫的訪問點,中止級聯故障,並在複雜的分佈式系統中實現彈性。

Spring Cloud使用了Hystrix來實現斷路器的共呢個。經過控制那些訪問遠程系統、服務、第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。

Hystrix具有回退機制和斷路器隔絕的線程和信號隔離,請求緩存和請求打包,監控和配置等功能

執行如下操做

  • 經過第三方客戶端訪問依賴關係,防止和控制延遲和故障
  • 複雜的分佈式系統中中止級聯故障
  • 快速失敗並迅速恢復
  • 優雅降級
  • 實時監控,警報和操做控制

複雜分佈式系統結構中的應用程序具備許多依賴關係,每一個依賴關係在某些時候都將不可避免地失敗。若是主機應用程序未與這些外部故障隔離,則會將它們取下

例如:對於依賴於30個服務的應用程序,其中每一個服務的正常運行時間爲99.99%,爲了不級聯錯誤,其中的0.01能夠將其隔離。

能夠設置當調用一個服務達到必定的閾值(5秒失敗20次)打開斷路器。開啓斷路回滾,阻止級聯失敗並容許關閉服務一段時間進行癒合。

而且能夠監控每一個服務訪問的運行狀態時間

#

Zuul(服務網關)

使用Eureka實現了服務註冊,Ribbon或Feign實現服務的消費以及均衡負載。Hystrix的斷路機制來避免異常故障蔓延

Zuul就是對外提供的一個服務網關。跟Nginx實現一樣的功能

經過服務網關統一貫外系統提供REST API的過程當中,除了具有服務路由、負載均衡功能外,還具有了權限控制等功能。

Zuul是從設備和網站到Netflix流應用程序後端的全部請求的攔截。

Zuul使用一系列不一樣類型的過濾器,使咱們可以快速靈活地將功能應用於咱們的邊緣服務。過濾器能夠幫助咱們執行如下功能:

  • 身份驗證和安全性:識別每一個資源的身份驗證要求並拒毫不知足這些要求的請求
  • 洞察和監控:邊緣跟蹤有意義的數據和統計數據,以便爲咱們提供準確的生產視圖
  • 動態路由:根據須要動態地將請求路由到不一樣的後端羣集
  • 壓力測試:逐漸增長羣集的流量以衡量性能
  • Load Shedding:爲每種類型的請求分配容量並刪除超過限制的請求
  • 靜態響應處理:直接在邊緣構建一些響應,而不是將它們轉發到內部集羣
  • 多區域彈性:跨AWS區域路由請求,以使咱們的ELB使用多樣化,並使咱們的優點更接近咱們的成員

服務路由

經過服務路由的功能,對外提供服務時,只須要經過暴露Zuul中配置的調用地址,就可讓調用方統一來訪問咱們的服務,而不須要了解具體提供的主機信息。

經過上面配置,全部訪問 /api-a-url/** 的訪問都映射到 localhost:2222上面

提供兩種方式映射

  • url映射,上圖方式
  • serviceId映射,結合Eureka。

 

服務過濾

對開放服務還須要一些安全措施來保護客戶端只能訪問它應該訪問到的資源。能夠用過濾器來實現對外服務的安全控制

例子:檢查請求中是否包含accessToken參數,若是沒有就拒絕訪問

#

ZooKeeper

分佈式應用程序的分佈式開源協調服務。

公開了一組簡單的基礎原件,分佈式應用能夠在這些原件之上實現更高級別的服務。

好比同步、配置維護、羣集和命名。

設計目標

Zookeeper容許程序經過一個共享的相似於標準文件系統的有組織的分層命名空間分佈式處理協調。

Zookeeper的實現提供了一個優質的高性能、高可用,嚴格的訪問順序。

Zookeeper是很是簡單和高效的。由於它的目標就是,做爲建設複雜服務的基礎,好比同步。zookeeper提供了一套保證,他們包括:

  • 順序一致性 - 來自客戶端的更新會按順序應用。
  • 原子性 - 更新成功或者失敗,沒有局部的結果產生。
  • 惟一系統映像 - 一個客戶端無論鏈接到哪一個服務端都會看到一樣的視圖。
  • 可靠性- 一旦一個更新被應用,它將從更新的時間開始一直保持到一個客戶端重寫更新。
  • 時效性 - 系統中的客戶端視圖在特定的時間點保證成爲是最新的。

#

Dubbo

Apache Dubbo是一個高性能,輕量級,基於Java的RPC框架。提供三個關鍵功能,包括基於接口的遠程調用,容錯和負載平衡,以及自動服務註冊和發現。

功能

  • 基於透明接口的RPC:提供基於RPC的高性能接口,對用戶透明。(RPC:遠程過程調用協議)
  • 智能負載均衡:支持多種開箱即用的負載均衡策略,能夠感知下游服務狀態,從而減小整體延遲並挺高系統吞吐量
  • 自動服務註冊和發現:支持多個服務註冊表,能夠當即在線/離線檢測服務
  • 可擴展性高:Dubbo的微內核和插件設計確保能夠經過協議,傳輸和序列化等核心功能輕鬆擴展第三方實施
  • 運行時流量路由:能夠在運行時配置Dubbo,以便根據不一樣的規則路由流量,能夠輕鬆支持藍綠色部署,數據中心感知路由等功能
  • 可視化的服務治理:爲服務治理和維護提供了豐富的工具,例如查詢服務元數據,健康狀態和統計數據

#

Jenkins

獨立的開源自動化服務器,可用於自動執行與構建,測試,交付或部署軟件相關的各類任務。

#

Spring集成架構

  • Azure
    • Azure Support:Azure服務的自動配置(服務總線、存儲、活動目錄、cosmos DB、密鑰庫等)
    • Azure Active Directory:Spring Security與Azure Active Directory集成以進行身份​​驗證
    • Azure Key Vault:Spring值註釋與Azure Key Vault Secrets的集成
    • Azure Storage:Azure存儲服務集成
  • Cloud AWS
    • AWS Core:來自spring-cloud-aws的本地服務
    • AWS JDBC:AWS上的關係數據庫與RDS和spring-cloud-aws-jdbc
    • AWS Messaging:使用SQS和spring-cloud-aws-messaging在AWS上進行消息傳遞
  • Cloud Circuit Breaker:斷路器
    • Hystrix:斷路器與spring-cloud-netflix Hystrix
    • Hystrix Dashboard:帶有spring-cloud-netflix Hystrix的斷路器儀表板
    • Turbine:使用spring-cloud-netflix與Turbine和服務器發送事件的斷路器度量聚合
    • Turbine Stream:使用spring-cloud-netflix與Turbine和Spring Cloud Stream進行斷路器度量聚合(須要綁定器,例如Kafka或RabbitMQ)
  • Cloud Config:配置
    • Config Client:spring-cloud-config客戶端
    • Config Server:經過git或svn後端進行配置的集中管理
    • Vault Configuration:使用HashiCorp Vault進行配置管理
    • Zookeeper Configuration:使用Zookeeper和spring-cloud-zookeeper-config進行配置管理
    • Consul Configuration:Hashicorp Consul的配置管理
  • Cloud Contract:合同
    • Cloud Contract Verifier:測試自動生成測試所需的依賴關係 
    • Cloud Contract Stub Runner:用於基於HTTP /消息傳遞的通訊的Stub Runner。容許從RestDocs測試建立WireMock存根
  • Cloud Core:核心
    • Cloud Bootstrap:spring-cloud-context(例如Bootstrap context和@RefreshScope)
    • Cloud Function:做爲bean的功能
    • Cloud Security:使用spring-cloud-security保護負載平衡和路由
    • Cloud OAuth2:具備spring-cloud-security的OAuth2和分佈式應用程序模式
    • Cloud Task:任務結果跟蹤和與Spring Batch的集成
  • Cloud Discovery:發現
    • Eureka Discovery:使用spring-cloud-netflix和Eureka進行服務發現
    • Eureka Server:spring-cloud-netflix Eureka Server
    • Zookeeper Discovery:使用Zookeeper和spring-cloud-zookeeper-discovery進行服務發現
    • Cloud Foundry Discovery:使用Cloud Foundry進行服務發現
    • Consul Discovery:Hashicorp Consul的服務發現
  • Cloud Messaging:消息傳遞
    • Cloud Bus:使用Spring Cloud Stream的簡單控制總線(須要綁定器,例如Kafka或RabbitMQ)
    • Cloud Stream:使用Spring Cloud Stream傳遞微服務(須要綁定器,例如Kafka或RabbitMQ)
    • Reactive Cloud Stream:使用Spring Cloud Stream的反應性消息傳遞微服務(須要綁定器,例如Kafka或RabbitMQ)
  • Cloud Routing:路由
    • Zuul:使用spring-cloud-netflix Zuul進行智能和可編程路由 
    • Gateway:使用響應式Spring Cloud Gateway進行智能和可編程路由
    • Ribbon:使用spring-cloud-netflix和Ribbon進行客戶端負載均衡
    • Feign:使用spring-cloud-netflix Feign的聲明式REST客戶端
  • Cloud Support:支持
    • Colud Connectors:簡化與雲平臺服務的鏈接,包括spring-cloud-connector和spring-cloud-cloudfoundry-connector
    • Open Service Broker:建立符合Open Service Broker API規範的服務代理
  • Cloud Tracing:跟蹤
    • Sleuth:使用spring-cloud-sleuth經過日誌進行分佈式跟蹤
    • Zipkin Client:使用現有的Zipkin安裝和spring-cloud-sleuth-zipkin進行分佈式跟蹤
  • Core
    • DevTools:Spring Boot開發工具
    • Security:經過spring-security保護您的應用程序
    • Lombok:Java註釋庫,有助於更快地減小樣板代碼和代碼
    • Configuration Processor:爲您的自定義配置鍵生成元數據
    • Session:用於管理用戶會話信息的API和實現
    • Cache:Spring的Cache抽象
    • Validation:JSR-303驗證基礎設施(已包含在Web中)
    • Retry:經過spring-retry提供聲明性重試支持
    • Aspects:使用Spring AOP和AspectJ建立本身的Aspects
  • I/O
    • Batch: Spring Batch支持 
    • Mail:使用Java Mail和Spring Framework的JavaMailSender發送電子郵件
    • Apache Camel:使用Apache Camel進行集成
    • LDAP:LDAP支持,包括spring-data-ldap
    • Quartz Scheduler:使用Quartz安排工做
    • Spring Shell:構建基於shell的客戶端
    • Statemachine:使用狀態機概念構建應用程序
  • Integration:集成
    • Spring Integration:常見的彈簧集成模塊
    • RabbitMQ:經過spring-rabbit的高級消息隊列協議
    • Kafka:使用Spring Kafka的Kafka消息支持
    • Kakka Streams:支持使用Apache Kafka Streams構建流處理應用程序
    • JMS(ActiveMQ):經過Apache ActiveMQ的Java消息服務API
    • JMS(Artemis):經過Apache Artemis的Java消息服務API
  • NoSQL
    • Redis:Redis鍵值數據存儲,包括spring-data-redis
    • Reactive Redis:Redis鍵值數據存儲,包括spring-data-redis
    • MongoDB:MongoDB NoSQL數據庫,包括spring-data-mongodb
    • Reactive MongoDB:MongoDB NoSQL數據庫,包括spring-data-mongodb和被動驅動程序
    • Embedded MongoDB:嵌入式MongoDB進行測試
    • Elasticasearch:Elasticsearch搜索和分析引擎包括spring-data-elasticsearch
    • Solr:Apache Solr搜索平臺,包括spring-data-solr
    • Cassandra:Cassandra NoSQL數據庫,包括spring-data-cassandra
    • Reactive Cassandra:Cassandra NoSQL數據庫,包括spring-data-cassandra和反應式驅動程序
    • Couchbase:Couchbase NoSQL數據庫,包括spring-data-couchbase
    • Reactive Couchbase:Couchbase NoSQL數據庫,包括spring-data-couchbase和被動驅動程序
    • Neo4j:Neo4j NoSQL圖形數據庫,包括spring-data-neo4j
  • Ops
    • Actuator:生產就緒功能可幫助您監控和管理您的應用程序
    • Spring Boot Admin(Server):用於Spring引導應用程序的管理界面
    • Spring Boot Admin(Client):使用Spring引導管理實例註冊應用程序
  • Pivotal Cloud Foundry:關鍵的雲計算
    • Config Client:在Pivotal Cloud Foundry上配置客戶端
    • Service Registry:Pivotal Cloud Foundry上的Eureka服務發現
    • Circuit Breaker:Pivotal Cloud Foundry上的Hystrix斷路器
  • SQL
    • JPA:Java持久化API包括spring-data-jpa、spring-orm和Hibernate
    • MySql:MySQL JDBC驅動程序
    • H2:H2數據庫(支持嵌入式)
    • JDBC:JDBC數據庫
    • MyBatis:使用MyBatis的持久性支持
    • PostgreSQL:PostgreSQL JDBC驅動程序
    • SQL Server:Microsoft SQL Server JDBC驅動程序
    • HSQLDB:HSQLDB數據庫(支持嵌入式)
    • Apache Derby:Apache Derby數據庫(支持嵌入式)
    • Liquibase:Liquibase數據庫遷移庫
    • Flyway:Flyway數據庫遷移庫
    • JOOQ:持久性支持使用面向Java對象的查詢
  • Spring Cloud GCP
    • GCP Support:支持Google Cloud Platform服務
    • GCP Messaging:發佈並訂閱Google Cloud Pub / Sub主題
    • GCP Storage:訪問Google雲端存儲對象
  • Template Engines
    • Thymeleaf:Thymeleaf模板引擎
    • Freemarker:FreeMarker模板引擎
    • Mustache:Mustache模板引擎
    • Groovy Templates:Groovy模板引擎
  • Web
    • Web:使用Tomcat和Spring MVC進行全堆棧web開發
    • Reactive Web:使用Netty和Spring WebFlux進行響應式web開發
    • Rest Repositories:經過Spring-Data-REST-webmvc在REST上公開Spring數據存儲庫
    • Rest Repositories HAL Browser:在瀏覽器中瀏覽Spring Data REST存儲庫
    • HATEOAS:HATEOAS-based RESTful服務
    • Web Services:使用Spring Web服務開發契約優先的SOAP服務
    • Jersey(JAX-RS):支持JAX-RS的RESTful Web服務框架
    • Websocket:Websocket開發與SockJS和STOMP
    • REST Docs:經過結合手寫文檔和自動生成文檔來記錄RESTful服務
    • Vaadin:java web應用程序框架

微服務敢獨立交付嗎?

重溫一下微服務的概念:微服務架構是一種架構模式,提倡將單一應用程序劃分紅一組小的服務,每一個服務運行在其獨立的進程中,服務間採用輕量級的通訊機制互相溝通(一般是基於HTTP協議的RESTful API)。每一個服務都圍繞着具體業務進行構建,而且可以被獨立的部署到生產環境,類生產環境等。

獨立部署和自動化部署不是一個概念。自動化部署相對簡單,但獨立部署關鍵和難點在於獨立

若是失去了服務獨立部署的能力,一個微服務架構的威力將大打折扣。

爲何服務的獨立交付並不簡單

舉一個例子

程序員,開發了一個網上商城。代碼Push到Github並經過持續集成(Continuous integration,CI)構建持續交付流水線,最終自動化部署到雲端產品環境,供用戶訪問使用。

隨着用戶和訪問量的增長,需求和功能也愈來愈多。

使用微服務能夠將後臺部分拆成3個服務,簡稱ABC。

當對A服務作了一次新的提交以後,A服務的最新版本升級到了1.1 。這個新的版本之外的破壞了A與B之間的契約,錯誤的調用了B的接口,致使出現了錯誤。

雖然有完善的UT(單元測試),但UT沒法發現服務之間的集成是否被破壞。那麼是否能夠加集成測試呢?

測試多服務集成的測試統一稱做端到端測試(End-to-End tests,簡稱E2E測試)

當A服務逇新版本破壞了B服務的集成時,E2E測試就會及時診斷出來,並阻止A服務的最新版本想產品環境流動,保證不被破壞。

但添加了E2E測試,解決了服務間集成的驗證問題,但也失去了微服務架構的重要特徵:服務的獨立交付

假設A服務的修復過程當中,BC服務也提交了代碼,可是A服務因E2E測試掛掉的問題還未被修復,因此B和C的新版本也被E2E測試攔下來。此時E2E測試就像是一個亮起紅燈的路由,阻塞了全部服務通往產品環境的通道。

因此說,隨着集中E2E測試的添加,質量被保證的同時,微服務架構也悄然失去了服務獨立交付的能力。

雖然可以在代碼庫,部署結構上,甚至在組織上進行服務劃分,但最後一個交付的E2E測試,讓全部的服務又糾纏在一塊兒了,服務化拆分形同虛設,最終獲得了一個看起來像微服務架構的單體應用

拆除紅綠燈,各行其到,收復失地

解決方法也很簡單:Inline E2E tests

即並不添加新的集中的Pipeline作E2E測試,而是爲每個服務的Pipeline都添加一個相同的E2E測試的Stage,至關於將E2E測試lnline到每一個服務各自的部署流水線中

其實lnline E2E測試還不是最關鍵的,變化點就是假設A服務有了新的提交,運行到A服務本身Pipeline的E2E測試的時候,此時的E2E測試並非像以前同樣獲取B和C服務的最新代碼庫版本作集成驗證,而獲取當前產品環境上的B和C服務的已部署當前版本作集成驗證。

如圖所示A服務的版本從1.0升級到1.1,當前產品環境的B和C版本是2.0和3.0。執行A服務Pipeline上的E2E測試時,驗證過A和B集成存在問題,測試變紅,Pipeline掛掉,從而阻斷了A服務的1.1版本部署到產品環境,保證了產品環境不會被1.1版本破壞。

假設A尚未被修復,B也有了新的提交,此時B服務Pipeline上的E2E測試並不獲取當前A服務的代碼庫作集成測試,而是獲取產品環境上的當前版本作集成測試。假設B和A之間的集成沒有問題,那麼B就被成功交付到產品環境裏面了。

 

契約測試 

契約測試也是這兩年伴隨微服務架構的興起,常常被說起的一種比較新的測試類型。測試金字塔中,位於E2E和Component Test(單個服務API)之間

簡單的理解,契約測試就是一種能夠用相似於單元測試的技術驗證兩個服務之間集成的測試技術。相比於更低層次的單元測試的優點是實現方式上又相似於單元測試,更輕量,跑的更快,覆蓋的範圍天然能夠更廣更細

契約測試替換掉E2E測試以後,這個架構也會變得更復雜,目前契約測試的框架也有不少,例如Pact或SpringContracts等。

A服務調用B服務的一個API,稱爲A和B之間存在一個契約,即B應該提供知足契約要求的API,而A也應該按照這個契約約定的方式來調用B的這個API。

這個過程當中A做爲調用方,稱之爲Consumer端。B做爲被調用方,稱之爲Provider端

若是A和B都履行契約,按照契約定義的約定調用和被調用,就能夠認爲集成不會有問題。但不管是B修改了API破壞契約,仍是A修改了調用API的方式破壞契約,都會致使契約被破壞,反映到測試上就是契約測試失敗。

每一個契約,例如A->B,都會有Consumer端和Provider端生成的兩個產出物:分別是a-b.consumer.json.1.1(由Consumer端生成的契約文件,因此版本也是Consumer端A的版本號)和a-b.provider.jar.2.0(由Provider端生成的契約驗證測試包)這個jar包其實就是一組測試,輸入的是a-b.consumer.json,產出則是測試的結果,也就是契約的驗證結果:成功或失敗

能夠把契約文件當成一把鑰匙,測試包當成一把鎖。契約測試的執行過程就像是用鑰匙試着去開這把鎖:若是能夠打開,認爲這A1.1->B.20的契約是知足的,反之契約就是被破壞了。

契約測試不像E2E測試,是有方向的,因此看到a-b和b-a是兩個不一樣契約。

只有當A1.1->B.2.0和B2.0->A1.1雙向的契約都被驗證經過後,才能認爲A和B的集成是沒有問題的。

用契約測試代替E2E

假設已經構建了ABC三個服務兩兩之間的契約測試。此時A服務有了新的提交升級到了1.1版本,如何才能經過契約測試來驗證A1.1版本可否交付到產品環境呢?

只要經過A的1.1版本的最新代碼,生成全部A做爲Consumer端的契約文件(a.b.consumer.json.1.1和a-c.consumer.json.1.1),用兩把鑰匙去試着開對應的鎖。

若是均可以打開,就證實A的新版本做爲Consumer端與產品環境的B和C的服務是兼容的。

還要考慮A做爲Provider的狀況,是經過A的1.1版本的最新diamante生成A版本做爲Provider端的契約測試,拿着這兩把新鎖,去試着用產品環境上的兩把鑰匙去開。

重點

  • 微服務架構下的獨立部署(交付)很重要,但每每容易被忽視,沒有被引發足夠重視。
  • 爲了實現微服務的獨立持續交付,咱們要向「後」看,不要向「前」看,即關注當前變動服務與部署環境中其餘服務的兼容性而不是關注當前變動服務與其餘服務最新版本的兼容性。
  • 用契約測試來替代E2E測試,下降測試成本,提升測試覆蓋,儘早測試。並經過不斷地完善契約管理,保障微服務架構質量和避免微服務架構腐化僵化。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相關文章
相關標籤/搜索