版本: 2.2.1
一、簡介
- https://spring.io/projects/spring-cloud-alibaba
- 阿裡雲為分布式應用開發提供了一站式解決方案。它包含了開發分布式應用程式所需的所有元件,使您可以輕松地使用springcloud開發應用程式。
- 有了阿裡雲,你隻需要添加一些注解和少量的配置,就可以将Spring雲應用連接配接到阿裡的分布式解決方案上,用阿裡中間件搭建一個分布式應用系統。
二、環境搭建
0.建構項目并引入依賴
2.2.1.RELEASEcom.alibaba.cloudspring-cloud-alibaba-dependencies${spring.cloud.alibaba.version}pomimport
完整的pom.xml
4.0.0org.springframework.bootspring-boot-starter-parent2.2.5.RELEASEcom.md08-hello0.0.1-SNAPSHOT08-helloDemo project for Spring Boot1.82.2.1.RELEASEorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-devtoolsruntimetrueorg.projectlomboklomboktrueorg.springframework.bootspring-boot-starter-testtestcom.alibaba.cloudspring-cloud-alibaba-dependencies${spring.cloud.alibaba.version}pomimportorg.springframework.bootspring-boot-maven-pluginorg.projectlomboklombok
三、Nacos
0. 簡介
什麼是Nacos Name Service & Configurations Services
- https://nacos.io/zh-cn/index.html
- Nacos 緻力于幫助您發現、配置和管理微服務。Nacos 提供了一組簡單易用的特性集,幫助您快速實作動态服務發現、服務配置、服務中繼資料及流量管理。
- 總結:Nacos就是微服務架構中服務注冊中心以及統一配置中心,用來替換原來的(eureka,consul)以及config元件
1. 安裝Nacos
# 0.準備環境
- 1.64 bit OS,支援 Linux/Unix/Mac/Windows,推薦選用 Linux/Unix/Mac。
- 2.64 bit JDK 1.8+;下載下傳 & 配置。
- 3.Maven 3.2.x+;下載下傳 & 配置。
# 1.下載下傳nacos
- https://github.com/alibaba/nacos/releases
# 2.解壓縮安裝包到指定位置
- bin 啟動nacos服務的腳本目錄
- conf nacos的配置檔案目錄
- target nacos的啟動依賴存放目錄
- data nacos啟動成功後儲存資料的目錄
# 3.啟動安裝服務
- linux/unix/mac啟動
打開終端進入nacos的bin目錄執行如下指令
./startup.sh -m standalone
- windows啟動
在 cmd中
執行 startup.cmd -m standalone 或者輕按兩下startup.cmd運作檔案。
# 4.通路nacos的web服務管理界面
- http://localhost:8848/nacos/
- 使用者名 和 密碼都是nacos
四、開發服務注冊到nacos
0.建立項目并引入依賴
com.alibaba.cloudspring-cloud-starter-alibaba-nacos-discovery
4.0.0org.springframework.bootspring-boot-starter-parent2.2.5.RELEASEcom.md09-nacosclient87890.0.1-SNAPSHOT09-nacosclient8789Demo project for Spring Boot1.82.2.1.RELEASEorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-testtestcom.alibaba.cloudspring-cloud-starter-alibaba-nacos-discoverycom.alibaba.cloudspring-cloud-alibaba-dependencies${spring.cloud.alibaba.version}pomimportorg.springframework.bootspring-boot-maven-plugin
1.配置注冊位址
server.port=8789 #指定目前服務端口
spring.application.name=nacosclient #指定服務名稱
spring.cloud.nacos.server-addr=localhost:8848 #指定nacos服務位址
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr} #指定注冊中心位址
management.endpoints.web.exposure.include=* #暴露所有web端點
2.加入啟動服務注冊注解
3.檢視nacos的服務清單
五、服務間的通信
RestTemplate+Ribbon
https://www.cnblogs.com/mengd/p/14105955.html
可以看之前寫的文章,基本是一緻的
1. 建立項目
首先還是建立兩個項目,users和products
首先products對應的的pom.xml
4.0.0org.springframework.bootspring-boot-starter-parent2.2.5.RELEASEcom.md10-products90980.0.1-SNAPSHOT10-products9098Demo project for Spring Boot1.82.2.1.RELEASEorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-devtoolsruntimetrueorg.projectlomboklomboktrueorg.springframework.bootspring-boot-starter-testtestcom.alibaba.cloudspring-cloud-starter-alibaba-nacos-discoverycom.alibaba.cloudspring-cloud-alibaba-dependencies${spring.cloud.alibaba.version}pomimportorg.springframework.bootspring-boot-maven-pluginorg.projectlomboklombok
以及users對應的pom.xml檔案,類似這裡就不展示了
2. 配置檔案
server.port=9098
spring.application.name=products
spring.cloud.nacos.server-addr=localhost:8848
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr}
management.endpoints.web.exposure.include=*
#----------------------------------------------
server.port=9099
spring.application.name=users
spring.cloud.nacos.server-addr=localhost:8848
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr}
management.endpoints.web.exposure.include=*
3. nacos中進行檢視
啟動nacos,然後再啟動項目
4. constoller
在商品服務中,
package com.md.controller;
/**
* @author md
* @Desc
* @date 2020/12/17 20:38
*/
@RestController
@Slf4j
public class ProductController {
@Value("${server.port}")
private int port;
@GetMapping("/product/find")
public Mapfind(@RequestParam("id") String id)
{
HashMapmap = new HashMap<>();
map.put("status",true);
map.put("msg","目前調用的是商品服務,查詢商品的id:"+id);
map.put("port","目前的端口是:"+port);
return map;
}
}
重新開機,進行測試,直接通路
5. 使用RestTemplate
在users項目中
package com.md.controller;
@RestController
@Slf4j
public class UserController {
@GetMapping("/user/getProductInfo")
public String getProductInfo(String productId){
// 第一種方式. 通過restTemplate直接調用
RestTemplate restTemplate = new RestTemplate();
String forObject = restTemplate.getForObject("http://localhost:9098/product/find?id=" + productId, String.class);
return forObject;
}
}
重新開機,再通過users進行通路
6. restTemplate + ribbon
預設已經有依賴了
直接使用注解的方式
@Configuration
public class RestTemplateConfig {
// 在工廠中建立一個restTemplate對象
@Bean
// 加上這個注解代表目前的restTemplate對象帶有ribbon負載均衡
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
在controller中
package com.md.controller;
@RestController
@Slf4j
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/user/getProductInfo")
public String getProductInfo(String productId){
// 第二種方式,注解的方式
String forObject = restTemplate.getForObject("http://products/product/find?id=" + productId, String.class);
return forObject;
}
}
這樣更加的友善,頁面還是可以正常的方法
7.使用OpenFeign
https://www.cnblogs.com/mengd/p/14111059.html
可以看這個,寫的比較詳細
引入依賴在users中
org.springframework.cloudspring-cloud-starter-openfeign2.2.3.RELEASE
剩下的就不重複寫了
六、使用nacos作為配置中心
1.從nacos擷取配置
建立一個新的項目,還是基于alibaba的環境
# 1.建立項目并引入nacons配置中心依賴
com.alibaba.cloudspring-cloud-starter-alibaba-nacos-discoverycom.alibaba.cloudspring-cloud-starter-alibaba-nacos-config
完整的pom.xml檔案
4.0.0org.springframework.bootspring-boot-starter-parent2.2.5.RELEASEcom.md11-configclient90660.0.1-SNAPSHOT11-configclient9066Demo project for Spring Boot1.82.2.1.RELEASEorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-devtoolsruntimetrueorg.projectlomboklomboktrueorg.springframework.bootspring-boot-starter-testtestcom.alibaba.cloudspring-cloud-starter-alibaba-nacos-discoverycom.alibaba.cloudspring-cloud-starter-alibaba-nacos-configcom.alibaba.cloudspring-cloud-alibaba-dependencies${spring.cloud.alibaba.version}pomimportorg.springframework.bootspring-boot-maven-pluginorg.projectlomboklombok
# 2.配置配置中心位址
spring.cloud.nacos.server-addr=localhost:8848 # 遠端配置中心的位址
spring.cloud.nacos.config.group=DEFAULT_GROUP # 讀取配置的分組
# 這三者構成了下面的Data ID
spring.cloud.nacos.config.file-extension=properties # 指定讀取檔案字尾
spring.application.name=config # 指定讀取檔案的字首
spring.profiles.active=prod # 指定讀取檔案的具體環境
注意:寫的時候配置檔案不要有注釋
最好還是使用bootstrap.properties
# 3.在nacos中建立配置
這個配置内容就是之前寫的注冊到nacos上的配置,不要寫中文
# 4.編寫控制器測試配置讀取情況
@RestController
@Slf4j
public class HelloController {
//注入配置
@Value("${user.name}")
private String username;
@GetMapping("/hello/config")
public String config(){
log.info("使用者名: [{}]",username);
return username;
}
}
# 5.啟動項目方式測試配置讀取
2. DataId
# 1.DataId
- 用來讀取遠端配置中心的中具體配置檔案其完整格式如下:
- ${prefix}-${spring.profile.active}.${file-extension}
a. prefix 預設為 spring.application.name 的值,也可以通過配置項 spring.cloud.nacos.config.prefix來配置。
b. spring.profile.active 即為目前環境對應的 profile,詳情可以參考 Spring Boot文檔。 注意:當 spring.profile.active 為空時,對應的連接配接符 - 也将不存在,dataId 的拼接格式變成 ${prefix}.${file-extension}
c. file-exetension 為配置内容的資料格式,可以通過配置項 spring.cloud.nacos.config.file-extension 來配置。目前隻支援 properties 和 yaml 類型。
3.實作自動配置重新整理
# 1.自動重新整理
- 預設情況下nacos已經實作了自動配置重新整理功能,如果需要重新整理配置直接在控制器中加入@RefreshScope注解即可
@RestController
@Slf4j
@RefreshScope
public class HelloController {
//注入配置
@Value("${user.name}")
private String username;
@GetMapping("/hello/config")
public String config(){
log.info("使用者名: [{}]",username);
return username;
}
}
4.命名空間
# 1.命名空間(namespace)
- https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config
- namespace命名空間是nacos針對于企業級開發設計用來針對于不同環境的區分,比如正在企業開發時有測試環境,生産環境,等其他環境,是以為了保證不同環境配置實作隔離,提出了namespace的概念,預設在nacos中存在一個public命名空間所有配置在沒有指定命名空間時都在這個命名空間中擷取配置,在實際開發時可以針對于不能環境建立不同的namespace空間。預設空間不能删除!
# 2.建立其他命名空間
- 每個命名空間都有一個唯一id,這個id是讀取配置時指定空間的唯一辨別
# 3.在配置清單檢視空間
# 4.在指定空間下載下傳建立配置檔案
# 5.項目中使用命名空間指定配置
# 6.測試配置
5.配置分組
# 1.配置分組(group)
- 配置分組是對配置集進行分組,通過一個有意義的字元串(如 Buy 或 Trade )來表示,不同的配置分組下可以有相同的配置集(Data ID)。當您在 Nacos 上建立一個配置時,如果未填寫配置分組的名稱,則配置分組的名稱預設采用 DEFAULT_GROUP 。配置分組的常見場景:可用于區分不同的項目或應用,例如:學生管理系統的配置集可以定義一個group為:STUDENT_GROUP。
# 2.建立分組
# 3.讀取不同分組的配置
七、sentinel 流量衛兵
1.什麼是sentinel
說明
- https://github.com/alibaba/Sentinel/wiki
- 随着微服務的普及,服務調用的穩定性變得越來越重要。Sentinel以“流量”為突破口,在流量控制、斷路、負載保護等多個領域進行工作,保障服務可靠性。
- 通俗:用來在微服務系統中保護微服務對的作用 如何 服務雪崩 服務熔斷 服務降級 就是用來替換hystrix
特性
- 豐富的應用場景:Sentinel 承接了阿裡巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的範圍)、消息削峰填谷、叢集流量控制、實時熔斷下遊不可用應用等。
- 完備的實時監控:Sentinel 同時提供實時的監控功能。您可以在控制台中看到接入應用的單台機器秒級資料,甚至 500 台以下規模的叢集的彙總運作情況。
- 廣泛的開源生态:Sentinel 提供開箱即用的與其它開源架構/庫的整合子產品,例如與 Spring Cloud、Dubbo、gRPC 的整合。您隻需要引入相應的依賴并進行簡單的配置即可快速地接入 Sentinel。
sentinel使用
- sentinel提供了兩個服務元件:
一個是 sentinel 用來實作微服務系統中服務熔斷、降級等功能。這點和hystrix 類似
一個是 sentinel dashboard 用來監控微服務系統中流量調用等情況。這點和hystrix 類似
2. sentinel dashboard的安裝
# 1.下載下傳
- https://github.com/alibaba/Sentinel/releases
# 2.啟動
- 儀表盤是個jar包可以直接通過java指令啟動 如: java -jar 方式運作 預設端口為 8080
- java -Dserver.port=9191 -jar sentinel-dashboard-1.7.2.jar
預設的端口有沖突,是以啟動的時候指定端口啟動
# 3.通路web界面
- http://localhost:9191/#/login
# 4.登入
- 使用者名&密碼: sentinel
3.sentinel 實時監控服務
建立一個新的項目
# 1.建立項目引入依賴
com.alibaba.cloudspring-cloud-starter-alibaba-nacos-discoverycom.alibaba.cloudspring-cloud-starter-alibaba-sentinel
4.0.0org.springframework.bootspring-boot-starter-parent2.2.5.RELEASEcom.md09-nacosclient87890.0.1-SNAPSHOT09-nacosclient8789Demo project for Spring Boot1.82.2.1.RELEASEorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-testtestcom.alibaba.cloudspring-cloud-starter-alibaba-nacos-discoverycom.alibaba.cloudspring-cloud-starter-alibaba-sentinelcom.alibaba.cloudspring-cloud-alibaba-dependencies${spring.cloud.alibaba.version}pomimportorg.springframework.bootspring-boot-maven-plugin
# 2.配置檔案
server.port=8789
spring.application.name=nacosclient
spring.cloud.nacos.server-addr=localhost:8848
spring.cloud.nacos.discovery.server-addr=${spring.cloud.nacos.server-addr}
spring.cloud.sentinel.enabled=true # 開啟sentinel 預設開啟
spring.cloud.sentinel.transport.dashboard=localhost:9191 # 連接配接dashboard
spring.cloud.sentinel.transport.port=8719 # 與dashboard通信的端口
# 3.啟動服務
# 4.通路dashboard界面檢視服務監控
- 發現界面什麼都沒有?
- 預設情況下sentiel為延遲加載,不會在啟動之後立即建立服務監控,需要對服務進行調用時才會初始化
# 5.開發服務
@RestController
@Slf4j
public class SentinelController {
@GetMapping("/sentinel/test")
public String test(){
log.info("sentinel test");
return "sentinel test ";
}
@GetMapping("/sentinel/test1")
public String test1(){
log.info("sentinel test1");
return "sentinel test1 ";
}
}
# 6.啟動進行調用
- http://localhost:8789/sentinel/test
# 7.檢視監控界面
4.sentinel 流量控制
- 流量控制(flow control),其原理是監控應用流量的 QPS 或并發線程數等名額,當達到指定的門檻值時對流量進行控制,以避免被瞬時的流量高峰沖垮,進而保障應用的高可用性。
- 同一個資源可以建立多條限流規則。FlowSlot 會對該資源的所有限流規則依次周遊,直到有規則觸發限流或者所有規則周遊完畢。
-
一條限流規則主要由下面幾個因素組成,我們可以組合這些元素來實作不同的限流效果:
resource:資源名,即限流規則的作用對象
count: 限流門檻值
grade: 限流門檻值類型(QPS 或并發線程數)
limitApp: 流控針對的調用來源,若為 default 則不區分調用來源
strategy: 調用關系限流政策
controlBehavior: 流量控制效果(直接拒絕、Warm Up、勻速排隊)
- 流量控制主要有兩種統計類型,一種是統計并發線程數,另外一種則是統計 QPS
- 更多細節參見官網:https://github.com/alibaba/Sentinel/wiki/流量控制
QPS限流
# 1.配置QPS流量控制
# 2.測試
- 每秒隻能最大接收1個請求,超過1個報錯
線程數限流
# 1.配置線程數限流
# 2.通路測試
流控模式
- 直接:辨別流量控制規則到達門檻值直接觸發流量控制
- 關聯: 當兩個資源之間具有資源争搶或者依賴關系的時候,這兩個資源便具有了關聯。比如對資料庫同一個字段的讀操作和寫操作存在争搶,讀的速度過高會影響寫得速度,寫的速度過高會影響讀的速度。如果放任讀寫操作争搶資源,則争搶本身帶來的開銷會降低整體的吞吐量。可使用關聯限流來避免具有關聯關系的資源之間過度的争搶,舉例來說,read_db 和 write_db 這兩個資源分别代表資料庫讀寫,我們可以給 read_db 設定限流規則來達到寫優先的目的:設定 strategy 為 RuleConstant.STRATEGY_RELATE 同時設定 refResource 為 write_db。這樣當寫庫操作過于頻繁時,讀資料的請求會被限流。
- 鍊路限流: https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6
流控效果
- 直接拒絕:(RuleConstant.CONTROL_BEHAVIOR_DEFAULT)方式是預設的流量控制方式,當QPS超過任意規則的門檻值後,新的請求就會被立即拒絕,拒絕方式為抛出FlowException。
-
Warm Up:(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即預熱/冷啟動方式。當系統長期處于低水位的情況下,當流量突然增加時,直接把系統拉升到高水位可能瞬間把系統壓垮。通過"冷啟動",讓通過的流量緩慢增加,在一定時間内逐漸增加到門檻值上限,給冷系統一個預熱的時間,避免冷系統被壓垮。
更多:https://github.com/alibaba/Sentinel/wiki/限流---冷啟動
-
勻速排隊:(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式會嚴格控制請求通過的間隔時間,也即是讓請求以均勻的速度通過,對應的是漏桶算法。 隻能對請求進行排隊等待
更多:https://github.com/alibaba/Sentinel/wiki/流量控制-勻速排隊模式
4.熔斷降級
- https://github.com/alibaba/Sentinel/wiki/熔斷降級
- 除了流量控制以外,對調用鍊路中不穩定的資源進行熔斷降級也是保障高可用的重要措施之一。由于調用關系的複雜性,如果調用鍊路中的某個資源不穩定,最終會導緻請求發生堆積。Sentinel 熔斷降級會在調用鍊路中某個資源出現不穩定狀态時(例如調用逾時或異常比例升高),對這個資源的調用進行限制,讓請求快速失敗,避免影響到其它的資源而導緻級聯錯誤。當資源被降級後,在接下來的降級時間視窗之内,對該資源的調用都自動熔斷(預設行為是抛出 DegradeException)。
降級政策
- 平均響應時間 (DEGRADE_GRADE_RT):當 1s 内持續進入 N 個請求,對應時刻的平均響應時間(秒級)均超過門檻值(count,以 ms 為機關),那麼在接下的時間視窗(DegradeRule 中的 timeWindow,以 s 為機關)之内,對這個方法的調用都會自動地熔斷(抛出 DegradeException)。注意 Sentinel 預設統計的 RT 上限是 4900 ms,超出此門檻值的都會算作 4900 ms,若需要變更此上限可以通過啟動配置項 -Dcsp.sentinel.statistic.max.rt=xxx 來配置。
- 異常比例 (DEGRADE_GRADE_EXCEPTION_RATIO):當資源的每秒請求量 >= N(可配置),并且每秒異常總數占通過量的比值超過門檻值(DegradeRule 中的 count)之後,資源進入降級狀态,即在接下的時間視窗(DegradeRule 中的 timeWindow,以 s 為機關)之内,對這個方法的調用都會自動地傳回。異常比率的門檻值範圍是 [0.0, 1.0],代表 0% - 100%。
- 異常數 (DEGRADE_GRADE_EXCEPTION_COUNT):當資源近 1 分鐘的異常數目超過門檻值之後會進行熔斷。注意由于統計時間視窗是分鐘級别的,若 timeWindow 小于 60s,則結束熔斷狀态後仍可能再進入熔斷狀态。
5.SentinelResource注解
- https://github.com/alibaba/Sentinel/wiki/注解支援
@GetMapping("/sentinel/test1")
@SentinelResource(value = "aa",blockHandler = "fallBack",fallback = "fall")
public String test1(int id){
log.info("sentinel test1");
if(id<0)
throw new RuntimeException("非法參數!!!");
}
return "sentinel test1 :"+id;
}
//降級異常處理
public String fallBack(int id,BlockException e){
if(e instanceof FlowException){
return "目前服務已被流控! "+e.getClass().getCanonicalName();
}
return "目前服務已被降級處理! "+e.getClass().getCanonicalName();
}
//異常處理
public String fall(int id){
return "目前服務已不可用!";
}
八、.整合環境公共依賴
# 0.建構項目并引入依賴
1.8Hoxton.SR62.2.1.RELEASEcom.alibaba.cloudspring-cloud-alibaba-dependencies${spring.cloud.alibaba.version}pomimportorg.springframework.cloudspring-cloud-dependencies${spring-cloud.version}pomimport