1. 簡介
為什么會出現?
SpringCloud Netflix進入維護模式,意味著不再向模塊添加新的功能和組件
能干嘛?
服務降級限流、服務注冊與發現、分布式配置管理、訊息驅動能力、阿里云物件存盤、分布式任務調度
2. Nacos服務注冊配置中心
2.1 安裝
介紹
Nacos是注冊中心+配置中心的組合,即Nacos = Eurake + Config + Bus
下載
https://github.com/alibaba/nacos/releases/download/1.1.4/nacos-server-1.1.4.zip

解壓,進入bin目錄,雙擊sartup.cmd啟動!訪問 http://localhost:8848/nacos:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fp04jyFg-1619878400710)(E:\學習筆記\圖片\image-20210422162037895.png)]](https://img.uj5u.com/2021/05/03/2410970307152226.png)
2.2 Nacos服務注冊中心
2.2.1 服務提供者注冊
-
新建module:cloudalibaba-provider-payment9001
-
POM
-
父POM
-
子POM
<dependencies> <!--SpringCloud ailibaba nacos --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
-
-
YML
server: port: 9001 spring: application: name: nacos-payment-provider cloud: nacos: discovery: server-addr: localhost:8848 #配置Nacos地址 management: endpoints: web: exposure: include: '*' -
主啟動
@SpringBootApplication @EnableDiscoveryClient public class PaymentMain9001 { public static void main(String[] args) { SpringApplication.run(PaymentMain9001.class,args); } } -
業務類
@RestController public class PaymentController { @Value("${server.port}") private String serverPort; @GetMapping(value = "/payment/nacos/{id}") public String getPayment(@PathVariable("id") Integer id){ return "nacos registry, serverPort: "+serverPort+"\t id: " + id; } } -
新建9002:效果如下:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-QHQLOyu6-1619878400712)(E:\學習筆記\圖片\image-20210422171436190.png)]](https://img.uj5u.com/2021/05/03/241097030715221.png)
2.2.2 消費者注冊和負載
-
新建Module:cloudalibaba-consumer-nacos-order83
-
POM
<dependencies> <!--SpringCloud ailibaba nacos --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> -
YML
server: port: 83 spring: application: name: nacos-order-consumer cloud: nacos: discovery: server-addr: localhost:8848 #消費者將要去訪問的微服務名稱(注冊成功進nacos,的微服務提供者) service-url: nacos-user-service: http://nacos-payment-provider -
主啟動類
@EnableDiscoveryClient @SpringBootApplication public class PaymentMain9002 { public static void main(String[] args) { SpringApplication.run(PaymentMain9002.class,args); } } -
業務類
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-03YjFn75-1619878400713)(E:\學習筆記\圖片\image-20210422215304790.png)]](https://img.uj5u.com/2021/05/03/241097030715222.png)
@Configuration public class ApplicationContextConfig { @Bean @LoadBalanced public RestTemplate getRestTemplete(){ return new RestTemplate(); } }@RestController@Slf4jpublic class OrderNacosController { @Resource private RestTemplate restTemplate; @Value("${service-url.nacos-user-service}") private String serverURL; @GetMapping(value = "/consumer/payment/nacos/{id}") public String paymentInfo(@PathVariable("id") Long id){ return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class); }} -
測驗
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-tV5Ke9Sg-1619878400715)(E:\學習筆記\圖片\image-20210422220100070.png)]](https://img.uj5u.com/2021/05/03/241097030715223.png)
http://localhost:83/consumer/payment/nacos/13 實作了負載均衡

2.2.3 服務注冊中心對比

Nacos支持AP和CP的切換:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-f84TMpKp-1619878400717)(E:\學習筆記\圖片\image-20210422222151921.png)]](https://img.uj5u.com/2021/05/03/2410970307152228.png)
2.3 Nacos配置中心
2.3.1 基礎配置
-
新建module:cloudalibaba-config-nacos-client3377
-
POM
<dependencies> <!--nacos-config--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--SpringCloud ailibaba nacos --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> -
YML
Nacos同springcloud-config一樣,在專案初始化時,要保證先從配置中心進行配置拉取,拉取配置之后,才能保證專案的正常啟動,springboot中組態檔的加載是存在優先級順序的,bootstrap優先級高于application,-
bootstrap
#naco配置 server: port: 3377 spring: application: name: nacos-config-client cloud: nacos: discovery: server-addr: localhost:8848 #Nacos服務注冊中心地址 config: server-addr: localhost:8848 #Nacos作為配置中心地址 file-extension: yaml #指定yamL格式的配置 # $fspring.application.name}-${spring.profile.active]}.${spring.cLoud.nacos,config.file-extension} -
application
spring: profiles: active: dev #表示開發環境
-
-
主啟動類
@EnableDiscoveryClient @SpringBootApplication public class NacosConfigClientMain3377 { public static void main(String[] args) { SpringApplication.run(NacosConfigClientMain3377.class,args); } } -
業務類
@RestController @RefreshScope //支持nacos動態重繪 public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/config/info") public String getConfigInfo(){ return configInfo; } } -
在NACOS中添加配置資訊
配置規則:Nacos中的dataid的組成格式及與SpringBoot組態檔中的匹配規則
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZaMKbfkE-1619878400718)(E:\學習筆記\圖片\image-20210423103517036.png)]](https://img.uj5u.com/2021/05/03/2410970307152229.png)

![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qQRGSEkF-1619878400719)(E:\學習筆記\圖片\image-20210423104104866.png)]](https://img.uj5u.com/2021/05/03/2410970307152231.png)
-
自帶動態重繪

2.3.2 分類配置
namespace、group、dataid三者關系

默認情況:
Namespace=public,Group=DEFAULT_GROUP,默認Cluster是DEFAULT
Nacos默認的命名空間是public,Namespace主要用來實作隔離,
比方說我們現在有三個環境:開發、測驗、生產環境,我們就可以創建三個Namespace,不同的Namespace之間是隔離的,
Group默認是DEFAULT_GROUP,Group可以把不同的微服務劃分到同一個分組里面去
Service就是微服務;一個Service可以包含多個Cluster(集群),Nacos默認Cluster是DEFAULT,Cluster是對指定微服務的一個虛擬劃分,比方說為了容災,Service微服務分別部署在了杭州機房和廣州機房,這時就可以給杭州機房的Service微服務起一個集群名稱(HZ),給廣州機房的Service微服務起一個集群名稱(GZ),還可以盡量讓同一個機房的微服務互相呼叫,以提升性能,
最后是Instance,就是微服務的實體,
DataId配置方案
-
指定spring.profile.active和組態檔的DatalD來使不同環境下讀取不同的配置
-
默認空間+默認分組+新建dev和test兩個dataid,通過spring.profile.active屬性就能進行多環境下組態檔的讀取,測驗:

![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-lN7BrRfj-1619878400720)(E:\學習筆記\圖片\image-20210423111348729.png)]](https://img.uj5u.com/2021/05/03/241097030715227.png)
想切換哪個環境就換成哪個環境?
group分組方案



namespace空間方案
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Os8RrTYg-1619878400720)(E:\學習筆記\圖片\image-20210423112309433.png)]](https://img.uj5u.com/2021/05/03/2410970307152234.png)
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-kxeJKVsm-1619878400721)(E:\學習筆記\圖片\image-20210423113026377.png)]](https://img.uj5u.com/2021/05/03/2410970307152210.png)

2.4 Nacos集群持久化配置
集群架構說明
- 默認Nacos使用嵌入式資料庫實作資料的存盤,所以,如果啟動多個默認配置下的Nacos節點,資料存盤是存在一致性問題的,為了解決這個問題,Nacos采用了集中式存盤的方式來支持集群化部署,目前只支持MySQL的存盤,

持久化切換配置
-
Nacos默認自帶的是嵌入式資料庫derby
-
derby到mysql切換配置步驟
-
nacos的conf目錄下找到sql腳本:nacos-mysql.sql,在資料庫中執行

-
nacos的conf目錄下找到application.properties:在最后添加以下內容
spring.datasource.platform=mysql db.num=1 db.url.O=jdbc:mysql://127.0.0.1:3306/nacos_config? characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true db.user=root db.password=admin -
最后進入nacos測驗,發布組態檔,發現在資料庫中有:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-iPajixcv-1619878400721)(E:\學習筆記\圖片\image-20210423154841287.png)]](https://img.uj5u.com/2021/05/03/2410970307152213.png)
-
2.5 Nacos的Linux安裝
- 下載地址:https://github.com/alibaba/nacos/releases/download/1.4.1/nacos-server-1.4.1.tar.gz(1.4.1版本)
- 在opt目錄中解壓即可
2.6 集群配置(上)
-
在Linux上Mysql資料庫配置,跟在windows上一致,需要新建nacos_config庫并生成表
-
application.properties配置,跟windows上一致
-
Linux服務器上nacos集群配置cluster.conf

-
梳理出三臺不同nacos集群的服務埠號:3333、4444、5555(cluster.conf)
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Rm8CD0TS-1619878400722)(E:\學習筆記\圖片\image-20210423214434983.png)]](https://img.uj5u.com/2021/05/03/2410970307152214.png)
-
-
編輯nacos的啟動腳本startup.sh,使他能夠接受不同的啟動埠:

2.7 集群配置(下)

測驗:啟動3333、4444、5555,啟動nginx,測驗網址:http://192.168.200.130:1111/nacos/#/login,登錄密碼均為nacos!
(一定要注意如果訪問失敗很有可能是埠號沒有打開!!!)


新建一條配置測驗:


微服務cloudalibaba-provider-payment9002注冊進nacos集群:
修改組態檔:
server:
port: 9002
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
#server-addr: localhost:8848 #配置Nacos地址
#換成nginx的1111埠,做集群
server-addr: 192.168.200.130:1111
management:
endpoints:
web:
exposure:
include: '*'
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-xiGKEXl3-1619878400724)(E:\學習筆記\圖片\image-20210424150051254.png)]](https://img.uj5u.com/2021/05/03/2410970307152215.png)
3. Sentinel熔斷與限流
3.1 簡介
是什么
? 隨著微服務的流行,服務和服務之間的穩定性變得越來越重要,Sentinel以流量為切入點,從流量控
制、熔斷降級、系統負載保護等多個維度保護服務的穩定性,一句話,優化版的Hystrix,
特征
- 豐富的應用場景:Sentinel承接了阿里巴巴近10年的雙十一大促流量的核心場景,例如秒殺(即突
發流量控制在系統容量可以承受的范圍)、襠息削峰填谷、集群流量控制、實時熔斷下游不可用應
用等, - 完備的實時監控:Sentinel同時提供實時的監控功能,您可以在控制臺中看到接入應用的單臺機器
秒級資料,甚至500臺以下規模的集群的匯總運行情況, - 廣泛的開源生態:Sentinel提供開箱即用的與其它開源框架/庫的整合模塊,例如與Spring Cloud.
Dubbo、gRPC的整合,您只需要引入相應的依賴并進行簡單的配置即可快速地接入Sentinel,
完善的SPI擴展點: Sentinel提供簡單易用、完善的SPI擴展介面,您可以通過實作擴展介面來快
速地定制邏輯,例如定制規則管理、適配動態資料源等,

3.2 下載運行
-
下載地址:https://github.com/alibaba/Sentinel/releases/download/1.7.0/sentinel-dashboard-1.7.0.jar
-
sentinel分為兩部分:
- 核心庫(Java客戶端)不依賴任何框架/庫,能夠運行于所有Java運行時環境,同時對Dubbo /
Spring Cloud等框架也有較好的支持, - 控制臺(Dashboard)基于Spring Boot開發,打包后可以直接運行,不需要額外的Tomcat等應用
容器,
- 核心庫(Java客戶端)不依賴任何框架/庫,能夠運行于所有Java運行時環境,同時對Dubbo /
-
安裝:
-
在目錄下命令列中輸入:java -jar .\sentinel-dashboard-1.7.0.jar
-
輸入localhost:8080,進入sentinel頁面,用戶名密碼均為sentinel
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EZ7vXc4R-1619878400724)(E:\學習筆記\圖片\image-20210424153940600.png)]](https://img.uj5u.com/2021/05/03/2410970307152244.png)
-
3.3 Sentinel初始化監控
新建一個Module:cloudalibaba-sentinel-service8401
-
POM
<dependencies> <!-- alibaba sentinel --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel</artifactId> </dependency> <!-- sentinel-datasource-nacos 后續做持久化用到--> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--SpringCloud ailibaba nacos --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> -
YML
server: port: 8401 spring: application: name: cloudalibaba-sentinel-service cloud: nacos: discovery: server-addr: localhost:8848 sentinel: transport: #配置sentinel dashboard地址 dashboard: localhost:8080 #默認8719埠,假如被占用會自動從8719埠+1,直至找到未被占用的埠 port: 8719 management: endpoints: web: exposure: include: '*' -
主啟動
@EnableDiscoveryClient @SpringBootApplication public class MainApp8401 { public static void main(String[] args) { SpringApplication.run(MainApp8401.class,args); } } -
業務類FlowLimitController
@RestController public class FlowLimitController { @GetMapping("testA") public String testA(){ return "---------testA"; } @GetMapping("testB") public String testB(){ return "---------testB"; } }
啟動Sentinel和微服務8401,查看控制臺:
Sentinel執行的是懶加載機制,執行一次訪問即可!http://localhost:8401/testA或http://localhost:8401/testB:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-0ebod1ev-1619878400725)(E:\學習筆記\圖片\image-20210424160517505.png)]](https://img.uj5u.com/2021/05/03/2410970307152245.png)
3.4 流控規則
基本介紹
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-CrX57e48-1619878400726)(E:\學習筆記\圖片\image-20210424160747182.png)]](https://img.uj5u.com/2021/05/03/2410970307152246.png)
-
資源名∶唯一名稱,默認請求路徑
-
針對來源: Sentinel可以針對呼叫者進行限流,填寫微服務名,默認default(不區分來源)
-
閾值型別/單機閾值:
- QPS(每秒鐘的請求數量)︰當呼叫該api的QPS達到閾值的時候,進行限流
- 執行緒數:當呼叫該api的執行緒數達到閾值的時候,進行限流
-
是否集群:不需要集群
-
流控模式:
- 直接:api達到限流條件時,直接限流
- 關聯:當關聯的資源達到閾值時,就限流自己
- 鏈路:只記錄指定鏈路上的流量(指定資源從入口資源進來的流量,如果達到閾值,就進行限流)【api級別的針對來源】
-
流控效果
- 快速失敗:直接失敗,拋例外
- Warm up:根據codeFactor(冷加載因子,默認3)的值,從閾值/codeFactory,經過預熱時長,才達到設定的QPS閾值
- 排隊等待:勻速排隊,讓請求以勻速的速度通過,閾值型別必須設定為QPS,否則無效
3.4.1 流量模式1:直接
QPS直接失敗
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-tTB7e9Oi-1619878400726)(E:\學習筆記\圖片\image-20210424162225605.png)]](https://img.uj5u.com/2021/05/03/2410970307152247.png)

表示1s內查詢超過1次就是失敗!
執行緒數直接失敗

QPS:如果超過閾值,其余的請求直接拒絕,御敵于國門之外
執行緒數直接失敗:如果超過閾值,其余的請求無法訪問,報錯,但是并沒有拒絕,關門打狗!
3.4.2 流控模式2:關聯
簡介
當關聯的資源達到閾值時,就限流自己,即當與A關聯的資源B達到閥值后,就限流A自己,B惹事,A掛了

Postman模擬并發訪問testB:


此時A又掛了:

3.4.3 流控模式3:鏈路
介紹
多個請求呼叫了同一個微服務
3.4.4 流控效果1:預熱
介紹
-
快速失敗:默認的流控效果,直接提示失敗訊息!
-
公式:閾值除以coldFactory(默認值為3),經過預熱時長以后才會達到閾值!
-
默認coldFactory為3,即請求QPS從threshod/3開始,經預熱時長逐漸升高設定的QPS閾值

-
應用:秒殺系統在開啟的瞬間,會有很多流量上來,很有可能把系統打死,預熱方式就是把為了保護系統,可慢慢的把流量放迸來,慢慢的把閥值增長到設定的閥值,
3.4.5 流控效果2:排隊等待
介紹
勻速排隊,讓請求以均勻的速度通過,閥值型別必須設成QPS,否則無效,(漏桶演算法)

3.5 降級規則
簡介

- RT(平均回應時間,秒級)
平均回應時間超出閾值且在時間視窗內通過的請求>=5,兩個條件同時滿足后觸發降級,視窗期過后關閉斷路器,RT最大4900(更大的需要通過-Dcsp.sentinel.statistic.max.rt=XXXX才能生效) - 例外比列(秒級):QPS >=5且例外比例超過閾值時,觸發降級;時間視窗結束后,關閉降級
- 例外數(分鐘級):例外數超過閾值時,觸發降級;時間視窗結束后,關閉降級
- Sentinel的斷路器是沒有半開狀態的!
3.5.1 降級策略1:RT

3.5.2 降級策略2:例外比例


3.5.3 降級策略3:例外數
例外數:當資源近1分鐘的例外數目超過閾值之后會進行熔斷,注意由于統計時間視窗是分鐘級別的,若tiiewindow小于60s,則結束熔斷狀態后仍可能再進入熔斷狀態,

3.6 熱點規則
介紹
- 熱點引數限流會統計傳入引數中的熱點引數,并根據配置的限流閾值與模式,對包含熱點引數的資源呼叫進行限流,熱點引數限流可以看做是一種特殊的流量控制,僅對包含熱點引數的資源呼叫生效,
- 自定義服務降級從**@HystrixCommand到@SentinelResource**
配置實作
-
Controller
@RestController public class FlowLimitController { @GetMapping("/testHotKey") @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey") //隨便叫啥都可以,只是為了編碼的統一和規范和上面一直 public String testhotKey(@RequestParam(value = "p1",required = false) String p1, @RequestParam(value = "p1",required = false) String p2){ return "------testHotKey"; } public String deal_testHotKey(String p1, String p2, BlockException exception){ return "兜底┭┮﹏┭┮"; //sentinel默認提示為Blocked by sentinel (flow Limiting) } } -
新增熱點限流規則:方法testHotkey中的第一個引數只要QPS超過每秒1次,馬上降級處理

-
測驗:

-
如果,沒有使用兜底方法,即去掉了blockHandler = “deal_testHotKey”,當QPS超過閾值,直接調到ERROR PAGE,對用戶不友好!
引數例外項
-
在上述的情況下,當p1引數在1s內的QOS超過某個閾值的時候,p1馬上就會被限流,現在我們期望,當p1是某個特殊值的時候,它的限流值和平時不太一樣,例如當p1值為5的時候,它的閾值可以達到200,這就要用到引數例外項了,
-
配置:當p1為5的時候,限流閾值為200,當不為5的時候,限流閾值為1!

-
當方法中出現例外的時候,無論是否違背熱點規則,都無法進行兜底了,
@SentinelResource處理的是Sentinel控制臺配置的違規情況,有blockHandler方法配置的兜底處理,但運行時例外他不管,即它只管配置出錯,運行出錯該走例外走例外!
3.7 系統規則
介紹
-
系統保護規則是從應用級別的入口流量進行控制,從單臺機器的load、CPU使用率、平均RT、入口
QPS和并發執行緒數等幾個維度監控應用指標,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩
定性, -
系統保護規則是應用整體維度的,而不是資源維度的,并且僅對入口流量生效,入口流星指的是進入
應用的流量((EntryType.IN ),比如Web服務或Dubbo服務端接收的請求,都屬于入口流量, -
系統規則支持以下的模式:
- Load自適應(僅對Linux/Unixlike機器生效)∶系統的load1作為啟發指標,進行自適應系統
保護,當系統load1超過設定的啟發值,且系統當前的并發執行緒數超過估算的系統容量時才會觸
發系統保護(BBR 階段),系統容量由系統的maxQps * minRt估算得出,設定參考值一般是
CPu cores* 2.5, - CPU usage (1.5.0+版本)︰當系統CPU使用率超過閾值即觸發系統保護(取值范圍0.0-
1.0),比較靈敏, - 平均RT:當單臺機器上所有入口流量的平均RT達到閾值即觸發系統保護,單位是毫秒,
- 并發執行緒數:當單臺機器上所有入口流量的并發執行緒數達到閾值即觸發系統保護,
- 入口QPS:當單臺機器上所有入口流量的QPS達到閾值即觸發系統保護,
- Load自適應(僅對Linux/Unixlike機器生效)∶系統的load1作為啟發指標,進行自適應系統
-
配置:

testA、testB每秒QPS大于1的時候,都會直接失敗,對整個系統的所有服務都是這樣!
3.8 @SentinelResource
按資源名稱限流+后續處理
修改8401:
-
POM:
<!-- 引入自己定義的api通用包,可以使用payment支付Entity --> <dependency> <groupId>com.atguigu.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency> -
業務類:
@RestController public class RateLimitController { @GetMapping("/byResource") @SentinelResource(value = "byResource",blockHandler = "handleException") public CommonResult byResource(){ return new CommonResult(200,"按資源名稱限流測驗ok",new Payment(2020L,"serial001")); } public CommonResult handleException(BlockException exception){ return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服務不可用"); } } -
配置

-
問題:關閉8401,sentinel控制臺,流控規則消失了!
按url地址限流+后續處理
? 
問題:
- 系統默認的,沒有體現我們自己的業務要求,
- 依照現有條件,我們自定義的處理方法又和業務代碼耦合在一塊,不直觀,
- 每個業務方法都添加—個兜底的,那代碼膨脹加劇,
- 全域統—的處理方法沒有體現,
3.8.1 自定義限流處理
-
創建CustomerBlockHandler類用于自定義限流處理邏輯
public class CustomerBlockHandler { public static CommonResult handerException(BlockException exception){ return new CommonResult(4444,"按客戶自定義,global handerException ---- 1"); } public static CommonResult handerException2(BlockException exception){ return new CommonResult(4444,"按客戶自定義,global handerException ---- 2"); } } -
RateLimitController
//customerblockhandler @GetMapping("/rateLimit/customerBlockHandler") @SentinelResource(value = "customerBlockHandler", blockHandlerClass = CustomerBlockHandler.class, blockHandler = "handerException2") public CommonResult customerBlockHandler(){ return new CommonResult(200,"按客戶自定義測驗ok",new Payment(2020L,"serial003")); } -
限流后測驗:

3.8.2 更多注解說明:
三個核心API:
- Sphu定義資源
- Trace定義統計
- ContextUtil定義背景關系
3.9 服務熔斷
- 新建provider9003、9004,消費者Order84
- 實作Sentinel + ribbon + openFeign + fallback
服務熔斷無配置
如果程式運行出錯,直接404
只配置fallback
程式運行出錯,直接呼叫fallback指定的方法內容回傳,
只配置BlockHandler
當程式運行出錯,會用BlockHnadler來兜底!
兩種都配置
在沒被限流降級時,呼叫fallback,在被限流降級之后,呼叫blockhandler!
exceptionToIngore
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-sS8MkXGT-1619878400727)(E:\學習筆記\圖片\image-20210425160815520.png)]](https://img.uj5u.com/2021/05/03/2410970307152221.png)
如果這樣配置了,就不走fallback了!
熔斷框架對比

3.10 Sentinel持久化規則
介紹
一旦我們重啟應用,sentinel規則將消失,生產環境需要將配置規則進行持久化,因此將限流配置規則持久化進Nacos保存,只要重繪8401某個rest地址,sentinel控制臺的流控規則就能看到,只要Nacos里面的配置不洗掉,針對8401上sentinel上的流控規則持續有效
步驟
修改8401步驟:
-
POM
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency> -
YML
server: port: 8401 spring: application: name: cloudalibaba-sentinel-service cloud: nacos: discovery: server-addr: localhost:8848 sentinel: transport: #配置sentinel dashboard地址 dashboard: localhost:8080 #默認8719埠,假如被占用會自動從8719埠+1,直至找到未被占用的埠 port: 8719 datasource: ds1: nacos: server-addr: localhost:8848 dataId: cloudalibaba-sentinel-service groupId: DEFAULT_GROUP data-type: json rule-type: flow management: endpoints: web: exposure: include: '*' -
新建nacos業務規則配置:
resource:資源名稱;
limitApp:來源應用;
grade:閾值型別,0表示執行緒數,1表示QPS;
count:單機閾值;
strategy:流控模式,0表示直接,1表示關聯,2表示鏈路;
controlBehavior:流控效果,0表示快速失敗,1表示Warm Up,2表示排隊等待;
clusterMode:是否集群,
-
啟動8401,發現Sentinel控制臺有流控規則了!關閉8401,發現流控規則沒有了,重啟8401并多次重繪,流控規則又回來了!!!!!!!!!
4. Seata處理分布式事務
4.1 分布式事務問題由來

背景
單體應用被拆分成微服務應用,原來的三個模塊被拆分成三個獨立的應用,分別使用三個獨立的資料源,業務操作需要呼叫三個服務來完成,此時每個服務內部的資料一致性由本地事務來保證,但是全域的資料一致性問題沒法保證,
總結
一次業務操作需要跨多個資料源或需要跨多個系統進行遠程呼叫,就會產生分布式事務問題!
4.2 Seata
簡介
Seata是一款開源的分布式事務解決方案,致力于在微服務架構下提供高性能和簡單易用的分布式事務服務!
分布式事務模型:1個ID+三組件
-
1個ID:Transaction ID ------ XID 即全域唯一的事務ID
-
三組件概念:
- Transaction Coordinator (TC):事務協調者,維護全域和分支事務的狀態,驅動全域事務提交或回滾,
- Transaction Manager ?:事務管理器,定義全域事務的范圍:開始全域事務、提交或回滾全域事務,
- Resource Manager(RM):資源管理器,管理分支事務處理的資源,與TC交談以注冊分支事務和報告分支事務的狀態,并驅動分支事務提交或回滾,
-
處理程序:

- TM向TC申請開啟一個全域事務,全域事務創建成功并生成一個全域唯一的XID;
- XID在微服務呼叫鏈路的背景關系中傳播;
- RM向TC注冊分支事務,將其納入XID對應全域事務的管轄;
- TM向TC發起針對XID的全域提交或回滾決議;
- TC調度XID下管轄的全部分支事務完成提交或回滾請求,
4.3 Seata Serve安裝
-
下載地址:https://github.com/seata/seata/releases/download/v1.0.0/seata-server-1.0.0.zip
-
安裝:
-
解壓并修改conf目錄下的file.conf組態檔!主要修改:自定義事務組名稱+事務日志存盤模式為db+資料庫連接資訊
-
service模塊

-
store模塊
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wW8PXmzp-1619878400727)(E:\學習筆記\圖片\image-20210425212939869.png)]](https://img.uj5u.com/2021/05/03/2410970307152267.png)
-
-
-
mysql5.7新建資料庫seata
-
seata里面新建表:建表的db_store.sql在**\seata-server-0.9.0\seata\conf**目錄里面
drop table if exists `global_table`; create table `global_table` ( `xid` varchar(128) not null, `transaction_id` bigint, `status` tinyint not null, `application_id` varchar(32), `transaction_service_group` varchar(32), `transaction_name` varchar(128), `timeout` int, `begin_time` bigint, `application_data` varchar(2000), `gmt_create` datetime, `gmt_modified` datetime, primary key (`xid`), key `idx_gmt_modified_status` (`gmt_modified`, `status`), key `idx_transaction_id` (`transaction_id`) ); drop table if exists `branch_table`; create table `branch_table` ( `branch_id` bigint not null, `xid` varchar(128) not null, `transaction_id` bigint , `resource_group_id` varchar(32), `resource_id` varchar(256) , `lock_key` varchar(128) , `branch_type` varchar(8) , `status` tinyint, `client_id` varchar(64), `application_data` varchar(2000), `gmt_create` datetime, `gmt_modified` datetime, primary key (`branch_id`), key `idx_xid` (`xid`) ); drop table if exists `lock_table`; create table `lock_table` ( `row_key` varchar(128) not null, `xid` varchar(96), `transaction_id` long , `branch_id` long, `resource_id` varchar(256) , `table_name` varchar(32) , `pk` varchar(36) , `gmt_create` datetime , `gmt_modified` datetime, primary key(`row_key`) ); -
修改seata-server-0.9.0\seata\conf目錄下的registry.conf組態檔:指明注冊中心為nacos及修改連接資訊

-
測驗:先啟動nacos,再啟動seata server.bat,成功!
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-jGLtrX5k-1619878400728)(E:\學習筆記\圖片\image-20210425215243426.png)]](https://img.uj5u.com/2021/05/03/2410970307152224.png)
-
怎么玩?
本地@Transactional
全域@GlobalTransactional
Seata的分布式交易解決方案:

?
4.4 Seata原理
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2MAYPRpW-1619878400729)(E:\學習筆記\圖片\image-20210426155130463.png)]](https://img.uj5u.com/2021/05/03/2410970307152269.png)
AT模式如何做到對業務的無侵入
-
一階段加載:在一階段,Seata會攔截“業務SQL",
決議SQL語意,找到“業務SQL"要更新的業務資料,在業務資料被更新前,將其保存成"before image” ,執行“業務SQL"更新業務資料,在業務資料更新之后,其保存成“after image" ,最后生成行鎖,
以上操作全部在一個資料庫事務內完成,這樣保證了一階段操作的原子性,
-
二階段回滾:即Seata就需要回滾一階段已經執行的“業務SQL",還原業務資料,回滾方式便是用"before image"還原業務資料;但在還原前要首先要校驗臟寫,對比”資料庫當前業務資料”和"after image",如果兩份資料完全一致就說明沒有臟寫, 可以還原業務資料,如果不一致就說明有臟寫,出現臟寫就需要轉人工處理,

二階段提交:因為“業務SQL"在一階段已經提交至資料庫,所以Seata框架只需將一階段保存的快照資料和行鎖刪掉,完成資料清理即可,
?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/282304.html
標籤:java
