使用Sentinel進行服務(wù)調(diào)用的熔斷和限流管理(SpringCloud2023實戰(zhàn))

你好,這里是codetrend專欄“SpringCloud2023實戰(zhàn)”。

本文簡單介紹SpringCloud2023中使用Sentinel進行限流管理。

前言

隨著微服務(wù)的流行,服務(wù)和服務(wù)之間的穩(wěn)定性變得越來越重要。

Sentinel 是面向分布式、多語言異構(gòu)化服務(wù)架構(gòu)的流量治理組件,主要以流量為切入點,從流量路由、流量控制、流量整形、熔斷降級、系統(tǒng)自適應(yīng)過載保護、熱點流量防護等多個維度來幫助開發(fā)者保障微服務(wù)的穩(wěn)定性。

Sentinel 同時提供系統(tǒng)維度的自適應(yīng)保護能力。

防止雪崩,是系統(tǒng)防護中重要的一環(huán)。當(dāng)系統(tǒng)負(fù)載較高的時候,如果還持續(xù)讓請求進入,可能會導(dǎo)致系統(tǒng)崩潰,無法響應(yīng)。在集群環(huán)境下,網(wǎng)絡(luò)負(fù)載均衡會把本應(yīng)這臺機器承載的流量轉(zhuǎn)發(fā)到其它的機器上去。

如果這個時候其它的機器也處在一個邊緣狀態(tài)的時候,這個增加的流量就會導(dǎo)致這臺機器也崩潰,最后導(dǎo)致整個集群不可用。

Spring Cloud Alibaba 默認(rèn)為 Sentinel 整合了 Servlet、RestTemplate、FeignClient 和 Spring WebFlux。

Sentinel 在 Spring Cloud 生態(tài)中,不僅補全了 Hystrix 在 Servlet 和 RestTemplate 這一塊的空白,而且還完全兼容了 Hystrix 在 FeignClient 中限流降級的用法,并且支持運行時靈活地配置和調(diào)整限流降級規(guī)則。

Sentinel工作機制

Sentinel 的使用可以分為兩個部分:

  • 核心庫(Java 客戶端):不依賴任何框架/庫,能夠運行于 Java 8 及以上的版本的運行時環(huán)境,同時對 Dubbo / Spring Cloud 等框架也有較好的支持(見 主流框架適配)。
  • 控制臺(Dashboard):Dashboard 主要負(fù)責(zé)管理推送規(guī)則、監(jiān)控、管理機器信息等。

Sentinel 的主要工作機制如下:

  • 對主流框架提供適配或者顯示的 API,來定義需要保護的資源,并提供設(shè)施對資源進行實時統(tǒng)計和調(diào)用鏈路分析。
  • 根據(jù)預(yù)設(shè)的規(guī)則,結(jié)合對資源的實時統(tǒng)計信息,對流量進行控制。同時,Sentinel 提供開放的接口,方便您定義及改變規(guī)則。
  • Sentinel 提供實時的監(jiān)控系統(tǒng),方便您快速了解目前系統(tǒng)的狀態(tài)。

Sentinel特點

Sentinel 具有以下特征:

  • 豐富的應(yīng)用場景: Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發(fā)流量控制在系統(tǒng)容量可以承受的范圍)、消息削峰填谷、實時熔斷下游不可用應(yīng)用等。
  • 完備的實時監(jiān)控: Sentinel 同時提供實時的監(jiān)控功能。您可以在控制臺中看到接入應(yīng)用的單臺機器秒級數(shù)據(jù),甚至 500 臺以下規(guī)模的集群的匯總運行情況。
  • 廣泛的開源生態(tài): Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相應(yīng)的依賴并進行簡單的配置即可快速地接入 Sentinel。
  • 完善的 SPI 擴展點: Sentinel 提供簡單易用、完善的 SPI 擴展點。您可以通過實現(xiàn)擴展點,快速的定制邏輯。例如定制規(guī)則管理、適配數(shù)據(jù)源等。

Sentinel集成之控制臺(Dashboard)

Sentinel 控制臺提供一個輕量級的控制臺,它提供機器發(fā)現(xiàn)、單機資源實時監(jiān)控、集群資源匯總,以及規(guī)則管理的功能。您只需要對應(yīng)用進行簡單的配置,就可以使用這些功能。

java -Dserver.port=10300 -Dcsp.sentinel.dashboard.server=localhost:10300 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
# 如若8080端口沖突,可使用 -Dserver.port=新端口 進行設(shè)置。
  • 配置控制臺信息,application.yml 。
spring:
  cloud:
    sentinel:
      transport:
        port: 10201
        dashboard: localhost:10300

