天天看點

Sentinel主流架構的适配

目錄

注:模組子產品僅提供相應适配功能,若要求接入哨兵,請 避免 參考 哨兵訓示文檔

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#%E4%BA%91%E5%8E%9F%E7%94%9F%E5%BE%AE%E6%9C%8D%E5%8A%A1%E4%BD%93%E7%B3%BB

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#spring-cloud 春雲

Spring Cloud 阿裡巴巴

提供微服務開發的解決方案。Sentinel 與 Spring Boot/Spring Cloud 的整合見

Sentinel Spring Cloud Starter

Spring Cloud 阿裡巴巴預設為 Sentinel 整合了 Servlet、RestTemplate、FeignClient 和 Spring WebFluxSentinel 在 Spring Cloud 生态中,心靈補全 Hystrix 在 Servlet 和 RestTemplate 這一塊的空白,而且還完全了 Hystrix 在 FeignClient 中限流降級的使用,并且支援運作時動态地配置和調整限流降級規則。

Spring Cloud Alibaba Sentinel 的示例可以參考

sentinel-guide-spring-cloud

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#quarkus

注:從 1.8.0 版本開始支援,需要 Java 8 及以上版本。

Sentinel 提供

針對 Quarkus 微服務的适配子產品

(支援原生鏡像),可以很友善地 JAX-RS Web 服務接入并進行高防護,同時支援注解方式自定義埋點(基于 CDI)。

相關子產品:

  • sentinel-jax-rs-quarkus-adapter

  • sentinel-annotation-quarkus-adapter

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#web-%E9%80%82%E9%85%8D

注意:目前标記自帶的擴充卡僅Dubbo 方法埋點帶了熱點參數,其他适配子產品(如Web)預設不支援關注規則,可通過自定義埋點方式指定新的資源名稱并期望的參數。注意自定義埋點的資源名不要和适配子產品生成的資源名重複,否則會導緻重複統計。

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#web-servlet

Sentinel 提供針對 Servlet 的原生接入流量進行控制,可以對 Web 進行控制。使用時需引入以下子產品(以 Maven 為例):

<依賴>

    < groupId >com.alibaba.csp</ groupId >

    < artifactId >sentinel-web-servlet</ artifactId >

    <版本>xyz</版本>

</依賴>

您隻需要在Web容器中的

web.xml

配置檔案中進行如下配置開啟哨兵支援:

<過濾器>

 < filter-name >SentinelCommonFilter</ filter-name >

 <過濾器類>com.alibaba.csp.sentinel.adapter.servlet.CommonFilter</過濾器類>

</過濾器>

<過濾器映射>

 < url-pattern >/*</ url-pattern >

</過濾映射>

複制 SpringBoot 應用可以通過

FilterRegistrationBean

類進行配置,例如:

@Configuration

公共 類 FilterConfig {

    @Bean

    public FilterRegistrationBean sentinelFilterRegistration () {

         FilterRegistrationBean< Filter > registration = new FilterRegistrationBean<> ();

        注冊。setFilter( new CommonFilter ());

        注冊。addUrlPatterns( " /* " );

        注冊。setName( " sentinelFilter " );

        注冊。設定順序( 1 );

        退貨登記;

    }

}

接入濾波之後,所有通路的網頁的URL就會被自動統計為哨兵的資源,可以針對單個URL次元進行流控。若希望區分不同的HTTP方法,将可以

HTTP_METHOD_SPECIFY

這個初始化參數設為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請求中解析起源并注冊至

WebCallbackManager

。中注意來源數目不能太多,若太多請自定義埋點作為參數傳入并使用熱點規則。

注意:Snel Web Filter 某個特定的 URL 作為不同的資源處理,是以對于 REST 風格的 API,需要自己實作

UrlCleaner

接口查找一下資源(比如

/foo/:id

URL 都歸到

/foo/*

資源下),然後将

WebCallbackManager

否則會導緻資源注冊數量過多,超出資源上限值(目前是6000)時多出的資源規則将不會生效。

1.6.3版本開始,

UrlCleaner

自從從網絡過濾掉不希望統計的URL,隻需要在UrlCleaner中将不希望統計的URL轉換成空字元串("")分類。示例:

網絡回調管理器。setUrlCleaner(新 UrlCleaner(){

     @覆寫

    公共 字元串 幹淨(字元串 originUrl){

        如果(originUrl == 空 || originUrl 。的isEmpty()){

            回報originUrl;

        }

        //比如将滿足/富/ {ID}的URL都歸到/富/ *

        如果(originUrl。 startsWith( “ /富/ ”)){

            傳回 “ /富/ * ” ;

        //不希望統計* .ICO的資源檔案,可以将其轉換為空字元串(因為1.6.3)

        如果(originUrl。的endsWith( “ .ICO ”)){

            傳回 “ ” ;

        傳回originUrl;

});

如果您正在使用 Spring Boot / Spring Cloud,則可以通過 Spring Cloud 阿裡巴巴 Sentinel 來更友善地整合 Sentinel,詳情請參閱

Spring Cloud 阿裡巴巴文檔

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#spring-webflux

注:從 1.5.0 版本開始支援,需要 Java 8 及以上版本。

Sentinel 提供與 Spring WebFlux 的整合子產品,進而實作 Reactive Web 應用也可以利用 Sentinel 的流控降級來穩定。該內建子產品基于 Sentinel Reactor Adapter 實作。

使用時需引入以下子產品(以Maven為例):

    < artifactId >sentinel-spring-webflux-adapter</ artifactId >

使用時對應的

SentinelWebFluxFilter

執行個體以及

SentinelBlockExceptionHandler

執行個體。例如:

公共 類 WebFluxConfig {

    私有 最終 清單< ViewResolver > viewResolvers;

    私有 最終 ServerCodecConfigurer serverCodecConfigurer;

    公共 WebFluxConfig(ObjectProvider <清單<的ViewResolver > > viewResolversProvider,

                          ServerCodecConfigurer serverCodecConfigurer){

        此。viewResolvers = viewResolversProvider 。getIfAvailable(集合:: emptyList);

        這個。serverCodecConfigurer = serverCodecConfigurer;

    @Order ( - 1 )

     public SentinelBlockExceptionHandler sentinelBlockExceptionHandler () {

         //為 Spring WebFlux 注冊塊異常處理程式。

        傳回 新的 SentinelBlockExceptionHandler (viewResolvers, serverCodecConfigurer);

     public SentinelWebFluxFilter sentinelWebFluxFilter () {

         //注冊 Sentinel WebFlux 過濾器。

        傳回 新的 SentinelWebFluxFilter ();

您可以在

WebFluxCallbackManager

注冊頁面進行定制:

  • setBlockHandler

    :注冊函數用于實作自定義的邏輯處理被限流的請求,對應接口

    BlockRequestHandler

    。預設實作為

    DefaultBlockRequestHandler

    ,當被限流時會傳回下面的錯誤資訊:

    Blocked by Sentinel: FlowException

  • setUrlCleaner

    :注冊函數用于 Web 資源名的歸一化。函數類型為

    (ServerWebExchange, String) → String

    ,對應為

    (webExchange, originalUrl) → finalUrl

  • setRequestOriginParser

    :注冊函數用于從請求中解析請求來源。函數類型為

    ServerWebExchange → String

相關示例:

sentinel-demo-spring-webflux

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#jax-rs-java-ee

注:從 1.8.0 版本開始原生支援。若您的服務是 Spring Web 服務,可參考 Spring Web 适配文檔接入。
哨兵-jax-rs-擴充卡

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#rpc-%E9%80%82%E9%85%8D

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#dubbo 達博

Sentinel 提供 Dubbo 的相關适配

Sentinel Dubbo Adapter

,主要包括針對 Service Provider 和 Service Consumer 實作的 Filter。 相關子產品:

  • sentinel-apache-dubbo-adapter

    (Apache Dubbo2.7.x及以上版本,自Sentinel1.5.1開始支援)
  • sentinel-dubbo-adapter

    (dubbo 2.6.x版本)

對于Apache Dubbo 2.7.x及以上版本,使用時需引入以下子產品(以Maven為例):

    < artifactId >sentinel-apache-dubbo-adapter</ artifactId >

對于 Dubbo 2.6.x及以下版本,使用時需引入以下子產品(以 Maven 為例):

    < artifactId >sentinel-dubbo-adapter</ artifactId >

引入此依賴後,Dubbo 的服務接口和方法(包括調用端和服務端)将成為 Sentinel 中的資源,在配置了規則後就可以自動獲得 Sentinel 的防護能力。

注:若隻希望接入儀表闆,請參考 接入 Dubbo擴充卡接入接入D 的步驟

如果不希望開啟 Sentinel Dubbo Adapter 中的某個過濾器,可以手動關閉對應的過濾器,例如:

<!--關閉 Sentinel 對應的服務消費者過濾器-->

< 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 還支援配置的後備函數,可以在 Dubbo 服務被限流/降級/負載保護的時候進行相應的後備處理。使用者隻需要實作自定義的

DubboFallback

接口,并通過

DubboFallbackRegistry

注冊。預設情況會直接将

BlockException

包裝後抛出。同時,我們還可以配合

達博的回退機制

來為降級的服務提供替代的實作。

我們提供了 Dubbo 的相關示例,請檢視

sentinel-demo-dubbo

關于 Sentinel 在 Dubbo 中的最佳實踐,請參考

Sentinel: Dubbo 服務的流量哨兵

關于 Dubbo Filter 的更多資訊,請參考

Dubbo Filter 文檔

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#grpc

Sentinel 提供與

gRPC Java

的整合,以 gRPC

ServerInterceptor

ClientInterceptor

的形式保護 gRPC 服務資源。使用時限以下子產品(以 Maven 為例):

    < artifactId >sentinel-grpc-adapter</ artifactId >

在使用 Sentinel gRPC Adapter 時,非常适合對應的

Interceptor

注冊到對應的用戶端或服務端中。其中用戶端的示例如下:

公共 類 ServiceClient {

    私人 最終 ManagedChannel頻道;

    ServiceClient(字元串 主機,int 端口){

         this . 頻道= ManagedChannelBuilder 。forAddress(主機,端口)

            .intercept( new SentinelGrpcClientInterceptor ()) //在此處注冊攔截器

            。建造();

        //在此處初始化用戶端stub類

服務端的示例如下:

導入 io.grpc.Server;

伺服器伺服器= ServerBuilder 。forPort(端口)

     .addService( new MyServiceImpl ()) //添加自己的服務實作

     .intercept( new SentinelGrpcServerInterceptor ()) //在此處注冊攔截器

     .build();

注意:Sentinel gRPC Adapter 目前隻支援一進制調用。

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#feign

Feign适配整合在Spring Cloud Alibaba中,可以參考

Spring Cloud Alibaba Sentinel文檔

進行接入。

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#sofarpc

從1.7.2版本開始,Sentinel提供了SOFARPC的适配子產品

sentinel-sofa-rpc-adapter

,主要包括針對Service Provider和Service Consumer實作的Filter。使用時需引入以下子產品(以Maven為例):

    < artifactId >sentinel-sofa-rpc-adapter</ artifactId >

引入此依賴後,Sentinel 會自動統計 SOFARPC 的服務接口和方法調用(包括調用端和服務端),在配置了規則後就可以自動獲得 Sentinel 的防護能力。

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#http-client-%E9%80%82%E9%85%8D

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#apache-httpclient

注:從 Sentinel 1.8.0 版本開始支援。

Sentinel提供Apache HttpClient的适配子產品

sentinel-apache-httpclient-adapter

,可以針對HTTP用戶端請求進行流控和熔斷。使用時需引入以下子產品(Maven示例):

    < artifactId >sentinel-apache-httpclient-adapter</ artifactId >

注意目前暫不支援 AsyncHttpClient。

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#okhttp

Sentinel提供OkHttp的适配子產品

sentinelok http-adapter

,可以針對HTTP用戶端請求進行流控和熔斷。使用時需引入以下子產品(以Maven為例):

    < artifactId >sentinel-okhttp-adapter</ artifactId >

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#reactive-%E9%80%82%E9%85%8D

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#reactor

前哨提供

反應器

的适配,可以友善地在反應性應用中接入前哨使用時需引入以下子產品(以Maven的為例):

    < artifactId >sentinel-reactor-adapter</ artifactId >

Sentinel Reactor Adapter 分别針對

Mono

Flux

實作了對應的 Sentinel Operator,進而在各種事件時觸發彙入 Sentinel 的邏輯。同時 Sentinel 在相關階段提供

SentinelReactorTransformer

對應的操作符,使用者使用時隻需要通過

transform

操作符來進行漸變。

一些服務。doSomething() //傳回類型:Mono<T> or Flux<T> 

   .transform( new SentinelReactorTransformer<> (resourceName)) //在此處進行變換

   .subscribe();

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#api-gateway-%E9%80%82%E9%85%8D

Sentinel 支援對 Spring Cloud Gateway、Zuul 等主流的 API Gateway 進行限流。

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#spring-cloud-gateway

從 1.6.0 版本開始,Sentinel 提供了 Spring Cloud Gateway 的适配子產品,可以提供兩種資源次元的限流:

  • route 次元:即在 Spring 中配置的路由入口,資源檔案名稱對應的 routeId
  • 自定義 API 次元:使用者可以利用 Sentinel 提供的 API 來自定義一些 API 表現

    < artifactId >sentinel-spring-cloud-gateway-adapter</ artifactId >

SentinelGatewayFilter

SentinelGatewayBlockExceptionHandler

公共 類 GatewayConfiguration {

    公共 GatewayConfiguration(ObjectProvider <清單<的ViewResolver > > viewResolversProvider,

                                 ServerCodecConfigurer serverCodecConfigurer){

    @Order ( Ordered . HIGHEST_PRECEDENCE )

     public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler () {

         //注冊 Spring Cloud Gateway 的塊異常處理程式。

        傳回 新的 SentinelGatewayBlockExceptionHandler (viewResolvers, serverCodecConfigurer);

     public GlobalFilter sentinelGatewayFilter () {

         return new SentinelGatewayFilter ();

示範示例:

sentinel-demo-spring-cloud-gateway

詳細文檔可以參考

網關限流 - Spring Cloud Gateway 文檔

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#zuul-1x 祖爾 1.x

Sentinel 提供了 Zuul 1.x 的适配子產品,為 Zuul Gateway 提供了兩種資源次元的限流:

  • route對應的次元:即在Spring中配置的條目,資源名稱對應的路由ID(

    RequestContext

    中的

    proxy

    字段)

    < artifactId >sentinel-zuul-adapter</ artifactId >

網關限流 - Zuul 1.x

如果您正在使用 Spring Cloud Zuul Starter,那麼可以通過引入

spring-cloud-alibaba-sentinel-zuul

來更友善地整合 Sentinel。請參考對應的

文檔

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#zuul-2x 祖爾 2.x

注:從 1.7.2 版本開始支援,需要 Java 8 及以上版本。

Sentinel 提供了 Zuul 2.x 的适配子產品,為 Zuul Gateway 提供了兩種資源次元的限流:

  • 路線次元:對應SessionContext中的

    routeVIP

    < artifactId >sentinel-zuul2-adapter</ artifactId >

網關限流 - Zuul 2.x

https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#apache-rocketmq

在 Apache RocketMQ 中,當去消費消費消息的時候,無論是通過拉的方式還是推的方式,都可能會出現大時候的消息突刺。如果此時要處理所有消息可能會導緻系統負載過時高,穩定性。但實際上可能有幾秒之内都消息投遞,如果沒有直接把消息丢掉則可以充分利用系統的消息能力,我們希望把消息突襲均勻攤到可以處理内,讓系統。堅持保持在消息處理水位的同時,還有更多消息,即将到來的“削峰填谷”的效果:

我們可以看到消息突發的部分總是短暫的、沒有開始的,後系統通常有其資源。我們希望把紅色的消息處理能力的一部分。哨兵專門為場景提供了

某種速度

的特性,可以讓系統突然出現大量的大量資訊。請求以同速的形式均勻,以固定的時間間隔讓請求,以穩定的速度逐漸處理通過這些請求突,流量的“削峰填谷”效果,進而避免造成系統過度消耗。将不會主動,逐漸進行處理;當請求對方時間過長則直接拒絕,是拒絕全部請求。

比如在 RocketMQ 的場景下配置了同速模式下 QPS 為 5,每 200 毫秒處理一條消息,額外的處理任務将請求請求;同時設定了逾時時間為 5 秒,生産時間長超過 5 的處理任務将直接被拒絕。如下圖所示:

RocketMQ 使用者可以根據不同的組和不同的主題分别設定限流規則,限流控制模式設定為同速器模式(

RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER

),例如:

private void initFlowControlRule() {

     FlowRule rule = new FlowRule ();

    規則。設定資源(鍵);//對應的key為`groupName:topicName`

    規則。setCount( 5 );

    規則。setGrade( RuleConstant . FLOW_GRADE_QPS );

    規則。setLimitApp( “預設” );

    //同速器模式下,設定的QPS為5,則請求每200毫秒允許通過1個

    規則。setControlBehavior( RuleConstant . CONTROL_BEHAVIOR_RATE_LIMITER );

    //如果更多的請求到達,這些請求會被置于虛拟的等待隊列中。等待隊列有一個最大逾時,如果請求預計的等待時間超過這個時間會直接被塊

    //在這裡,逾時為5秒

    規則. setMaxQueueingTimeMs( 5 * 1000 );

    流規則管理器。loadRules( Collections . singletonList(rule));

結合RocketMQ用戶端使用Sentinel時,使用者需要在處理消息時手動埋點。詳情請見

Sentinel RocketMQ Demo

。相關部落格見

Sentinel為RocketMQ保駕護航