第一章 微服務架構演進
1.1、單體架構
架構說明:
全部功能集中在一個項目內(All in one)。
架構優點:
架構簡單,前期開發成本低、開發週期短,適合小型項目。
架構缺點:
全部功能集成在一個工程中,對於大型項目不易開發、擴展和維護。
技術棧受限,只能使用一種語言開發。
系統性能擴展只能通過擴展集羣節點,成本高。
1.2、垂直架構
架構說明:
按照業務進行切割,形成小的單體項目。
架構優點:
技術棧可擴展(不同的系統可以用不同的編程語言編寫)。
架構缺點:
功能集中在一個項目中,不利於開發、擴展、維護。
系統擴張只能通過集羣的方式。
項目之間功能冗餘、數據冗餘、耦合性強。
1.3、SOA架構
架構說明:
SOA全稱爲Service-Oriented Architecture,即面向服務的架構,它可以根據需求通過網絡對鬆散耦合的粗粒度應用組件(服務)進行分佈式部署、組合和使用,一個服務通常以獨立的形式存在於操作系統進程中。站在功能的角度,把業務邏輯抽象成可複用的服務,通過服務的編排實現業務的快速再生,目的:把原先固有的業務功能轉變爲通用的業務服務,實現業務邏輯的快速複用。
將重複功能或模塊抽取成組件的形式,對外提供服務,在項目與服務之間使用ESB(企業服務總線)的形式作爲通信的橋樑。
架構優點:
重複功能或模塊抽取爲服務,提高開發效率。
可重用性高。
可維護性高。
架構缺點:
各系統之間業務不同,很難確認功能或模塊是重複的。
抽取服務的粒度大。
系統和服務之間耦合度高。
1.4、微服務架構
架構說明:
微服務就是將一個單體架構的應用按業務劃分爲一個個的獨立運行的程序即服務,它們之間通過 HTTP 協議進行通信,也可以採用消息隊列來通信,例如 RabbitMQ,Kafaka 等,可以採用不同的編程語言,使用不同的存儲技術,自動化部署(如 Jenkins)減少人爲控制,降低出錯概率。服務數量越多,管理起來越複雜,因此採用集中化管理。例如 Eureka,Zookeeper 等都是比較常見的服務集中化管理框架。
微服務是一種架構風格,一個大型的複雜軟件應用,由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是松耦合的。每個微服務僅關注於完成一件任務並很好的完成該任務。
架構優點:
服務拆分粒度更細,有利於提高開發效率。
可以針對不同服務制定對應的優化方案。
適用於互聯網時代,產品迭代週期更短。
架構缺點:
粒度太細導致服務太多,維護成本高。
分佈式系統開發的技術成本高,對團隊的挑戰大。
第二章 微服務設計原則
2.1、CAP 定理原則
CAP 原則又稱 CAP 定理,指的是在一個分佈式系統中必須具有以下其中兩個特性:
- Consistency (一致性)
- Availability (可用性)
- Partition tolerance(分區容錯性)
CAP 由 Eric Brewer 在 2000 年 PODC 會議上提出,該猜想在提出兩年後被證明成立,成爲我們熟知的 CAP 定理,CAP 三者不可兼得。
特性 | 定理 |
---|---|
Consistency | 也叫做數據原子性,系統在執行某項操作後仍然處於一致的狀態。在分佈式系統中,更新操作執行成功後所有的用戶都應該讀到最新的值,這樣的系統被認爲是具有強一致性的。等同於所有節點訪問同一份最新的數據副本。 |
Availability | 每一個操作總是能夠在一定的時間內返回結果,這裏需要注意的是"一定時間內"和"返回結果"。一定時間內指的是,在可以容忍的範圍內返回結果,結果可以是成功或者是失敗。 |
Partition tolerance | 在網絡分區的情況下,被分隔的節點仍能正常對外提供服務(分佈式集羣,數據被分佈存儲在不同的服務器上,無論什麼情況,服務器都能正常被訪問)。 |
CAP 三個特性只能滿足其中兩個,那麼取捨的策略就共有三種:
- CA without P:如果不要求P(不允許分區),則C(強一致性)和A(可用性)是可以保證的。但放棄 P 的同時也就意味着放棄了系統的擴展性,也就是分佈式節點受限,沒辦法部署子節點,這是違背分佈式系統設計的初衷的。
- CP without A:如果不要求A(可用),相當於每個請求都需要在服務器之間保持強一致,而P(分區)會導致同步時間無限延長(也就是等待數據同步完才能正常訪問服務),一旦發生網絡故障或者消息丟失等情況,就要犧牲用戶的體驗,等待所有數據全部一致了之後再讓用戶訪問系統。設計成 CP 的系統其實不少,最典型的就是分佈式數據庫,如 Redis、HBase 等。對於這些分佈式數據庫來說,數據的一致性是最基本的要求,因爲如果連這個標準都達不到,那麼直接採用關係型數據庫就好,沒必要再浪費資源來部署分佈式數據庫。
- AP without C:要高可用並允許分區,則需放棄一致性。一旦分區發生,節點之間可能會失去聯繫,爲了高可用,每個節點只能用本地數據提供服務,而這樣會導致全局數據的不一致性。典型的應用就如某米的搶購手機場景,可能前幾秒你瀏覽商品的時候頁面提示是有庫存的,當你選擇完商品準備下單的時候,系統提示你下單失敗,商品已售完。這其實就是先在 A(可用性)方面保證系統可以正常的服務,然後在數據的一致性方面做了些犧牲,雖然多少會影響一些用戶體驗,但也不至於造成用戶購物流程的嚴重阻塞。
2.2、AFK 拆分原則
業界對於可擴展的系統架構設計有一個樸素的理念,就是:通過加機器可以解決容量和可用性問題(如果一臺不行就兩臺,兩臺不行就多臺)。
用個段子描述就是:世界上沒有什麼事是一頓燒烤解決不了的,如果有,那就兩頓。
這一理念在“雲計算”概念瘋狂流行的今天。得到了廣泛的認可。對於一個規模迅速增長的系統而言。容量和性能問題當然是首當其衝的。但是隨着時間的向前,系統規模的增長,除了面對性能與容量的問題外,還需要面對功能與模塊數量上增長帶來的系統複雜性問題。以及業務變化帶來的提供差異化服務問題。而許多系統在架構設計時並未充分考慮到這些問題,導致系統的重構成爲常態。從而影響業務交付能力,還浪費人力財力。對此《The Art of Scalability》一書提出了一個更加系統的可擴展模型—AKF 可擴展立方,這個立方體中沿着三個座標軸設置分別爲 X,Y,Z。理論上按照這三個擴展模式,可以將一個單體系統,進行無限擴展。
- X 軸:指的是水平復制,很好理解,就是講單體系統多運行幾個實例,成爲集羣加負載均衡的模式。
- Y 軸:就是我們所說的微服務的拆分模式,就是基於不同的業務拆分。
- Z 軸:是基於類似的數據分區,比如一個互聯網打車應用突然火了,用戶量激增,集羣模式撐不住了,那就按照用戶請求的地區進行數據分區,北京、上海、四川等多建幾個集羣。
場景說明:比如打車應用,一個集羣撐不住時,分了多個集羣,後來用戶激增還是不夠用,經過分析發現是乘客和車主訪問量很大,就將打車應用拆成了三個,分別爲乘客服務、車主服務、支付服務。三個服務的業務特點各不相同,獨立維護,各自都可以再次按需擴展。
2.3、前後端分離原則
- 前後端技術分離,可以由各自的專家來對各自的領域進行優化,這樣前端的用戶體驗優化效果更好。
- 前後端分離模式下,前後端交互界面更清晰,就剩下了接口模型,後端的接口簡潔明瞭,更容易維護。
- 前端多渠道集成場景更容易實現,後端服務無需變更,採用統一的數據和模型,可以支持多個前端:例如:微信小程序、PC 前端、Android 前端、IOS 前端。
2.4、無狀態服務原則
對於無狀態服務,首先說一下什麼是狀態:如果一個數據需要被多個服務共享,才能完成一筆交易,那麼這個數據被稱爲狀態。進而依賴這個“狀態”數據的服務被稱爲有狀態服務,反之稱爲無狀態服務。那麼這個無狀態服務原則並不是說在微服務架構裏就不允許存在狀態,表達的真實意思是要把有狀態的業務服務改變爲無狀態的計算類服務,那麼狀態數據也就相應的遷移到對應的“有狀態數據服務”中。場景說明:例如我們以前在本地內存中建立的數據緩存、Session 緩存,到現在的微服務架構中就應該把這些數據遷移到分佈式緩存中存儲,讓業務服務變成一個無狀態的計算節點。遷移後,就可以做到按需動態伸縮,微服務應用在運行時動態增刪節點,就不再需要考慮緩存數據如何同步的問題。
2.5、Restful通信風格
基於**“無狀態服務原則”**,在這裏我們直接推薦一個實踐優選的 Restful 通信風格 ,因爲他有很多好處:
- 無狀態協議 HTTP,具備先天優勢,擴展能力很強。例如需要安全加密時,有現成的成熟方案 HTTPS 可用。
- JSON 報文序列化,輕量簡單,人與機器均可讀,學習成本低,搜索引擎友好。
- 語言無關,各大熱門語言都提供成熟的 Restful API 框架,相對其他的一些 RPC 框架生態更完善。
第三章 Spring Cloud介紹
Spring Cloud 是一個服務治理平臺,提供了一些服務框架。包含了:服務註冊與發現、配置中心、消息中心 、負載均衡、數據監控等等。
Spring Cloud 是一個微服務框架,相比 Dubbo 等 RPC 框架,Spring Cloud 提供了全套的分佈式系統解決方案。
Spring Cloud 對微服務基礎框架 Netflix 的多個開源組件進行了封裝,同時又實現了和雲端平臺以及 Spring Boot 框架的集成。
Spring Cloud 是一個基於 Spring Boot 實現的雲應用開發工具,它爲開發中的配置管理、服務發現、斷路器、智能路由、微代理、控制總線、全局鎖、決策競選、分佈式會話和集羣狀態管理等操作提供了一種簡單的開發方式。
Spring Cloud 爲開發者提供了快速構建分佈式系統的工具,開發者可以快速的啓動服務或構建應用、同時能夠快速和雲平臺資源進行對接。微服務是可以獨立部署、水平擴展、獨立訪問(或者有獨立的數據庫)的服務單元,Spring Cloud 就是這些微服務的大管家,採用了微服務這種架構之後,項目的數量會非常多,Spring Cloud 做爲大管家需要管理好這些微服務,自然需要很多小弟(組件)來幫忙。
第四章 Spring Cloud組件介紹
4.1、第一代微服務
Netflix是一家美國公司,在美國、加拿大提供互聯網隨選流媒體播放,定製DVD、藍光光碟在線出租業務。該公司成立於1997年,總部位於加利福尼亞州洛斯蓋圖,1999年開始訂閱服務。2009年,該公司可提供多達10萬部DVD電影,並有1千萬的訂戶。2007年2月25日,Netflix宣佈已經售出第10億份DVD。HIS一份報告中表示,2011年Netflix網絡電影銷量佔據美國用戶在線電影總銷量的45%。針對多種 Netflix 組件提供的開發工具包,其中包括 Eureka、Hystrix、Ribbon、Zuul、Archaius 等。
官方地址:https://github.com/spring-cloud/spring-cloud-netflix
Netflix Eureka
:一個基於 Rest 服務的服務治理組件,包括服務註冊中心、服務註冊與服務發現機制的實現,實現了雲端負載均衡和中間層服務器的故障轉移。Netflix Hystrix
:容錯管理工具,實現斷路器模式,通過控制服務的節點,從而對延遲和故障提供更強大的容錯能力。Netflix Ribbon
:客戶端負載均衡的服務調用組件。Netflix Feign
:基於 Ribbon 和 Hystrix 的聲明式服務調用組件。Netflix Zuul
:微服務網關,提供動態路由,訪問過濾等服務。Netflix Archaius
:配置管理 API,包含一系列配置管理 API,提供動態類型化屬性、線程安全配置操作、輪詢框架、回調機制等功能。
4.2、第二代微服務
Spring Cloud Alibaba 致力於提供微服務開發的一站式解決方案。此項目包含開發分佈式應用微服務的必需組件,方便開發者通過 Spring Cloud 編程模型輕鬆使用這些組件來開發分佈式應用服務。依託 Spring Cloud Alibaba,只需要添加一些註解和少量配置,就可以將 Spring Cloud 應用接入阿里微服務解決方案,通過阿里中間件來迅速搭建分佈式應用系統。
官方地址:https://github.com/alibaba/spring-cloud-alibaba
Sentinel
:把流量作爲切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。Nacos
:一個更易於構建雲原生應用的動態服務發現、配置管理和服務管理平臺。RocketMQ
:一款開源的分佈式消息系統,基於高可用分佈式集羣技術,提供低延時的、高可靠的消息發佈與訂閱服務。Dubbo
:Apache Dubbo™ 是一款高性能 Java RPC 框架。Seata
:阿里巴巴開源產品,一個易於使用的高性能微服務分佈式事務解決方案。Alibaba Cloud OSS
: 阿里雲對象存儲服務(Object Storage Service,簡稱 OSS),是阿里雲提供的海量、安全、低成本、高可靠的雲存儲服務。您可以在任何應用、任何時間、任何地點存儲和訪問任意類型的數據。Alibaba Cloud SchedulerX
: 阿里中間件團隊開發的一款分佈式任務調度產品,提供秒級、精準、高可靠、高可用的定時(基於 Cron 表達式)任務調度服務。Alibaba Cloud SMS
: 覆蓋全球的短信服務,友好、高效、智能的互聯化通訊能力,幫助企業迅速搭建客戶觸達通道。
第五章 Spring Cloud版本介紹
5.1、版本歷史
採用倫敦的地鐵站名稱來作爲版本號的命名,根據首字母排序,字母順序靠後的版本號越大。
注意:以下數據截至到2021-01-31號之前。
5.2、版本說明
發佈計劃:
標識 | 含義 | 說明 |
---|---|---|
BUILD-XXX | 開發版 | 開發團隊內部使用 |
M | 里程碑版 | MileStone,M1 表示第 1 個里程碑版本,一般同時標註 PRE,表示預覽版 |
RC | 候選發佈版 | Release Candidate,正式發佈版的前一個觀察期,不添加新功能,主要着重於除錯 |
SR | 正式發佈版 | Service Release,SR1 表示第 1 個正式版本,一般同時標註 GA,表示穩定版本 |
GA | 穩定版 | 經過全面測試並可對外發行稱之爲GA(General Availability) |
各版本號:
例如:Spring Cloud Alibaba 2.1.0.RELEASE
- 2:主版本號。當功能模塊有較大更新或者整體架構發生變化時,主版本號會更新。
- 1:次版本號。次版本表示只是局部的一些變動。
- 0:修改版本號。一般是 bug 的修復或者是小的變動。
- RELEASE:希臘字母版本號。標註當前版本的軟件處於哪個開發階段。
希臘字母:
- Base:設計階段。只有相應的設計沒有具體的功能實現。
- Alpha:軟件的初級版本。存在較多的 bug。
- Bate:表示相對 Alpha 有了很大的進步,消除了嚴重的 bug,還存在一些潛在的 bug。
- Gamma:是 Beta 版做過一些修改,成爲正式發佈的候選版本(Release Candidate)。
- Release:該版本表示最終版。
第六章 Spring Cloud版本要求
查看地址:https://start.spring.io/actuator/info
6.1、Spring Cloud
具體版本要求地址:https://docs.spring.io/spring-cloud/docs/Hoxton.SR9/reference/html/
注意:maven建議使用3.6.3,jdk應該保持1.8及以上。
6.2、Spring Cloud Alibaba
具體版本要求地址:https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
注意:maven建議使用3.6.3,jdk應該保持1.8及以上。
第七章 Spring Cloud開發準備
7.1、idea創建父工程
7.2、idea統一編碼集
7.3、idea註解的配置
7.4、idea排除的文件
*.hprof;*.pyc;*.pyo;*.rbc;*.yarb;*~;.DS_Store;.git;.hg;.svn;CVS;__pycache__;_svn;vssver.scc;vssver2.scc;*.idea;*.iml;
7.5、idea熱部署設置
按下 CTRL+ALT+SHITF+/
會彈出一個窗口,請點擊 Registry
。
注意:這一步設置完成以後,請重新啓動idea,爲了讓這些配置生效。
7.6、修改 POM 內容
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.caochenlei</groupId>
<artifactId>spring-cloud-study</artifactId>
<version>2021</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<!--spring boot 2.3.5.RELEASE-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud Hoxton.SR9-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>