SpringCloud入門及建立分散式專案

CodeTiger發表於2021-06-30

1、瞭解微服務

1.1 什麼是微服務

  • 微服務是一種架構風格
  • 一個應用拆分為一組小型服務
  • 每個服務執行在自己的程式內,也就是可獨立部署和升級
  • 服務之間使用輕量級HTTP互動
  • 服務圍繞業務功能拆分
  • 可以由全自動部署機制獨立部署
  • 去中心化,服務自治。服務可以使用不同的語言、不同的儲存技術

1.2 微服務架構

  • 服務呼叫
  • 服務降級
  • 服務註冊與發先
  • 服務熔斷
  • 負載均衡
  • 服務訊息佇列
  • 服務閘道器
  • 配置中心管理
  • 自動化構建部署
  • 服務監控
  • 全鏈路追蹤
  • 服務定時任務
  • 排程操作

2、瞭解SpringCloud

2.1 SpringCloud是什麼

SpringCloud是分散式微服務架構的站式解決方案,是多種微服務架構落地技術的集合體,俗稱微服務全家桶

官方文件:https://spring.io/projects/spring-cloud

Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state). ---摘自官網

根據官方對SpringCloud的描述,SpringCloud提供了一系列工具,能夠讓開發者快速的構建分散式系統。所以SpringCloud並不是一個新技術,只是整合了一些常用的技術進行封裝,然後結合SpringBoot,我們就可以快速構建分散式專案。

SpringCloud包含了很多的技術,看官網的目錄就知道了,一個螢幕都截不全。往往一個技術還沒學會就告訴我已經不用了,特喵的。

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

2.2 SpringCloud停更元件和替換

SpringCloud的Hoxton版本,和之前的版本相比,用新的元件替換掉了原來大部分的元件,老的元件現在處於 停更不停用 的狀況。

詳情見下圖(× 的表示之前的元件,現在停更了的; 的表示新的替換後的元件):

在這裡插入圖片描述

服務註冊中心

Eureka:官方停止更新,並且已經有更好的替代產品了,可以使用,但是官方已經不建議使用了。

Zookeeper:某些老系統,以前是用的Zookeeper + Dubbo,後來做技術升級,結果發現SpringCloud的Eureka停更了,然後就用了最少的技術切換,那麼就用了Zookeeper做註冊中心。

Consul:go語言開發的,也是一個優秀的服務註冊框架,但是使用量較少,風頭都被Nacos搶了。

Nacos:來自於SpringCloudAlibaba,在企業中經過了百萬級註冊考驗的,不但可以完美替換Eureka,還能做其他元件的替換,所以強烈建議使用,是學習的重點。

服務呼叫

Ribbon:也進入了維護狀態,停止更新了,但是Spring官方還在使用。

LoadBalancer:Spring官方推出的一個新的元件,打算逐漸取代掉Ribbon,但是現在還處於萌芽狀態。

服務呼叫2

Feign:Netflix 公司產品,也停止更新了。

OpenFeign:Spring社群等不了Netflix更新了,然後就自己做了一個元件,不用Feign了。

服務降級

Hystrix:官網不推薦使用,但是中國企業中還在大規模使用。

Resilience4J:官網推薦使用,但是國內很少用這個。

Sentienl:來自於SpringCloudAlibaba,在中國企業替換Hystrix的元件,國內強烈建議使用。

服務閘道器

Zuul:Netflix 公司產品,公司內部產生分歧,有的人想自己出一個Zuul2。

Zuul2:也是Netflix 公司準備出的產品,但是由於內部分歧,所以Zuul2已經胎死腹中了。

gateway:Spring社群自己出的閘道器元件,官方隆重介紹和極度推薦的閘道器服務元件。

服務配置

Config:目前也在使用,風頭被Nacos搶了。

Nacos:來自於SpringCloudAlibaba,後來居上,把Config給替換了。

服務匯流排

Bus:SpringCloud原生的服務匯流排元件,現在風頭也被Nacos搶了。

Nacos:來自於SpringCloudAlibaba,後來居上,把Bus給替換了。


綜上可以看出,Nacos 是重中之重,一個元件就替換掉了原來的幾個元件。

3、建立分散式專案

分散式專案和單體專案不一樣,一般都會分為多個模組,構成父工程子工程的關係。一般單個SpringBoot專案,pom檔案總是有這麼一段

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

父專案指定為SringBoot某個版本,後續使用相關的jar包都繼承父專案指定的版本資訊。

下面來新建一個分散式專案的父工程

3.1 建立父工程

建立微服務cloud整體聚合父工程Project,有8個關鍵步驟:

(1)New Project - maven工程
(2)聚合總父工程名字
(3)Maven選版本
(4)工程名字
(5)字元編碼 - Settings - File encoding
(6)註解生效啟用 - Settings - Annotation Processors
(7)Java編譯版本選8
(8)File Type過濾 - Settings - File Type

在這裡插入圖片描述

建立完後,可以把src目錄刪除,因為父工程不需要,刪除後變成了下面這樣

在這裡插入圖片描述

然後需要修改pom.xml檔案,注意看註釋

<?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.codeliu</groupId>
    <artifactId>springcloud-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--父工程的打包方式必須為pom-->
    <packaging>pom</packaging>

    <!--統一管理jar包版本號-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.16.18</lombok.version>
        <mysql.version>8.0.11</mysql.version>
        <druid.version>1.1.16</druid.version>
        <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
    </properties>

    <!--宣告依賴jar包和指定版本,並不實現引入,由子專案進行引入,子專案如果不指定版本則使用父專案申明的版本,也可以指定版本進行覆蓋-->
    <dependencyManagement>
        <dependencies>
            <!--spring boot 2.2.2-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud Hoxton.SR1-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud alibaba 2.1.0.RELEASE-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </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>

關於dependencyManagementdependencies,Maven使用dependencyManagement元素來管理依賴版本號。通常會在一個組織或者專案的最頂層的父POM中看到dependencyManagement元素。

使用pom.xml中的dependencyManagement元素能讓所有子專案中引用依賴而不用顯式的列出版本號。

Maven會沿著父子層次向上走,直到找到一個擁有dependencyManagement元素的專案,然後它就會使用這個
dependencyManagement元素中指定的版本號。

比如在父專案中宣告瞭資料庫驅動的jar

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.11</version>
</dependency>

那麼在子專案中,就不需要指定版本號了

<dependency>
    <groupId>mysq1</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

這樣做的好處就是:如果有多個子專案都引用同一樣依賴,則可以避免在每個使用的子專案裡都宣告一個版本號,這樣當想升級或切換到另一個版本時,只需要在頂層父容器裡更新,而不需要一個一個子專案的修改;另外如果某個子專案需要另外的一個版本,只需要宣告version即可。

dependencyManagement裡只是宣告依賴,並不實現引入,因此子專案需要顯示的宣告需要用的依賴。如果不在子專案中宣告依賴,是不會從父專案中繼承下來的;只有在子專案中寫了該依賴項,並且沒有指定具體版本,才會從父專案中繼承該項,並且version和scope都讀取自父pom。

如果子專案中指定了版本號,那麼會使用子專案中指定的jar版本。

另外關於springcloud的版本號,指定的是Hoxton.SR1,這也是有說法的。具體可以參考:https://juejin.cn/post/6844903922511904776

3.2 建立子專案

在父工程上右鍵新建

在這裡插入圖片描述

我們的子專案是什麼型別的就建什麼型別的,這裡新建一個SpringBoot專案,填寫相關資訊

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

建立完成後的目錄結構如下

在這裡插入圖片描述

然後我們需要修改父專案和子專案的pom檔案進行關聯

在這裡插入圖片描述

建立其他的子專案都是一樣的步驟。

對於一些不需要服務啟動的子模組,比如common模組,那麼在新建後,可以刪除啟動類及相關的測試資料夾。

在子專案中如果要互相引用,比如某個子模組要引入cloud-provider-payment模組,直接在pom檔案中進行指定即可

<dependency>
    <groupId>com.codeliu</groupId>
    <artifactId>cloud-provider-payment</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

參考

相關文章