Spring Cloud alibaba


1.引言

目前Spring Cloud進入了維護模式,而Spring Cloud alibaba對Spring Cloud做了封裝,使用起來更簡單。包含的功能有服務限流降級、服務注冊於發現、分布式配置管理、消息驅動能力、阿里雲對象存儲、分布式任務調度等。

參考文檔:

https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html

源代碼:https://github.com/zhongyushi-git/spring-cloud-alibaba-demo.git

2.Nacos

一個更易於構建雲原生應用的動態服務發現、配置管理和服務管理平台。是注冊中心與配置中心的組合。官網:https://nacos.io/zh-cn/index.html

2.1下載

打開https://github.com/alibaba/nacos/releases下載需要的版本,這里以1.1.4版本為例說明。

2.2安裝

2.2.1在windows系統安裝

下載壓縮包后解壓即可使用。進入bin目錄,雙擊startup.cmd看到下圖說明運行成功。

默認是以集群方式啟動,若啟動報錯,那么需要修改為單機版啟動,在bin目錄打開cmd,輸入下面的命令進行啟動。

startup.cmd -m standalone

訪問http://localhost:8848/nacos,登錄用戶名和密碼都是nacos。登錄之后的頁面如下,可以看到相關想信息。

2.2.2在Linux系統安裝

把下載好的壓縮上傳制到Linux后解壓

tar -zxvf nacos-server-1.1.4.tar.gz -C /usr/local

解壓之后單機版啟動,啟動之后在瀏覽器訪問nacos首頁,同上。

bash startup.sh -m standalone

2.3基礎環境搭建

創建maven的父工程spring-cloud-alibaba-demo,刪除src目錄。導入依賴,進行版本鎖定

    <!--統一管理jar包版本-->
    <properties>
        <spring.boot.version>2.2.2.RELEASE</spring.boot.version>
        <spring.cloud.alibaba.version>2.2.0.RELEASE</spring.cloud.alibaba.version>
        <spring.cloud.version>Hoxton.SR1</spring.cloud.version>
    </properties>

    <!--  依賴管理,父工程鎖定版本-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring.cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <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>

2.4服務注冊

1)創建服務提供者子模塊cloud-alibaba-provider8001,導入依賴

   <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--springcloud alibaba nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

2)application.yml配置

server:
  port: 8001

spring:
  application:
    name: cloud-alibaba-nacos-provider
  cloud:
    #配置nacos地址
    nacos:
      #服務器地址
      server-addr: 127.0.0.1:8848
      #服務注冊與發現地址
      discovery:
        server-addr: ${spring.cloud.nacos.server-addr}

#開啟端口暴露
management:
  endpoints:
    web:
      exposure:
        include: "*"

3)創建啟動類

package com.zys.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(NacosProviderMain8001.class,args);
    }
}

4)創建controller接口

package com.zys.cloud.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/user/get")
    public String get() {
        return "provider port is :" + port;
    }
}

5)啟動服務提供者,在nacos頁面的服務列表中可以看到服務已注冊進來。那么此時服務的注冊就已完成,非常簡單。

6)同理,按照cloud-alibaba-provider8001方式創建服務提供者子模塊cloud-alibaba-provider8002,端口為8002。啟動后發現nacos中服務的集群數目變成了2。

2.5服務調用

nacos並不提供服務調用的方法,因此還需要使用SpringCloud的方式進行調用,這里使用OpenFeign進行說明(關於OpenFeign的用法其他文章已介紹)。

1)創建服務消費者子模塊cloud-alibaba-consumer80,導入依賴

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--springcloud alibaba nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

2)application.yml配置

server:
  port: 80

spring:
  application:
    name: cloud-alibaba-nacos-consumer
  cloud:
    #配置nacos地址
    nacos:
      #服務器地址
      server-addr: 127.0.0.1:8848
      #服務注冊與發現地址
      discovery:
        server-addr: ${spring.cloud.nacos.server-addr}


feign:
  client:
    config:
      #指定全局
      default:
        #連接超時時間
        connectTimeout: 5000
        #服務等待時間
        readTimeout: 5000
        loggerLevel: full

