Sentinel(十九)之主流框架的适配
轉載自??主流框架的適配
注:適配模塊僅提供相應適配功能,若希望接入 Sentinel 控制臺,請務必參考?Sentinel 控制臺文檔。
云原生微服務體系
Spring Cloud
Spring Cloud Alibaba?致力于提供微服務開發的一站式解決方案。Sentinel 與 Spring Boot/Spring Cloud 的整合見?Sentinel Spring Cloud Starter。
Spring Cloud Alibaba 默認為 Sentinel 整合了 Servlet、RestTemplate、FeignClient 和 Spring WebFlux。Sentinel 在 Spring Cloud 生態中,不僅補全了 Hystrix 在 Servlet 和 RestTemplate 這一塊的空白,而且還完全兼容了 Hystrix 在 FeignClient 中限流降級的用法,并且支持運行時靈活地配置和調整限流降級規則。
Spring Cloud Alibaba Sentinel 的示例可以參考?sentinel-guide-spring-cloud
Quarkus
注:從 1.8.0 版本開始支持,需要 Java 8 及以上版本。
Sentinel 提供針對 Quarkus 微服務的適配模塊(支持 native image),可以很方便地將 JAX-RS Web 服務接入并進行高可用防護,同時支持注解方式自定義埋點(基于 CDI)。
相關模塊:
- sentinel-jax-rs-quarkus-adapter
- sentinel-annotation-quarkus-adapter
Web 適配
Web Servlet
Sentinel 提供針對 Servlet 的原生整合,可以對 Web 請求進行流量控制。使用時需引入以下模塊(以 Maven 為例):
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-web-servlet</artifactId><version>x.y.z</version> </dependency>您只需要在 Web 容器中的?web.xml?配置文件中進行如下配置即可開啟 Sentinel 支持:
<filter><filter-name>SentinelCommonFilter</filter-name><filter-class>com.alibaba.csp.sentinel.adapter.servlet.CommonFilter</filter-class> </filter><filter-mapping><filter-name>SentinelCommonFilter</filter-name><url-pattern>/*</url-pattern> </filter-mapping>若是 SpringBoot 應用可以通過FilterRegistrationBean類進行配置,例如:
@Configuration public class FilterConfig {@Beanpublic FilterRegistrationBean sentinelFilterRegistration() {FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();registration.setFilter(new CommonFilter());registration.addUrlPatterns("/*");registration.setName("sentinelFilter");registration.setOrder(1);return registration;} }接入 filter 之后,所有訪問的 Web URL 就會被自動統計為 Sentinel 的資源,可以針對單個 URL 維度進行流控。若希望區分不同 HTTP Method,可以將?HTTP_METHOD_SPECIFY?這個 init parameter 設為 true,給每個 URL 資源加上前綴,比如?GET:/foo。
限流處理邏輯:默認情況下,當請求被限流時會返回默認的提示頁面?Blocked by Sentinel (flow limiting)。您也可以通過 JVM 參數?-Dcsp.sentinel.web.servlet.block.page?或代碼中調用?WebServletConfig.setBlockPage(blockPage)?方法設定自定義的跳轉 URL,當請求被限流時會自動跳轉至設定好的 URL。同樣您也可以實現?UrlBlockHandler?接口并編寫定制化的限流處理邏輯,然后將其注冊至?WebCallbackManager?中。
提示:1.7.0 版本開始默認的限流頁面 HTTP 返回碼是?429。您可以通過?csp.sentinel.web.servlet.block.status?配置項自定義限流頁面的 HTTP 狀態碼。
按來源限流:若希望對 HTTP 請求按照來源限流,則可以自己實現?RequestOriginParser?接口從 HTTP 請求中解析 origin 并注冊至?WebCallbackManager?中。注意來源數目不能太多,若太多請自定義埋點作為參數傳入并使用熱點規則。
注意:Sentinel Web Filter 會將每個到來的不同的 URL 都作為不同的資源處理,因此對于 REST 風格的 API,需要自行實現?UrlCleaner?接口清洗一下資源(比如將滿足?/foo/:id?的 URL 都歸到?/foo/*?資源下),然后將其注冊至?WebCallbackManager中。否則會導致資源數量過多,超出資源數量閾值(目前是 6000)時多出的資源的規則將?不會生效。
從 1.6.3 版本開始,UrlCleaner?還可以來過濾掉不希望統計的 URL,只需要在 UrlCleaner 中將不希望統計的 URL 轉換成空字符串("")即可。示例:
WebCallbackManager.setUrlCleaner(new UrlCleaner() {@Overridepublic String clean(String originUrl) {if (originUrl == null || originUrl.isEmpty()) {return originUrl;}// 比如將滿足 /foo/{id} 的 URL 都歸到 /foo/*if (originUrl.startsWith("/foo/")) {return "/foo/*";}// 不希望統計 *.ico 的資源文件,可以將其轉換為 empty string (since 1.6.3)if (originUrl.endsWith(".ico")) {return "";}return originUrl;} });如果您正在使用 Spring Boot / Spring Cloud,那么可以通過引入 Spring Cloud Alibaba Sentinel 來更方便地整合 Sentinel,詳情請見?Spring Cloud Alibaba 文檔。
Spring WebFlux
注:從 1.5.0 版本開始支持,需要 Java 8 及以上版本。
Sentinel 提供與 Spring WebFlux 的整合模塊,從而 Reactive Web 應用也可以利用 Sentinel 的流控降級來保障穩定性。該整合模塊基于 Sentinel Reactor Adapter 實現。
使用時需引入以下模塊(以 Maven 為例):
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-spring-webflux-adapter</artifactId><version>x.y.z</version> </dependency>使用時只需注入對應的?SentinelWebFluxFilter?實例以及?SentinelBlockExceptionHandler?實例即可。比如:
@Configuration public class WebFluxConfig {private final List<ViewResolver> viewResolvers;private final ServerCodecConfigurer serverCodecConfigurer;public WebFluxConfig(ObjectProvider<List<ViewResolver>> viewResolversProvider,ServerCodecConfigurer serverCodecConfigurer) {this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);this.serverCodecConfigurer = serverCodecConfigurer;}@Bean@Order(-1)public SentinelBlockExceptionHandler sentinelBlockExceptionHandler() {// Register the block exception handler for Spring WebFlux.return new SentinelBlockExceptionHandler(viewResolvers, serverCodecConfigurer);}@Bean@Order(-1)public SentinelWebFluxFilter sentinelWebFluxFilter() {// Register the Sentinel WebFlux filter.return new SentinelWebFluxFilter();} }您可以在?WebFluxCallbackManager?注冊回調進行定制:
- setBlockHandler:注冊函數用于實現自定義的邏輯處理被限流的請求,對應接口為?BlockRequestHandler。默認實現為?DefaultBlockRequestHandler,當被限流時會返回類似于下面的錯誤信息:Blocked by Sentinel: FlowException。
- setUrlCleaner:注冊函數用于 Web 資源名的歸一化。函數類型為?(ServerWebExchange, String) → String,對應含義為?(webExchange, originalUrl) → finalUrl。
- setRequestOriginParser:注冊函數用于從請求中解析請求來源。函數類型為?ServerWebExchange → String。
相關示例:sentinel-demo-spring-webflux
JAX-RS (Java EE)
注:從 1.8.0 版本開始原生支持。若您的服務是 Spring Web 服務,可參考 Spring Web 適配文檔接入。
sentinel-jax-rs-adapter
RPC 適配
Dubbo
Sentinel 提供 Dubbo 的相關適配?Sentinel Dubbo Adapter,主要包括針對 Service Provider 和 Service Consumer 實現的 Filter。相關模塊:
- sentinel-apache-dubbo-adapter(兼容 Apache Dubbo 2.7.x 及以上版本,自 Sentinel 1.5.1 開始支持)
- sentinel-dubbo-adapter(兼容 Dubbo 2.6.x 版本)
對于 Apache Dubbo?2.7.x?及以上版本,使用時需引入以下模塊(以 Maven 為例):
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-apache-dubbo-adapter</artifactId><version>x.y.z</version> </dependency>對于 Dubbo?2.6.x?及以下版本,使用時需引入以下模塊(以 Maven 為例):
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-dubbo-adapter</artifactId><version>x.y.z</version> </dependency>引入此依賴后,Dubbo 的服務接口和方法(包括調用端和服務端)就會成為 Sentinel 中的資源,在配置了規則后就可以自動享受到 Sentinel 的防護能力。
注:若希望接入 Dashboard,請參考?接入控制臺的步驟。只引入 Sentinel Dubbo Adapter 無法接入控制臺!
若不希望開啟 Sentinel Dubbo Adapter 中的某個 Filter,可以手動關閉對應的 Filter,比如:
<!-- 關閉 Sentinel 對應的 Service Consumer Filter --> <dubbo:consumer filter="-sentinel.dubbo.consumer.filter"/>限流粒度可以是服務接口和服務方法兩種粒度:
- 服務接口:resourceName 為?接口全限定名,如?com.alibaba.csp.sentinel.demo.dubbo.FooService
- 服務方法:resourceName 為?接口全限定名:方法簽名,如?com.alibaba.csp.sentinel.demo.dubbo.FooService:sayHello(java.lang.String)
Sentinel Dubbo Adapter 還支持配置全局的 fallback 函數,可以在 Dubbo 服務被限流/降級/負載保護的時候進行相應的 fallback 處理。用戶只需要實現自定義的?DubboFallback?接口,并通過?DubboFallbackRegistry?注冊即可。默認情況會直接將?BlockException?包裝后拋出。同時,我們還可以配合?Dubbo 的 fallback 機制?來為降級的服務提供替代的實現。
我們提供了 Dubbo 的相關示例,請見?sentinel-demo-dubbo。
有關 Sentinel 在 Dubbo 中的最佳實踐,請參考?Sentinel: Dubbo 服務的流量哨兵。
關于 Dubbo Filter 的更多信息,請參考?Dubbo Filter 文檔。
gRPC
Sentinel 提供與?gRPC Java?的整合,以 gRPC?ServerInterceptor?和?ClientInterceptor?的形式保護 gRPC 服務資源。使用時需引入以下模塊(以 Maven 為例):
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-grpc-adapter</artifactId><version>x.y.z</version> </dependency>在使用 Sentinel gRPC Adapter 時,只需要將對應的?Interceptor?注冊至對應的客戶端或服務端中。其中客戶端的示例如下:
public class ServiceClient {private final ManagedChannel channel;ServiceClient(String host, int port) {this.channel = ManagedChannelBuilder.forAddress(host, port).intercept(new SentinelGrpcClientInterceptor()) // 在此處注冊攔截器.build();// 在此處初始化客戶端 stub 類} }服務端的示例如下:
import io.grpc.Server;Server server = ServerBuilder.forPort(port).addService(new MyServiceImpl()) // 添加自己的服務實現.intercept(new SentinelGrpcServerInterceptor()) // 在此處注冊攔截器.build();注意:Sentinel gRPC Adapter 目前只支持 unary call。
Feign
Feign 適配整合在 Spring Cloud Alibaba 中,可以參考?Spring Cloud Alibaba Sentinel 文檔?進行接入。
SOFARPC
從 1.7.2 版本開始,Sentinel 提供 SOFARPC 的適配模塊?sentinel-sofa-rpc-adapter,主要包括針對 Service Provider 和 Service Consumer 實現的 Filter。使用時需引入以下模塊(以 Maven 為例):
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-sofa-rpc-adapter</artifactId><version>x.y.z</version> </dependency>引入此依賴后,Sentinel 會自動統計 SOFARPC 的服務接口和方法調用(包括調用端和服務端),在配置了規則后就可以自動享受到 Sentinel 的防護能力。
HTTP Client 適配
Apache HttpClient
注:從 Sentinel 1.8.0 版本開始支持。
Sentinel 提供 Apache HttpClient 的適配模塊?sentinel-apache-httpclient-adapter,可以針對 HTTP client 請求進行流控和熔斷。使用時需引入以下模塊(以 Maven 為例):
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-apache-httpclient-adapter</artifactId><version>x.y.z</version> </dependency>注意目前暫不支持 AsyncHttpClient。
OkHttp
注:從 Sentinel 1.8.0 版本開始支持。
Sentinel 提供 OkHttp 的適配模塊?sentinel-okhttp-adapter,可以針對 HTTP client 請求進行流控和熔斷。使用時需引入以下模塊(以 Maven 為例):
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-okhttp-adapter</artifactId><version>x.y.z</version> </dependency>Reactive 適配
Reactor
注:從 1.5.0 版本開始支持,需要 Java 8 及以上版本。
Sentinel 提供?Reactor?的適配,可以方便地在 reactive 應用中接入 Sentinel。使用時需引入以下模塊(以 Maven 為例):
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-reactor-adapter</artifactId><version>x.y.z</version> </dependency>Sentinel Reactor Adapter 分別針對?Mono?和?Flux?實現了對應的 Sentinel Operator,從而在各種事件觸發時匯入 Sentinel 的相關邏輯。同時 Sentinel 在上層提供了?SentinelReactorTransformer?用于在組裝期裝入對應的 operator,用戶使用時只需要通過?transform?操作符來進行變換即可。接入示例:
someService.doSomething() // return type: Mono<T> or Flux<T>.transform(new SentinelReactorTransformer<>(resourceName)) // 在此處進行變換.subscribe();API Gateway 適配
Sentinel 支持對 Spring Cloud Gateway、Zuul 等主流的 API Gateway 進行限流。
Spring Cloud Gateway
從 1.6.0 版本開始,Sentinel 提供了 Spring Cloud Gateway 的適配模塊,可以提供兩種資源維度的限流:
- route 維度:即在 Spring 配置文件中配置的路由條目,資源名為對應的 routeId
- 自定義 API 維度:用戶可以利用 Sentinel 提供的 API 來自定義一些 API 分組
使用時需引入以下模塊(以 Maven 為例):
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-spring-cloud-gateway-adapter</artifactId><version>x.y.z</version> </dependency>使用時只需注入對應的?SentinelGatewayFilter?實例以及?SentinelGatewayBlockExceptionHandler?實例即可。比如:
@Configuration public class GatewayConfiguration {private final List<ViewResolver> viewResolvers;private final ServerCodecConfigurer serverCodecConfigurer;public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,ServerCodecConfigurer serverCodecConfigurer) {this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);this.serverCodecConfigurer = serverCodecConfigurer;}@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {// Register the block exception handler for Spring Cloud Gateway.return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);}@Bean@Order(-1)public GlobalFilter sentinelGatewayFilter() {return new SentinelGatewayFilter();} }Demo 示例:sentinel-demo-spring-cloud-gateway
詳細文檔可以參考?網關限流 - Spring Cloud Gateway 文檔。
Zuul 1.x
Sentinel 提供了 Zuul 1.x 的適配模塊,可以為 Zuul Gateway 提供兩種資源維度的限流:
- route 維度:即在 Spring 配置文件中配置的路由條目,資源名為對應的 route ID(對應?RequestContext?中的?proxy?字段)
- 自定義 API 維度:用戶可以利用 Sentinel 提供的 API 來自定義一些 API 分組
使用時需引入以下模塊(以 Maven 為例):
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-zuul-adapter</artifactId><version>x.y.z</version> </dependency>詳細文檔可以參考?網關限流 - Zuul 1.x。
如果您正在使用 Spring Cloud Zuul Starter,那么可以通過引入?spring-cloud-alibaba-sentinel-zuul?來更方便地整合 Sentinel。請參考?對應文檔。
Zuul 2.x
注:從 1.7.2 版本開始支持,需要 Java 8 及以上版本。
Sentinel 提供了 Zuul 2.x 的適配模塊,可以為 Zuul Gateway 提供兩種資源維度的限流:
- route 維度:對應 SessionContext 中的?routeVIP
- 自定義 API 維度:用戶可以利用 Sentinel 提供的 API 來自定義一些 API 分組
使用時需引入以下模塊(以 Maven 為例):
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-zuul2-adapter</artifactId><version>x.y.z</version> </dependency>詳細文檔可以參考?網關限流 - Zuul 2.x。
Apache RocketMQ
在 Apache RocketMQ 中,當消費者去消費消息的時候,無論是通過 pull 的方式還是 push 的方式,都可能會出現大批量的消息突刺。如果此時要處理所有消息,很可能會導致系統負載過高,影響穩定性。但其實可能后面幾秒之內都沒有消息投遞,若直接把多余的消息丟掉則沒有充分利用系統處理消息的能力。我們希望可以把消息突刺均攤到一段時間內,讓系統負載保持在消息處理水位之下的同時盡可能地處理更多消息,從而起到“削峰填谷”的效果:
?
上圖中紅色的部分代表超出消息處理能力的部分。我們可以看到消息突刺往往都是瞬時的、不規律的,其后一段時間系統往往都會有空閑資源。我們希望把紅色的那部分消息平攤到后面空閑時去處理,這樣既可以保證系統負載處在一個穩定的水位,又可以盡可能地處理更多消息。Sentinel 專門為這種場景提供了勻速器的特性,可以把突然到來的大量請求以勻速的形式均攤,以固定的間隔時間讓請求通過,以穩定的速度逐步處理這些請求,起到“削峰填谷”的效果,從而避免流量突刺造成系統負載過高。同時堆積的請求將會排隊,逐步進行處理;當請求排隊預計超過最大超時時長的時候則直接拒絕,而不是拒絕全部請求。
比如在 RocketMQ 的場景下配置了勻速模式下請求 QPS 為 5,則會每 200 ms 處理一條消息,多余的處理任務將排隊;同時設置了超時時間為 5 s,預計排隊時長超過 5 s 的處理任務將會直接被拒絕。示意圖如下圖所示:
?
RocketMQ 用戶可以根據不同的 group 和不同的 topic 分別設置限流規則,限流控制模式設置為勻速器模式(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER),比如:
private void initFlowControlRule() {FlowRule rule = new FlowRule();rule.setResource(KEY); // 對應的 key 為 `groupName:topicName`rule.setCount(5);rule.setGrade(RuleConstant.FLOW_GRADE_QPS);rule.setLimitApp("default");// 勻速器模式下,設置了 QPS 為 5,則請求每 200 ms 允許通過 1 個rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);// 如果更多的請求到達,這些請求會被置于虛擬的等待隊列中。等待隊列有一個 max timeout,如果請求預計的等待時間超過這個時間會直接被 block// 在這里,timeout 為 5srule.setMaxQueueingTimeMs(5 * 1000);FlowRuleManager.loadRules(Collections.singletonList(rule)); }結合 RocketMQ Client 使用 Sentinel 時,用戶需要在處理消息時手動埋點。詳情請見?Sentinel RocketMQ Demo。相關 Blog 見?Sentinel 為 RocketMQ 保駕護航。
總結
以上是生活随笔為你收集整理的Sentinel(十九)之主流框架的适配的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 家庭电脑配置推荐价位(家庭 电脑 配置)
- 下一篇: 电脑主机配置2000元左右(电脑主机配置