這里的 spring.cloud.sentinel.transport.port 端口配置會在應(yīng)用對應(yīng)的機器上啟動一個 Http Server,該 Server 會與 Sentinel 控制臺做交互。比如 Sentinel 控制臺添加了一個限流規(guī)則,會把規(guī)則數(shù)據(jù) push 給這個 Http Server 接收,Http Server 再將規(guī)則注冊到 Sentinel 中。

Sentinel集成之普通服務(wù)

引入pom.xml

  • 引入Sentinel主要是引入 spring-cloud-starter-alibaba-sentinel 。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <dependencies>
        <!-- sentinel核心包引入 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-core</artifactId>
        </dependency>
        <!-- sentinel-springboot引入 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
    </dependencies>
</project>

修改配置

  • 新增配置文件 application.yml,配置主要是 spring.cloud.sentinel 下面的配置。
spring.application.name: banana-client4-sentinel
spring:
  cloud:
    sentinel:
      transport:
        port: 10201
        dashboard: localhost:10300
    zookeeper:
      connect-string: localhost:2181

接口demo

  • 通過訪問 http://localhost:10200/client4/swagger-ui.html ,輸入賬號密碼 yulin/123yl. 就可以訪問到最新的接口文檔,驗證限流是否開啟成功。
@Service
public class TestService {

    @SentinelResource(value = "sayHello")
    public String sayHello(String name) {
        return "Hello, " + name;
    }
}

@RestController
public class TestController {

    @Autowired
    private TestService service;

    @GetMapping(value = "/hello/{name}")
    public String apiHello(@PathVariable String name) {
        return service.sayHello(name);
    }
}
  • 在控制面板設(shè)置 http://localhost:10200/client4/hello 的QPS為5。通過如下腳本驗證限流是否成功:
import requests
token_list =[]
for j in range(10):
    token_list.append(str(j)+'hello')
    response = requests.get('http://localhost:10200/client4/hello/'+str(j)+'hello','hello')
    print(response.text)

輸出文檔如下:

Hello, 0hello
Hello, 1hello
Hello, 2hello
Hello, 3hello
Hello, 4hello
Blocked by Sentinel (flow limiting)
Blocked by Sentinel (flow limiting)
Blocked by Sentinel (flow limiting)
Blocked by Sentinel (flow limiting)
Blocked by Sentinel (flow limiting)

Sentinel集成之OpenFeign

pom.xml和配置修改

Feign 適配整合在 Spring Cloud Alibaba 中,可以參考 Spring Cloud Alibaba Sentinel 文檔 進行接入。

Sentinel 適配了 Feign 組件。如果想使用,除了引入 spring-cloud-starter-alibaba-sentinel 的依賴外還需要 2 個步驟:

  • 配置文件打開 Sentinel 對 Feign 的支持:feign.sentinel.enabled=true
  • 加入 spring-cloud-starter-openfeign 依賴使 Sentinel starter 中的自動化配置類生效:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

demo驗證代碼

@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
    @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
    String echo(@PathVariable("str") String str);
}

class FeignConfiguration {
    @Bean
    public EchoServiceFallback echoServiceFallback() {
        return new EchoServiceFallback();
    }
}

class EchoServiceFallback implements EchoService {
    @Override
    public String echo(@PathVariable("str") String str) {
        return "echo fallback";
    }
}
  • EchoService 接口中方法 echo 對應(yīng)的資源名為 GET:http://service-provider/echo/{str}。 通過對該資源限流配置即可。
  • 實際驗證失敗,可能是沒有開發(fā)到springcloud2023。

Sentinel集成之Gateway

若想跟 Sentinel Starter 配合使用,需要加上 spring-cloud-alibaba-sentinel-gateway 依賴,同時需要添加 spring-cloud-starter-gateway 依賴來讓 spring-cloud-alibaba-sentinel-gateway 模塊里的 Spring Cloud Gateway 自動化配置類生效:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

同時請將 spring.cloud.sentinel.filter.enabled 配置項置為 false(若在網(wǎng)關(guān)流控控制臺上看到了 URL 資源,就是此配置項沒有置為 false)。Sentinel 網(wǎng)關(guān)流控默認(rèn)的粒度是 route 維度以及自定義 API 分組維度,默認(rèn)不支持 URL 粒度。

文檔來自Sentinel文檔。這里不仔細(xì)展開開發(fā)和說明,后續(xù)在網(wǎng)關(guān)業(yè)務(wù)層進行配置和說明。

完整源碼信息查看可以在gitee或者github上搜索r0ad。

關(guān)于作者

來自一線全棧程序員nine的探索與實踐,持續(xù)迭代中。

歡迎關(guān)注或者點贊~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容