logging:
  level:
    com.zys.cloud.client.UserClient: debug

雖然是調用別的服務,但也需要把自身服務注冊到nacos.

3)創建啟動類

package com.zys.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerMain80 {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerMain80.class, args);
    }
}

4)創建Client接口,用於接口映射

package com.zys.cloud.client;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(value = "cloud-alibaba-nacos-provider")
public interface UserClient {

    @GetMapping("/user/get")
    String get();
}

5)創建controller接口

package com.zys.cloud.controller;

import com.zys.cloud.client.UserClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/consumer")
public class UserController {

    @Autowired
    private UserClient userClient;

    @GetMapping("/get")
    public String get() {
        return userClient.get();
    }
}

6)啟動服務,可以在nacos頁面的服務列表中看到兩個注冊的服務。

訪問http://localhost/consumer/get,看到是8001和8002進行輪詢負載的。是因為nacos默認支持負載均衡,原因是它默認引入了ribbon。

2.6服務配置

2.6.1基本配置

為了不改動上述的代碼,這里新建一個模塊說明服務的配置,原理是一樣的。

1)創建配置的客戶端子模塊cloud-alibaba-config-client,導入依賴

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--springcloud alibaba nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
    </dependencies>

這里同時引入了服務注冊和服務配置的依賴。作為客戶端,當然需要注冊到nacos,而配置又是此服務必不可少的。

2)yml配置

bootstrap.yml:系統級別的配置,主要配置配置中心的相關信息。

spring:
  cloud:
    nacos:
      #服務器地址
      server-addr: 127.0.0.1:8848
      discovery:
        server-addr: ${spring.cloud.nacos.server-addr}
      config:
        #配置中心地址
        server-addr: ${spring.cloud.nacos.server-addr}
        #指定配置的格式,有yaml和properties兩種
        file-extension: yaml

application.yml:主要配置服務的名稱及激活的配置文件

spring:
  application:
    name: nacos-config-client
  profiles:
    active: dev

3)創建啟動類

package com.zys.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class NacosConfigClientMain {
    public static void main(String[] args) {
        SpringApplication.run(NacosConfigClientMain.class,args);
    }
}

4)創建controller接口

package com.zys.cloud.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
//動態刷新
@RefreshScope
public class UserController {

    @Value("${config.info}")
    private String info;

    @GetMapping("/config/get")
    public String get() {
        return "The config info is :" + info;
    }
}

需要注意的是,這里在類上加了@RefreshScope注解,用於自動刷新。若不添加,則無法進行自動的配置刷新。

5)創建統一的配置文件

在創建之前,先了解一些dataID的命名規則,它的完整格式為${prefix}-${spring.profile.active}.${file-extension}。

prefix :默認為 spring.application.name 的值,也可以通過配置項 spring.cloud.nacos.config.prefix來配置。
spring.profile.active :即為當前環境對應的 profile。
file-exetension: 為配置內容的數據格式,可以通過配置項 spring.cloud.nacos.config.file-extension 來配置。目前只支持 properties 和 yaml 類型。

假如spring.application.name=nacos-config-client,環境為dev,后綴名是yaml,那么dataID就是nacos-config-client-dev.yaml。這里不存在主/從配置文件的說法,只指定不同環境的配置,公共的配置都放在自己的環境中。另外,dataId后綴必須是yaml或properties。

了解之后,就在nacos的配置管理頁面新建一個配置文件,然后發布。

配置代碼:

server:
    port: 3344

config:
    info: '我的名字叫張三'

 6)測試

啟動3344,訪問http://localhost:3344/config/get,可以看到配置的信息。然后修改配置中的config.info內容,再刷新頁面,發現配置信息也更新了。此時就做到了配置實時刷新。

2.6.2分類配置

級別大小:namespace > Group > dataId。

1)dataId方案

一個dateId就是一個配置文件。在nacos頁面再創建一個配置文件,作為測試環境配置

修改application.yml的環境為test。

重啟后訪問http://localhost:3355/config/get,可以看到test環境的配置信息。

