文章目錄
- Sentinel介紹
- Spring Cloud Gateway集成Sentinel
- pom依賴
- Sentinel配置
- Sentinel集成Nacos作為數據源
- 自定義降級響應
Sentinel介紹
? 隨著微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 是面向分布式、多語言異構化服務架構的流量治理組件,主要以流量為切入點,從流量路由、流量控制、流量整形、熔斷降級、系統自適應過載保護、熱點流量防護等多個維度來幫助開發者保障微服務的穩定性。 — 摘自官網
Spring Cloud Gateway集成Sentinel
pom依賴
? 添加spring cloud gateway sentinel的starter依賴。
<!-- SpringCloud Alibaba Sentinel Gateway -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
Sentinel配置
? 引入starter依賴后只需要一些配置就可以實現網關對于后端API的流控,降級等功能,具體的實現starter提供實現,Spring Cloud Gateway可以讓spring-cloud-alibaba-sentinel-gateway
中的自動化配置生效,配置前綴前綴為spring.cloud.sentinel.filter.scg
。
- Spring Cloud Alibaba Sentinel 提供了這些配置選項
配置項 | 含義 | 默認值 |
---|---|---|
spring.cloud.sentinel.enabled | Sentinel自動化配置是否生效 | true |
spring.cloud.sentinel.eager | 是否提前觸發 Sentinel 初始化 | false |
spring.cloud.sentinel.transport.port | 應用與Sentinel控制臺交互的端口,應用本地會起一個該端口占用的HttpServer(可以不配置) | 8719 |
spring.cloud.sentinel.transport.dashboard | Sentinel 控制臺地址(可以配置host:port,這樣就不用單獨配置port) | |
spring.cloud.sentinel.transport.heartbeat-interval-ms | 應用與Sentinel控制臺的心跳間隔時間 | |
spring.cloud.sentinel.transport.client-ip | 此配置的客戶端IP將被注冊到 Sentinel Server 端 | |
spring.cloud.sentinel.filter.order | Servlet Filter的加載順序。Starter內部會構造這個filter | Integer.MIN_VALUE |
spring.cloud.sentinel.filter.url-patterns | 數據類型是數組。表示Servlet Filter的url pattern集合 | /* |
spring.cloud.sentinel.filter.enabled | Enable to instance CommonFilter | true |
spring.cloud.sentinel.metric.charset | metric文件字符集 | UTF-8 |
spring.cloud.sentinel.metric.file-single-size | Sentinel metric 單個文件的大小 | |
spring.cloud.sentinel.metric.file-total-count | Sentinel metric 總文件數量 | |
spring.cloud.sentinel.log.dir | Sentinel 日志文件所在的目錄 | |
spring.cloud.sentinel.log.switch-pid | Sentinel 日志文件名是否需要帶上pid | false |
spring.cloud.sentinel.servlet.block-page | 自定義的跳轉 URL,當請求被限流時會自動跳轉至設定好的 URL | |
spring.cloud.sentinel.flow.cold-factor | https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81— %E5%86%B7%E5%90%AF%E5%8A%A8[冷啟動因子] | 3 |
spring.cloud.sentinel.zuul.order.pre | SentinelZuulPreFilter 的 order | 10000 |
spring.cloud.sentinel.zuul.order.post | SentinelZuulPostFilter 的 order | 1000 |
spring.cloud.sentinel.zuul.order.error | SentinelZuulErrorFilter 的 order | -1 |
spring.cloud.sentinel.scg.fallback.mode | Spring Cloud Gateway 熔斷后的響應模式(選擇 redirect or response ) | |
spring.cloud.sentinel.scg.fallback.redirect | Spring Cloud Gateway 響應模式為 ‘redirect’ 模式對應的重定向 URL | |
spring.cloud.sentinel.scg.fallback.response-body | Spring Cloud Gateway 響應模式為 ‘response’ 模式對應的響應內容 | |
spring.cloud.sentinel.scg.fallback.response-status | Spring Cloud Gateway 響應模式為 ‘response’ 模式對應的響應碼 | 429 |
spring.cloud.sentinel.scg.fallback.content-type | Spring Cloud Gateway 響應模式為 ‘response’ 模式對應的 content-type | application/json |
請注意。這些配置只有在 Servlet 環境下才會生效,RestTemplate 和 Feign 針對這些配置都無法生效
? 表格中的配置看似很多,實際上應用的并不多,有些配置使用默認值即可,根據實際需求配置響應參數即可,這里我給出一個我本地的一個配置示例,配置直接使用可能有問題,因為我這里只摘取了spring.cloud.gateway.sentinel
的相關配置,僅供參考。
spring:application:name: ruuby-gatewayprofiles:active: devcloud:gateway:routes:- id: account-svcuri: lb://account-svcpredicates:- Path=/gateway/account/**filters:- StripPrefix=1sentinel:# 取消控制臺懶加載eager: truetransport:# 控制臺地址dashboard: 127.0.0.1:8080filter:enabled: true# 配置默認fallback,也可以編碼自定義fallback scg.fallback:mode: responseresponse-status: 444response-body: 1234scg:order: -100
? 配置完成后啟動網關,這時候可以在Sentinel
控制臺中看到gateway已經注冊到了Sentinel控制臺,但是沒有任何資源,這時候需要手動創建資源,資源就是Sentinel系統保護的一個單元。在Spring Cloud Gateway中配置的資源可以是url,也可以是轉發服務的服務id,也就是服務發現的service,如上配置中的account-svc
,所以我們在Sentinel
控制臺就可以創建熔斷或限流規則,我這里創建了一個流控規則,API名稱就是account-svc
,API類型是Route ID
,閾值類型是QPS
,單機的閾值是0,如下圖:
? 這就意味著一個請求都不會轉發到account-svc服務的請求,因為閾值設置為0,請求結果如下:
account-svc
是一個使用Spring Cloud Alibaba
開發腳手架開發的一個業務服務,后面在講到服務發現注冊的時候會把該服務的一些代碼寫出來,也可以參考GitHub。
Sentinel集成Nacos作為數據源
? 在生產系統中,我們往往不會對接Sentinel的控制臺,而且想在服務啟動時就已經把Sentinel控制的資源配置好,這個時候我們可以將Sentinel控制的數據源配置起來,這里就以Nacos為例,將Sentinel的資源配置通過Nacos配置中心管理。
? spring-cloud-alibaba-sentinel-gateway
starter中已經提供了Sentinel DataSource的相關依賴,我們在使用時只需要配置即可。配置內容如下:
- ruuby-gateway-dev.yml配置
server:port: 8081spring:application:name: ruuby-gatewayprofiles:active: devcloud:nacos:username: "nacos"password: "nacos"discovery:# 服務注冊中心地址server-addr: 127.0.0.1:8848# 阿里云平臺ak,sk# access-key:# secret-key:namespace: 3ef5e608-6ee8-4881-8e50-ed47a5a04af2config:server-addr: 127.0.0.1:8848# 阿里云平臺ak,sk# access-key:# secret-key:# 配置文件格式file-extension: ymlshared-configs:- ${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}namespace: 3ef5e608-6ee8-4881-8e50-ed47a5a04af2group: DEFAULT-GROUPgateway:routes:- id: account-svcuri: lb://account-svcpredicates:- Path=/gateway/account/**filters:- StripPrefix=1sentinel:# 取消控制臺懶加載eager: truetransport:# 控制臺地址dashboard: 127.0.0.1:8080# nacos配置持久化datasource:ds1:nacos:server-addr: 127.0.0.1:8848dataId: ${spring.application.name}-sentinel-${spring.profiles.active}.jsonnamespace: 3ef5e608-6ee8-4881-8e50-ed47a5a04af2groupId: DEFAULT_GROUPdata-type: jsonrule-type: gw-flowfilter:enabled: true# 配置默認fallback,也可以編碼自定義fallback scg.fallback:mode: responseresponse-status: 444response-body: 1234scg:order: -100
? spring.cloud.sentinel.datasource
配置制定數據源,數據源可以是多個,這里使用的是nacos
,配置的Sentinel規則的配置文件是${spring.application.name}-sentinel-${spring.profiles.active}.json
也就是ruuby-gateway-sentinel-dev.json
,配置內容格式為json
,該配置內容如下:
[{"resource": "account-svc","count": 5,"grade": 0,"limitApp": "default"}
]
? 啟動網關,這時可以在Sentinel控制臺上看到我們在json文件中配置好的流控規則,如下圖:
? 這時如果在Nacos修改參數會同步到Sentinel控制臺,但是從Sentinel控制臺修改參數不會同步到Nacos配置中心,所以生產上如果使用Nacos作為Sentinel數據源的話,建議從Nacos上修改Sentinel資源參數。
自定義降級響應
? 通過上面的實驗,我們可以知道通過配置spring.cloud.gateway.sentinel.filter.scg.fallback
可以實現服務降級后的返回,Spring Cloud Gateway Sentinel也提供了接口讓開發人員實現自定義的服務降級響應,只要實現BlockRequestHandler
即可,代碼如下:
@Slf4j
public class SentinelFallbackHandler implements BlockRequestHandler {@Overridepublic Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange,Throwable throwable) {log.info(LogUtil.marker(), "SCG Sentinel blocked!");return ServerResponse.status(444).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue("SCG Sentinel blocked!"));}
}
? 自定義降級配置代碼如下:
@Configuration
public class GatewayConfiguration {@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public SentinelFallbackHandler sentinelFallbackHandler() {return new SentinelFallbackHandler();}
}
注:使用自定義降級時不能配置spring.cloud.gateway.sentinel.filter.scg.fallback,配置的優先級是大于自定義實現的
? 測試結果如下: