SpringCloud (一) 微服務入門
SpringCloud 是目前主流的 Java 開發框架,平時一直在用 SpringCloud 開發專案,所以花點時間把 SpringCloud 相關知識整理一下,沒有其他目的就是喜歡。
不要求寫的有多好,但是別留坑!
環境說明
以下所有的 SpringCloud 專案均基於以下環境:
- Jdk版本:1.8
- maven版本:3.6.0
- 開發工具:idea 2019.3.3 版本
SpringCloud 是什麼?
SpringCloud 是一系列框架的有序集合。它利用 SpringBoot 的開發便利性巧妙地簡化了分散式系統基礎設施的開發,如服務發現註冊、配置中心、訊息匯流排、負載均衡、斷路器、資料監控等,都可以用 SpringBoot 的開發風格做到一鍵啟動和部署。Spring並沒有重複製造輪子,它只是將目前各家公司開發的比較成熟、經得起實際考驗的服務框架組合起來,通過 SpringBoot 風格進行再封裝遮蔽掉了複雜的配置和實現原理,最終給開發者留出了一套簡單易懂、易部署和易維護的分散式系統開發工具包。
微服務是可以獨立部署、水平擴充套件、獨立訪問(或者有獨立的資料庫)的服務單元,SpringCloud 就是這些微服務的大管家,採用了微服務這種架構之後,專案的數量會非常多,SpringCloud 做為大管家就需要提供各種方案來維護整個生態。
SpringCloud 就是一套分散式服務治理的框架,既然它是一套服務治理的框架,那麼它本身不會提供具體功能性的操作,更專注於服務之間的通訊、熔斷、監控等。
使用 SpringCloud 開發專案,必須認同它的開發理念和思想,SpringCloud 本身並不是一款框架,而是基於 SpringBoot 的一系列微服務框架的集合,SpringCloud 中最重要的就是整合一系列元件實現 服務呼叫、熔斷降級、監控等功能
SpringCloud 搭建架構
這是一張比較完整的 SpringCloud 分散式服務架構圖,從上到下分析一下:
1、首先客戶端通過域名訪問服務端,通過 DNS + Nginx 實現服務端負載均衡方式對外提供服務
2、然後到達服務閘道器叢集,服務閘道器叢集對請求進行一些 鑑權、限流、路由轉發 等進一步處理,過濾掉一些無效請求,保證服務高可用
3、業務服務進行叢集部署,處理業務請求
4、提供一些中介軟體處理資料和服務呼叫,例如 訊息中介軟體、大資料中介軟體 等
5、在資料庫層提供 Mysql叢集、Redis叢集、MQ叢集等,保障資料儲存和效能
6、SpingCloud 搭建的分散式微服務,擴充套件以後往往是龐大的,為了保證服務的高可用和效能,SpringCloud 提供註冊中心進行服務治理,提供配置中心對配置進行統一管理和動態修改,提供鏈路追蹤對呼叫鏈路進行分析發現耗時服務,提供熔斷降級防止因為某些微服務不可用導致整個系統雪崩
SpringCloud 專案搭建
前面我們介紹了 SringCloud 是什麼
、SpringCloud 專案架構
,下面帶大家搭建使用 SpringCloud 作為專案架構的分散式系統,後面的一系列課程都是基於這個專案。
準備工作
開發工具
IDEA 2019.3.3 版本
SpringCloud 和 SpringBoot 版本依賴說明
在搭建SpringCloud專案時,由於其基於SpringBoot所以兩者版本依賴關係必須要了解。
瞭解的途徑:https://spring.io/projects/spring-cloud
開啟上面的地址,然後往下翻,或者 Ctrl + F 然後搜尋 Release Trains
,就能看到 SpringCloud 和 SpringBoot 版本依賴關係了
搭建父工程
1、建立專案
使用 idea 工具可以很方便的建立 Spring project,首先進入 New Project 介面,選擇 Spring Initiallizr
點選 Next
完成後,繼續 Next
然後選擇程式碼的存放位置
使用 idea 工具建立 project,由於我們的專案使用 maven 進行依賴管理,所以這裡選擇 Maven
2、修改 pom
以下檔案是修改後的,並對位置做了一些調整,其中包含:
1、統一管理jar包版本
2、統一依賴管理
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gorun</groupId>
<artifactId>cloud2020</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cloud2020</name>
<packaging>pom</packaging>
<!-- 統一管理jar包版本 -->
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.1.RELEASE</spring-boot.version>
<spring-cloud.version>Greenwich.SR6</spring-cloud.version>
</properties>
<!-- 子模組繼承之後,提供作用:鎖定版本+子modlue不用寫groupId和version -->
<dependencyManagement>
<dependencies>
<!-- spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
搭建子module
接下來我們新建一個基於 Eureka 註冊中心的服務端
1、建立 module
此時建立的專案是這樣的,和我們的父工程沒有關係
2、修改 pom
修改父工程pom,將剛才新建的子module 納入管理
修改子module pom,修改點如下
1、將parent替換為父工程
2、刪除無用的依賴管理,外掛管理
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.gorun</groupId>
<artifactId>cloud2020</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>cloud-eureka-server-8761</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
3、修改 application.properties
由於我們的子module是搭建 Eureka Server,為了專案可以正常啟動,需要修改 application.propertes 檔案,修改 Eureka 相關配置
server.port=8761
eureka.instance.hostname=localhost
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
spring.application.name=eureka-server
4、主啟動類新增 @EnableEurekaServer 註解
5、測試
啟動專案,訪問 http://localhost:8761/
SpringCloud 元件及功能介紹
Spring Cloud 新舊元件一覽
SpringCloud 整合了目前各家公司開發的比較成熟、經得起實際考驗的服務框架,經過進一步的封裝,納入了 SpringCloud 社群形成各種元件。其中某些元件已經停止更新維護了,大家要對這些有一定的瞭解,在專案中謹慎使用,當然 SpringCloud 也提供了更好的替代者,如下圖所示:
Spring Cloud Netflix
簡單介紹
Spring Cloud Netflix通過自動配置並繫結到Spring Environment和其他Spring程式設計模型習慣用法,為Spring Boot應用程式提供Netflix OSS整合。使用一些簡單的批註,您可以快速啟用和配置應用程式內部的通用模式,並使用經過測試的Netflix元件構建大型分散式系統。提供的模式包括服務發現(Eureka),斷路器(Hystrix),智慧路由(Zuul)和客戶端負載平衡(Ribbon)。
特性
Spring Cloud Netflix功能:
- 服務發現:可以註冊Eureka例項,並且客戶端可以使用Spring託管的Bean發現例項
- 服務發現:可以使用宣告性Java配置建立嵌入式Eureka伺服器
- 斷路器:Hystrix客戶端可以使用簡單的註釋驅動的方法裝飾器構建
- 斷路器:具有宣告性Java配置的嵌入式Hystrix儀表板
- 宣告式REST客戶端:Feign建立一個用JAX-RS或Spring MVC註釋修飾的介面的動態實現。
- 客戶端負載均衡器:功能區
- 外部配置:從Spring Environment到Archaius的橋樑(使用Spring Boot約定啟用Netflix元件的本機配置)
- 路由器和過濾器:Zuul過濾器的自動註冊,以及用於反向代理建立的簡單配置約定
Spring Cloud Alibaba
簡單介紹
Spring Cloud Alibaba為分散式應用程式開發提供了一站式解決方案。它包含開發分散式應用程式所需的所有元件,使您可以輕鬆地使用Spring Cloud開發應用程式。
使用Spring Cloud Alibaba,您只需要新增一些註釋和少量配置即可將Spring Cloud應用程式連線到Alibaba的分散式解決方案,並使用Alibaba中介軟體構建分散式應用程式系統。
特性
- 流量控制和服務降級:使用阿里巴巴Sentinel進行流量控制,斷路和系統自適應保護
- 服務註冊和發現:例項可以在Alibaba Nacos上註冊,客戶可以使用Spring管理的bean發現例項。通過Spring Cloud Netflix支援Ribbon,客戶端負載均衡器
- 分散式配置:使用阿里巴巴Nacos作為資料儲存
- 事件驅動:構建與Spring Cloud Stream RocketMQ Binder 連線的高度可擴充套件的事件驅動微服務
- 訊息匯流排:使用Spring Cloud Bus RocketMQ連結分散式系統的節點
- 分散式事務:支援高效能且易於使用的Seata分散式事務解決方案
- Dubbo RPC:通過Apache Dubbo RPC擴充套件Spring Cloud服務間呼叫的通訊協議
如何使用
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>{project-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Spring Cloud Security
簡單介紹
Spring Cloud Security提供了一組原語,用於以最少的麻煩構建安全的應用程式和服務。可以在外部(或中央)進行大量配置的宣告式模型通常可以通過中央身份管理服務來實現大型的,相互協作的遠端元件系統。在Cloud Foundry等服務平臺中使用它也非常容易。在Spring Boot和Spring Security OAuth2的基礎上,我們可以快速建立實現常見模式(如單點登入,令牌中繼和令牌交換)的系統。
如何使用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
Spring Cloud Stream
簡單介紹
Spring Cloud Stream是一個框架,用於構建與共享訊息傳遞系統連線的高度可擴充套件的事件驅動型微服務。
該框架提供了一個靈活的程式設計模型,該模型建立在已經建立並熟悉的Spring習慣用法和最佳實踐的基礎上,包括對永續性pub / sub語義,使用者組和有狀態分割槽的支援。
如何使用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
Spring Cloud Gateway
簡單介紹
Spring Cloud Gateway 提供了一個用於在Spring MVC之上構建API閘道器的庫。Spring Cloud Gateway旨在提供一種簡單而有效的方法來路由到API,併為它們提供跨領域的關注,例如:安全性,監視/指標和彈性。
如何使用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
Spring Cloud OpenFeign
簡單介紹
Spring Cloud OpenFeign以將OpenFeign整合到Spring Boot應用中的方式,為微服務架構下服務之間的呼叫提供瞭解決方案。首先,利用了OpenFeign的宣告式方式定義Web服務客戶端;其次還更進一步,通過整合Ribbon或Eureka實現負載均衡的HTTP客戶端。
如何使用
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign</artifactId>
<version>2.0.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>