2)Group方案

在上述的章節中,並沒有去指定Group,而是采用的默認的名稱DEFAULT_GROUP,如果需要自定義分組名稱,則在創建配置時指定分組名即可,不過需要在bootstrap.yml在指定組名。

新建一個配置文件,分組名為GROUP_TEST

修改application.yml的環境為info,然后在bootstrap.yml指定組名

重啟后訪問http://localhost:3344/config/get,可以看到info環境的配置信息。

3)namespace方案

用於區分不同的部署環境,實現隔離。命名空間是最大的,需要設置的話就創建命名空間(id一般不指定,自動生成即可),在配置文件中指定創建的命名空間的id即可。

2.7持久化配置

nacos默認自帶的是嵌入式數據庫derby,持久化就需要切換到MySQL,MySQL版本5.7以上。

1)執行sql腳本

在下載的nacos文件夾中,nacos-server-1.1.4\nacos\conf\nacos-mysql.sql即是sql腳本,先創建一個名為nacos的數據庫,然后執行這個腳本即可。

2)修改配置文件

打開nacos-server-1.1.4\nacos\conf\application.properties,在最后添加

#增加支持mysql數據源配置
spring.datasource.platform=mysql

db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456

3)啟動測試

重啟nacos,發現之前配置的信息沒有了,原因是MySQL中並沒有進行配置。這時在nacos頁面創建一個名為nacos-config-client-info.yaml的配置文件如下:

啟動服務配置客戶端,訪問http://localhost:3344/config/get,可以看到info環境的配置信息。其配置信息在表config_info中可看到。

2.8集群配置

在搭建集群之前,默認在Linux已安裝完成nocas。另外,nginx單機版也在Linux搭建完成,用於負載均衡nacos服務,MySQL在Linux已安裝完成(MySQL版本5.7+)。

1)執行sql腳本(同上一小節)

2)配置nacos數據源,修改application.properties文件,在最后添加

#增加支持mysql數據源配置
spring.datasource.platform=mysql

db.num=1
db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456

3)獲取本機的ip

hostname -i

4)配置cluster.conf

打開文件

cp cluster.conf.example cluster.conf
vim cluster.conf

把內容修改如下:

172.16.68.248:8849
172.16.68.248:8850
172.16.68.248:8851

需要注意的是,這里的ip必須是上一步獲取的本機ip。

5)修改startup.sh啟動文件

vim startup.sh

修改的文件前后對比,主要添加了啟動的端口號

 

   

 6)啟動集群

./startup.sh -p 8849
./startup.sh -p 8850
./startup.sh -p 8851

在啟動的時候,遇到了一個大坑,就是安裝的jdk必須手動配置java_home,否則會報錯。

3.Sentinel

學習地址:https://github.com/alibaba/Sentinel/wiki/介紹

Sentinel主要從流量控制、熔斷降級、系統負載保護維度保護服務的穩定性。

3.1下載與安裝

1)下載地址https://github.com/alibaba/Sentinel/releases,選擇對應的版本下載即可。這里以1.8.2版本為例

可以下載壓縮包,也可以直接下載jar。本章節在Windows中說明,就直接下載jar進行說明。

2)下載到本地后,在其目錄下打開cmd,輸入命令

java -jar sentinel-dashboard-1.7.2.jar

3)在瀏覽器訪問http://localhost:8080,看到下面的頁面說明安裝成功。

用戶名和密碼都是sentinel。

4)登錄后看到儀表盤是空的,因為現在沒有監控任何的服務。

3.2初始化監控

為了不改動上述的代碼,這里新建一個模塊進行說明,原理是一樣的。

1)創建一個模塊cloud-alibaba-sentinel,導入依賴

      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--springcloud alibaba nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--springcloud alibaba sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

2)配置application.yml,簡單起見,配置文件在本地進行配置

server:
  port: 8401
spring:
  application:
    name: cloud-alibaba-sentinel-service
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      discovery:
        server-addr: ${spring.cloud.nacos.server-addr}
    sentinel:
      transport:
        # sentinel dashboard的地址
        dashboard: 127.0.0.1:8080
        # sentinel dashboard內部通信端口,默認為8719,如果被占用會自動+1,直到找到為止
        port: 8719

