Spring Cloud 高級進(jìn)階
微服務(wù)監(jiān)控之 Turbine 聚合監(jiān)控
參考上?Hystrix部分
微服務(wù)監(jiān)控之分布式鏈路追蹤技術(shù) Sleuth + Zipkin
分布式鏈路追蹤技術(shù)適?場景(問題場景)
場景描述
為了?撐?益增?的龐?業(yè)務(wù)量,我們會使?微服務(wù)架構(gòu)設(shè)計我們的系統(tǒng),使得 我們的系統(tǒng)不僅能夠通過集群部署抵擋流量的沖擊,?能根據(jù)業(yè)務(wù)進(jìn)?靈活的擴(kuò)展。那么,在微服務(wù)架構(gòu)下,?次請求少則經(jīng)過三四次服務(wù)調(diào)?完成,多則跨越?? 個甚?是上百個服務(wù)節(jié)點。那么問題接踵?來:
1)如何動態(tài)展示服務(wù)的調(diào)?鏈路?(?如A服務(wù)調(diào)?了哪些其他的服務(wù)---依賴
關(guān)系)
2)如何分析服務(wù)調(diào)?鏈路中的瓶頸節(jié)點并對其進(jìn)?調(diào)優(yōu)?(?如A—>B—>C,C 服務(wù)處理時間特別?)
3)如何快速進(jìn)?服務(wù)鏈路的故障發(fā)現(xiàn)?
這就是分布式鏈路追蹤技術(shù)存在的?的和意義
分布式鏈路追蹤技術(shù)
如果我們在?個請求的調(diào)?處理過程中,在各個鏈路節(jié)點都能夠記錄下?志,并 最終將?志進(jìn)?集中可視化展示,那么我們想監(jiān)控調(diào)?鏈路中的?些指標(biāo)就有希 望了~~~?如,請求到達(dá)哪個服務(wù)實例?請求被處理的狀態(tài)怎樣?處理耗時怎 樣?這些都能夠分析出來了...
分布式環(huán)境下基于這種想法實現(xiàn)的監(jiān)控技術(shù)就是就是分布式鏈路追蹤(全鏈路追 蹤)。
市場上的分布式鏈路追蹤?案
分布式鏈路追蹤技術(shù)已然成熟,產(chǎn)品也不少,國內(nèi)外都有,?如
Spring Cloud Sleuth + Twitter Zipkin
阿?巴巴的“鷹眼”
?眾點評的“CAT”
美團(tuán)的“Mtrace”
京東的“Hydra”
新浪的“Watchman”
另外還有最近也被提到很多的Apache Skywalking。
分布式鏈路追蹤技術(shù)核?思想
本質(zhì):記錄?志,作為?個完整的技術(shù),分布式鏈路追蹤也有??的理論和概念
微服務(wù)架構(gòu)中,針對請求處理的調(diào)?鏈可以展現(xiàn)為?棵樹,示意如下


上圖標(biāo)識?個請求鏈路,?條鏈路通過TraceId唯?標(biāo)識,span標(biāo)識發(fā)起的請求信 息,各span通過parrentId關(guān)聯(lián)起來
注意:我們往往把Spring Cloud Sleuth 和 Zipkin ?起使?,把 Sleuth 的數(shù)據(jù)信 息發(fā)送給 Zipkin 進(jìn)?聚合,利? Zipkin 存儲并展示數(shù)據(jù)。

微服務(wù)統(tǒng)?認(rèn)證?案 Spring Cloud OAuth2 + JWT



第?代 Spring Cloud 核?組件 (SCA)
第?代 Spring Cloud (主要是 SCN)很多組件已經(jīng)進(jìn)?停更維護(hù)模式。
Spring Cloud:Net?ix,Spring官?,SCA(被Spring官?認(rèn)可) 注意:市場上主要使?的還是SCN,SCA?套框架的集合
Alibaba 更進(jìn)?步,搞出了Spring Cloud Alibaba(SCA),SCA 是由?些阿?巴巴 的開源組件和云產(chǎn)品組成的,2018年,Spring Cloud Alibaba 正式?住了 Spring Cloud 官?孵化器。
- Nacos(服務(wù)注冊中?、配置中?)
- Sentinel哨兵(服務(wù)的熔斷、限流等)
- Dubbo RPC/LB
- Seata分布式事務(wù)解決?案
nacos
下載 nacos 編譯后壓縮包 nacos-server-$version.zip 包。
啟動服務(wù)器
Linux/Unix/Mac 啟動命令(standalone代表著單機(jī)模式運行,非集群模式):
sh startup.sh -m standalone
Windows 啟動命令(standalone代表著單機(jī)模式運行,非集群模式):
cmd startup.cmd -m standalone
保護(hù)閾值:可以設(shè)置為0-1之間的浮點數(shù),它其實是?個?例值(當(dāng)前服務(wù)健康實例數(shù)/當(dāng)前服務(wù)總實例數(shù))。
保護(hù)閾值的意義在于當(dāng)服務(wù)A健康實例數(shù)/總實例數(shù) < 保護(hù)閾值 的時候,nacos將會把該服務(wù)所有的實例信息全部提供給消費者,消費者可能訪問到不健康的實例,保證了整個系統(tǒng)的?個可?。
Nacos 數(shù)據(jù)模型(領(lǐng)域模型)
Namespace 命名空間、Group 分組、集群這些都是為了進(jìn)?歸類管理,把服務(wù)和配置?件進(jìn)?歸類,歸類之后就可以實現(xiàn)?定的效果,?如隔離
?如,對于服務(wù)來說,不同命名空間中的服務(wù)不能夠互相訪問調(diào)?
Namespace:命名空間,對不同的環(huán)境進(jìn)?隔離,?如隔離開發(fā)環(huán)境、測試環(huán)境和?產(chǎn)環(huán)境
Group:分組,將若?個服務(wù)或者若?個配置集歸為?組,通常習(xí)慣?個系統(tǒng)歸為?個組
Service:某?個服務(wù),?如簡歷微服務(wù)
DataId:配置集或者可以認(rèn)為是?個配置?件
Namespace + Group + Service 如同 Maven 中的GAV坐標(biāo),GAV坐標(biāo)是為了鎖定Jar,?這?是為了鎖定服務(wù)
Namespace + Group + DataId 如同 Maven 中的GAV坐標(biāo),GAV坐標(biāo)是為了鎖定Jar,?這?是為了鎖定配置?件
SCA Nacos 服務(wù)注冊和配置中?
Nacos (Dynamic Naming and Configuration Service)是阿?巴巴開源的?個針對微服務(wù)架構(gòu)中服務(wù)發(fā)現(xiàn)、配置管理和服務(wù)管理平臺。
Nacos就是注冊中?+配置中?的組合(Nacos=Eureka+Config+Bus)
官?:https://nacos.io 下載地址:https://github.com/alibaba/Nacos
Nacos功能特性
- 服務(wù)發(fā)現(xiàn)與健康檢查
- 動態(tài)配置管理
- 動態(tài)DNS服務(wù)
- 服務(wù)和元數(shù)據(jù)管理(管理平臺的?度,nacos也有?個ui??,可以看到注冊的服務(wù)及其實例信息(元數(shù)據(jù)信息)等),動態(tài)的服務(wù)權(quán)重調(diào)整、動態(tài)服務(wù)優(yōu)雅下線,都可以去做
SCA Sentinel 分布式系統(tǒng)的流量防衛(wèi)兵
Sentinel是?個?向云原?微服務(wù)的流量控制、熔斷降級組件。替代Hystrix,針對問題:服務(wù)雪崩、服務(wù)降級、服務(wù)熔斷、服務(wù)限流。
Sentinel 分為兩個部分:
核?庫:(Java 客戶端)不依賴任何框架/庫,能夠運?于所有 Java 運?時環(huán)
境,同時對 Dubbo / Spring Cloud 等框架也有較好的?持。
控制臺:(Dashboard)基于 Spring Boot 開發(fā),打包后可以直接運?,不需
要額外的 Tomcat 等應(yīng)?容器。
Nacos + Sentinel + Dubbo 三劍合璧
刪除OpenFeign 和 Ribbon,使?Dubbo RPC 和 Dubbo LB。
SCA ?結(jié)
1)因為內(nèi)容重疊,SCA 中的分布式事務(wù)解決?案 Seata 會在緊接著的Mysql課程中 講解。 2)SCA實際上發(fā)展了三條線
第?條線:開源出來?些組件 第?條線:阿?內(nèi)部維護(hù)了?個分?,??業(yè)務(wù)線使? 第三條線:阿?云平臺部署?套,付費使? 從戰(zhàn)略上來說,SCA更是為了貼合阿?云。 ?前來看,開源出來的這些組件,推?及普及率不?,社區(qū)活躍度不?,穩(wěn)定性 和體驗度上仍需進(jìn)?步提升,根據(jù)實際使?來看Sentinel的穩(wěn)定性和體驗度要好 于Nacos。
作業(yè)
編程題:根據(jù)如下描述,改造 Spring Cloud(上)的作業(yè),完成以下要求:
1、Eureka 注冊中心替換為 Nacos 注冊中心
2、Config + Bus 配置中心替換為 Nacos 配置中心
3、Feign 調(diào)用 替換為 Dubbo RPC 調(diào)用
4、使用 Sentinel 對 GateWay 網(wǎng)關(guān)的入口資源進(jìn)行限流(限流參數(shù)自定義并完成測試即可)
注意:所有替換組件使用單節(jié)點即可
作業(yè)資料說明:
1、提供資料:代碼工程、驗證及講解視頻。
2、講解內(nèi)容包含:題目分析、實現(xiàn)思路、代碼講解。
3、效果展示
這個作業(yè)可以根據(jù)之前的圖進(jìn)行下列的改造:

首先,保證基本配置不變。比如 nginx 配置依舊得到保留。
第一步: 啟用 Nacos 服務(wù)端
使用單機(jī)模式進(jìn)行啟動 sh startup.sh -m standalone。Nacos 將默認(rèn)使用 8848 端口.
訪問地址為:http://localhost:8848/nacos/
第二步: 集成 Nacos 客戶端發(fā)現(xiàn)服務(wù)配置
lagou-parent 的 pom 文件中引入依賴
<dependencyManagement/>
</dependencies/>
...
<!--SCA -->
<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>
<!--SCA -->
</dependencies>
</dependencyManagement>
在?程中注釋掉 eureka 客戶端相關(guān)依賴, 引? nacos客戶端依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
bootstrap.yml 新增以下配置
spring:
cloud:
nacos:
discovery:
# 配置 nacos server地址
server-addr: 192.168.3.29:8848
然后根據(jù)此種方式依次改造 code, email, gateway 和 user 微服務(wù)。
【可選操作】這里順便對 Nacos Server 數(shù)據(jù)持久化改造, 方便 nacos 服務(wù)端每次重啟后還得重新進(jìn)行配置.
- 執(zhí)行項目中的
${nacoshome}/conf/nacos-mysql.sqlSQL 語句。 - 修改
${nacoshome}/conf/application.properties,增加 Mysql 數(shù)據(jù)源配置
spring.datasource.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?
characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456
第三步: Nacos Nacos 客戶端配置集成
- 微服務(wù)中如何鎖定 Nacos Server 中的配置?件(dataId)
通過 Namespace + Group + dataId 來鎖定配置?件.
目前已知 Namespace 不指定就默認(rèn)public
Group不指定就默認(rèn) DEFAULT_GROUP
dataId 的完整格式如下 ${prefix}-${spring.profile.active}.${file-extension}
先在網(wǎng)頁中進(jìn)行新建配置 lagou-cloud-config.yaml
spring:
# 1. 數(shù)據(jù)庫配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: YOUR-URL
username: YOUR-USER-NAME
password: YOUR-PASSWORD
# 2. 郵箱配置
mail:
## 發(fā)送郵件服務(wù)器
host: YOUR-HOST
## 發(fā)送郵件的郵箱地址
username: YOUR-USER-NAME
## 客戶端授權(quán)碼,不是郵箱密碼,這個在qq郵箱設(shè)置里面自動生成的
password: YOUR-PASSWORD
# 3. 防暴刷配置:限制單個客戶端ip最新 X 分鐘的請求注冊接口不能超過 Y 次
myconfig:
x: 2
y: 2
- 客戶端添加依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos?config</artifactId>
</dependency
和 bootstap.yml 配置
spring:
cloud:
nacos:
config:
server-addr: ${myServerIp}:8848
namespace: public
group: DEFAULT_GROUP
# 前綴
prefix: lagou-cloud-config
# 拓展名,默認(rèn)為 properties
file-extension: yaml
- 通過@Value讀取屬性, 通過 @RefreshScope 注解使支持自動刷新.
舉例改造 email 服務(wù)
package com.lagou.edu.service.impl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
...
...
@Service
@RefreshScope
public class EmailServiceImpl implements EmailService {
@Value("${spring.mail.username}")
private String fromEmailAddress;
/**
* @param toEmailAddress 收件人郵箱
* @param code 幾位數(shù)的驗證碼
*/
@Override
public void sendSimpleMail(String toEmailAddress, String code) {
...
...
}
}
測試驗證: email 服務(wù)是否可以讀取配置.
http://edu.lagou.com:8082/email/acc8226@vip.qq.com/123456
第四步: Sentinel 集成
服務(wù)端依舊是通過 java -jar 的方式啟動: java -jar ./sentinel-dashboard-1.7.2.jar
- 客戶端 pom.xml 引用依賴
<!--Sentinel 核?環(huán)境 依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
- 客戶端配置 yml
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080 # sentinel dashboard/console
port: 8719 # sentinel會在該端?啟動http server,那么這樣 的話,控制臺定義的?些限流等規(guī)則才能發(fā)送傳遞過來, #如果8719端?被占?,那么會依次+1
- 簡單配置流控規(guī)則
這里順便對 Sentinel 進(jìn)行數(shù)據(jù)持久化改造【可選操作】
lagou-service-email-degrade-rules
[
{
"resource":"/email/acc8226@vip.qq.com/123456",
"grade":2,
"count":1,
"timeWindow":5
}
]
lagou-service-email-?ow-rules
[
{"resource":"/email/acc8226@vip.qq.com/123456",
"limitApp":"default",
"grade":1,
"count":1,
"strategy":0,
"controlBehavior":0,
"clusterMode":false}
]
<!-- Sentinel?持采? Nacos 作為規(guī)則配置數(shù)據(jù)源,引?該適配依賴 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
spring:
cloud:
sentinel:
datasource:
# 此處的flow為?定義數(shù)據(jù)源名
flow: # 流控規(guī)則
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
data-id: ${spring.application.name}-flow-rules
groupId: DEFAULT_GROUP
data-type: json
# 類型來?RuleType類 流控規(guī)則
rule-type: flow
degrade: # 流控規(guī)則
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
data-id: ${spring.application.name}-degrade-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow
第五步: feign 換成 dubbo
- 注釋掉父工程的 spring-boot-devtools 依賴
<!--熱部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
- 客戶端配置
1.創(chuàng)建 lagou-service-dubbo-api 工程. 這里包含了共用的接口.
2.添加dubbo 相關(guān)依賴
<!--spring cloud alibaba dubbo 依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
</dependency>
3.實現(xiàn)類使用 org.apache.dubbo.config.annotation.Service 注解. 而非spring的注解.
4.yaml 進(jìn)行配置
dubbo:
scan:
# dubbo 服務(wù)掃描基準(zhǔn)包
base-packages: com.lagou.edu.service.impl
protocol:
# dubbo 協(xié)議
name: dubbo
# dubbo 協(xié)議端?( -1 表示?增端?,從 20880 開始)
port: -1
registry:
# 掛載到 Spring Cloud 的注冊中?
address: spring-cloud://192.168.3.29
spring:
main:
allow-bean-definition-overriding: true
具體實現(xiàn):
改造 email 微服務(wù)
- 刪除 feigen 和 robbion 配置. 轉(zhuǎn)用 dubbo 相關(guān)配置. 同樣需要配置下spring.main.allow-bean-de?nition-overriding=true
2.將 EmailService 接口移動至 lagou-sercie-dobbo-api 服務(wù)
3.service 添加 dubbo 的 @Service 注解
4.配置 bootstrap.yml, 添加以下內(nèi)容。
# 只提供服務(wù)
dubbo:
scan:
# 服務(wù)掃描基準(zhǔn)包
base-packages: com.lagou.edu.service.impl
protocol:
# dubbo 協(xié)議
name: dubbo
# dubbo 協(xié)議端?( -1 表示?增端?,從 20880 開始)
port: -1
registry:
# 掛載到 Spring Cloud 的注冊中?
address: spring-cloud://192.168.3.29
改造 code 微服務(wù)
- 刪除 feigen 和 robbion 配置. 轉(zhuǎn)用 dubbo 相關(guān)配置. 同樣需要配置下spring.main.allow-bean-de?nition-overriding=true
2.將 CodeService 接口移動至 lagou-sercie-dobbo-api 服務(wù)
3.service 添加 dubbo 的 @Service 注解
4.配置 bootstrap.yml, 添加以下內(nèi)容。
# 只提供服務(wù)
dubbo:
scan:
# dubbo 服務(wù)掃描基準(zhǔn)包
base-packages: com.lagou.edu.service.impl
protocol:
# dubbo 協(xié)議
name: dubbo
# dubbo 協(xié)議端?( -1 表示?增端?,從 20880 開始)
port: 20881
host: 192.168.3.29
registry:
# 掛載到 Spring Cloud 的注冊中?
address: spring-cloud://192.168.3.29
# 還使用服務(wù)
cloud:
# 訂閱服務(wù)提供?的應(yīng)?列表,訂閱多個服務(wù)提供者使? "," 連接
subscribed-services: lagou-service-email,lagou-service-user
驗證: 發(fā)送驗證碼的服務(wù)是否正常
http://localhost:8081/code/create/acc8226@qq.com
改造 user 微服務(wù)
- 刪除 feigen 和 robbion 配置. 轉(zhuǎn)用 dubbo 相關(guān)配置. 同樣需要配置下spring.main.allow-bean-de?nition-overriding=true
2.將 UserService 接口移動至 lagou-sercie-dobbo-api 服務(wù) - service 添加 dubbo 的 @Service 注解
- 配置 bootstrap.yml, 添加以下內(nèi)容。
# 只提供服務(wù)
dubbo:
scan:
# dubbo 服務(wù)掃描基準(zhǔn)包
base-packages: com.lagou.edu.service.impl
protocol:
# dubbo 協(xié)議
name: dubbo
# dubbo 協(xié)議端?( -1 表示?增端?,從 20880 開始)
port: 20882
host: 192.168.3.29
registry:
# 掛載到 Spring Cloud 的注冊中?
address: spring-cloud://192.168.3.29
# 還使用服務(wù)
cloud:
# 訂閱服務(wù)提供?的應(yīng)?列表,訂閱多個服務(wù)提供者使? "," 連接
subscribed-services: lagou-service-code
驗證: 注冊功能是否好使
http://localhost:8077/user/register/acc8226@qq.com/123456/989410
第六步網(wǎng)關(guān)改造
詳見第四步提到的 Sentinel 集成方案.
pom 導(dǎo)入 Sentinel 核心依賴
<!--Sentinel 核?環(huán)境 依賴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
bootstrap.yml 需要新增以下配置
spring:
cloud:
sentinel:
transport:
# sentinel服務(wù)端地址
dashboard: 127.0.0.1:8080
# sentinel dashboard/console
port: 8719 # sentinel會在該端?啟動 http server,那么這樣的話,控制臺定義的?些限流等規(guī)則才能發(fā)送傳遞過來,
# 如果8719端?被占?,那么會依次 +1
# 如果發(fā)現(xiàn)監(jiān)聽的地址不對的話,可以在sentinel客戶端配置中加入客戶端ip配置
# client-ip: 192.168.0.7
測試驗證:添加每秒只能訪問1次的限制
測試地址:http://edu.lagou.com/api/user/info/5d1ad7d9-53ba-4566-8a39-6a96078545da
參考
nacos 中文官網(wǎng)
https://nacos.io/zh-cn/
SpringCloud、dubbo 和 druid 問題總結(jié) - 星火燎原智勇 - 博客園
https://www.cnblogs.com/liang1101/p/12702631.html