management:
  endpoints:
    web:
      exposure:
        include: "*"

3)創建啟動類

package com.zys.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class SentinelMain {
    public static void main(String[] args) {
        SpringApplication.run(SentinelMain.class, args);
    }
}

4)創建controller

package com.zys.cloud.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FlowLimitController {

    @GetMapping("/testA")
    public String testA(){
        return "--------testA";
    }

    @GetMapping("/testB")
    public String testB(){
        return "--------testB";
    }


}

5)測試。先啟動nacos服務,再啟動sentinel服務,再啟動8401。訪問http://localhost:8401/testA后會在儀表盤看到生成了一個服務:

將接口testA多調用幾次,再看儀表盤

其中QBS表示1秒的請求數,QPS表示1秒的拒絕請求數。

原理:只要服務加入了Sentienl並進行了配置,那么在調用服務時,就會通過內部通信服務把日志信息發送給dashboard服務,其在頁面上展示。因此只有的服務調用時dashboard才會進行初始化。

6)簇點鏈路

打開簇點鏈路的菜單,可以看到鏈路的信息,可操作的按鈕包含流控、熔斷、熱點和授權,后續一一介紹。

3.2流控

流控:流量控制(flow control),其原理是監控應用流量的QPS或並發線程數等指標,當達到指定的閾值時對流量進行控制,以避免被瞬時的流量高峰沖垮,從而保障應用的高可用性。

3.2.1閾值類型-QPS

QPS表示每秒的請求數。可在簇點鏈路中選擇鏈路的點擊流控按鈕添加,也可在流控規則中添加。其他的功能類似。這里以/testA的流控為例:

上圖的配置,也就是說對於請求/testA,當每秒請求的次數超過閾值,那么會直接返回失敗的信息。保存后顯示列表如下:

訪問localhost:8401/testA結果是正常的,若快速的刷新幾次,會發現返回了流控的信息:

對於針對來源,默認使用default,那么也可以指定來源,那么當指定的這個來源調用/testA請求時會進行流控,其他服務調用/testA時不進行流控,也就是對來源進行針對性的流控。

3.3.2閾值類型-並發線程數

當然也可設置並發線程的閾值,當某一時刻並發線程數量超過時會進行流控。

1)點擊編輯,將/testA的閾值類型修改並發線程數

2)使用Jmeter對/testA發送超過閾值的並發請求,那么在發送的同時再訪問/testA就會出現流控。

3.3.3 流控模式-關聯

1)說明:前面的兩種的流程模式都設置為直接,這種模式是默認的,也就是說流量控制規則到達閾值時直接觸發流量控制。本小節說明關聯模式,均以QPS類型說明,后同。

2)關聯:當兩個資源之間具有資源爭搶或者依賴關系的時候,這兩個資源便具有了關聯。比如對數據庫同一個字段的讀操作和寫操作存在爭搶,讀的速度過高會影響寫得速度,寫的速度過高會影響讀的速度。如果放任讀寫操作爭搶資源,則爭搶本身帶來的開銷會降低整體的吞吐量。關聯的關系是反向關聯。

3)上述代碼中的/testA和/testB就是關聯關系,它們在同一個controller中,占用相同的資源,編輯配置如下:

使用Jmeter對/testB發送超過閾值的並發請求,那么在發送的同時再訪問/testA就會出現流控。原因是兩個請求相互爭搶資源,進行了流控。

3.3.3 流控模式-鏈路

鏈路模式也就是對某一條鏈路進行流控。如用戶服務會調用訂單服務,商品服務也會調用訂單服務,就存在兩條鏈路。在某個時刻,對商品服務->訂單服務這條鏈路進行流控,從而保證訂單服務的正常使用,最終讓用戶服務可以正常調用訂單服務,雖然限流了商品服務這條鏈路,但不影響用戶服務這條鏈路。

3.3.4流控效果-快速失敗

默認的流量控制方式,當QPS超過任意規則的閾值后,新的請求就會被立即拒絕,拒絕方式為拋出FlowException 。前面已經使用過多次。

3.3.5流控效果-Warm Up

預熱/冷啟動方式。當系統長期處於低水位的情況下,當流量突然增加時,直接把系統拉升到高水位可能瞬間把系統壓垮。通過"冷啟動",讓通過的流量緩慢增加,在一定時間內逐漸增加到閾值上限,給冷系統一個預熱的時間,避免冷系統被壓垮。它有一個冷加載因子,值是3。曲線圖如下:

新加/testA的流控規則如下:

當1秒同時有20個請求,預熱時間是10秒。那么服務會先處理7個請求(20/3),后面依次處理,當達到20秒時處理完所有的請求。

3.3.6流控效果-排隊等待

讓請求以均勻的速度通過。修改/testA的規則:

也就是說,當有大量的請求來時,每秒只處理20個請求,其他的請求進行排隊等待,依次類推。當后面排隊的時間超過5秒時就報錯,顯示流控信息。

3.3熔斷降級

一個服務常常會調用別的模塊,如果依賴的服務出現了不穩定的情況,請求的響應時間變長,那么調用服務的方法的響應時間也會變長,線程會產生堆積,最終可能耗盡業務自身的線程池,服務本身也變得不可用。而Sentinel在服務出現不穩定情況時,會對其進行限制,請求快速失敗,避免影響到其他資源而導致級聯錯誤。當資源被降級后,在接下來的時間窗口內,對該資源的調用都自動熔斷。

3.3.1降級策略

(1)慢調用比例:當單位統計時長內請求數目大於設置的最小請求數目,並且平均響應時間超過最大RT的請求的比例大於閾值,則接下來的熔斷時長內請求會自動被熔斷。

經過熔斷時長后熔斷器會進入探測恢復狀態,若接下來的一個請求成功完成則結束熔斷,否則會再次被熔斷。

說明:在1000ms內請求數超過5個,且平均響應時間超過300ms的請求的比例(超過300ms的請求占總請求的比例)大於0.4,則該資源自動熔斷10s。10s后根據下一個請求判斷是否再次被熔斷。

(2)異常比例:當單位統計時長內請求數目大於設置的最小請求數目,並且異常的比例大於閾值,則接下來的熔斷時長內請求會自動被熔斷。

經過熔斷時長后熔斷器會進入探測恢復狀態,若接下來的一個請求成功完成則結束熔斷,否則會再次被熔斷。

說明:在1000ms內請求數超過5個,且異常的比例(異常的請求占總請求的比例)大於0.8,則該資源自動熔斷15s。15s后根據下一個請求判斷是否再次被熔斷。

(3)異常數:當單位統計時長內的異常數目超過閾值之后會自動進行熔斷。

經過熔斷時長后熔斷器會進入探測恢復狀態,若接下來的一個請求成功完成則結束熔斷,否則會再次被熔斷。

說明:在1000ms內請求數超過5個,且異常的請求超過6個,那么該資源將自動熔斷20s。20s后根據下一個請求判斷是否再次被熔斷。

3.3.2注解@SentinelResource的使用

前面的所講的流控或降級,其返回的數據都是 Blocked by Sentinel (flow limiting) ,當然可以自定義。@SentinelResource和@HystrixCommand的作用是類似的,都是來指定流控或降級時返回的信息。

在方法上加@SentinelResource注解,且使用blockHandler(或者blockHandlerClass)指定流控或降級時的自定義提示,而blockHandler函數訪問范圍需要是public,返回類型需要與原方法相匹配,參數類型需要和原方法相匹配並且最后加一個額外的參數(類型是BlockException),且和原方法在同一個類中。使用fallback 指定未流控或降級發生異常時的自定義提示,其方法必須是public,返回類型需要與原方法相匹配,參數類型需要和原方法相匹配。

下面通過對/testC進行流控和降級來說明:

1)流控配置:

 

2)降級配置:

3)后台代碼:

    @GetMapping("/testC")
    @SentinelResource(value = "aaa", blockHandler = "testCBlockHandler",fallback = "testCFallback")
    public String testC(Integer id) {
        if (id < 0) {
            throw new RuntimeException("參數值格式錯誤");
        }
        return "--------testC";
    }

    //自定義降級或熔斷時的提示信息
    public String testCBlockHandler(Integer id, BlockException exception) {
        //判斷異常的類型
        if (exception instanceof FlowException) {
            return "你被限流了,請稍后再試";
        } else if (exception instanceof DegradeException) {
            return "你被降級了,請稍后再試";
        }
        return "當前服務不可用";
    }

    //自定義未限流時發生異常的提示信息
    public String testCFallback(Integer id){
        return "參數不合法";
    }

在@SentinelResource指定了value,其值就是要流控或降級的資源名,必須配置。

當訪問/testC?id=8時,快速刷新,會出現流控提示信息。

當問/testC?id=-5時,刷新1此,會出現錯誤提示信息。

當問/testC?id=-5時,刷新5次以上,會出現降級提示信息。

3.4規則持久化

你有沒有發現,每次無論重啟sentinel服務還是要監控的服務,sentinel頁面的配置規則都會消失,這是因為這些規則沒有持久化,對應大量的配置規則,持久化也非常重要,可將其配置到nacos中。

這里直接在cloud-alibaba-sentinel模塊進行說明:

1)導入依賴

        <!--springcloud alibaba sentinel-datasource-nacos-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

2)在yml配置,已存在配置省略:

spring:
  cloud:
      # 流控規則持久化到nacos
      datasource:
        dsl:
          nacos:
            server-addr: ${spring.cloud.nacos.server-addr}
            data-id: ${spring.application.name}
            group-id: DEFAULT_GROUP
            data-type: json
            rule-type: flow

3)在nacos中添加配置文件,如下圖:

 json內容:

[
    {
        "resource": "/testA",
        "limitApp": "default",
        "grade": 1,
        "count": 5,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

可看到json中是一個數組,數組中只有一個元素,那么針對/test的請求的配置規則會存下來,不會因為重啟而丟失,而其他的請求的配置規則還是丟失。針對這些請求,都按照這種規則配置在數組中即可。

4.Seata

官網:https://seata.io/zh-cn/index.html

一次業務操作需要跨多個數據源或需要跨多個系統進行遠程調用,就會產生分布式事務問題。Seata是一種分布式事務的解決方案,在服務搭建正確的情況下,在業務上添加@GlobalTransactional

4.1術語(一ID+三組件模式)

1)XID:(Transaction ID)全局唯一的事務ID

1)TC:(Transaction Coordinator)事務協調器,維護全局事務的運行狀態,負責協調並驅動全局事務的提交或回滾

2)TM:(Transaction Manager)控制全局事務的邊界,負責開啟一個全局事務,並最終發起全局提交或全局回滾的決議

3)RM:(Resource Manager)控制分支事務,負責分支注冊、狀態匯報,並接收事務協調器的指令,驅動分支(本地)事務的提交和回滾

4.2處理過程

1)TM向TC申請開啟一個全局事務,全局事務創建成功並生成一個全局唯一的XID

2)XID在微服務調用鏈路的上下文中傳播

3)RM向TC注冊分支事務,將其納入XID對應全局事務的管轄

4)TM向TC發起針XID的全局提交或回滾決議

5)TC調度XID下管轄的全部分支事務完成提交或回滾請求。 

4.3下載安裝

1)下載地址:https://github.com/seata/seata/releases,下載對應版本即可。

5.微服務架構整合

相比之下,使用SpringCloud+SpringCloud alibaba效果會更好。整合的組件說明如下表:

微服務組件 框架 具體組件
服務注冊 SpringCloud alibaba nacos
服務調用 SpringCloud openfeign
服務配置 SpringCloud alibaba nacos
服務網關 SpringCloud gateway
服務熔斷和降級 SpringCloud alibaba sentinel
服務負載均衡 SpringCloud Ribbon。默認已有

涉及到整合,那么兩者的版本需要進行匹配並進行統一管理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM