阿里sentinel流控框架初探

netflix的hystrix作爲業界使用最廣泛的流控框架,sentinel的開發團隊自然少不了對其的學習與改進,這裏有一篇開發團隊寫的兩者的對比,總結起來就是sentinel的實現更加輕量,進行流控的維度也更多樣。

使用sentinel的另一個理由就是其與國內廣泛使用的各大微服務框架都做了集成,接入sentinel更加方便。這裏是sentinel集成的其它框架的接入文檔

下面我們以國內使用最爲廣泛的微服務框架dubbo爲例,探索sentinel的使用。

sentinel dashboard部署

sentinel控制檯可以對接入的應用的實際流量進行監控,也可以查看,修改接入應用的流控,降級,熱點等規則。開發者文檔很詳細的介紹了部署和接入步驟,這裏不再贅述,需要提醒的是隻有當被限流的服務產生實際流量時,控制檯纔會顯示數據。


dubbo provider接入

首先引入sentinel基礎依賴
對於 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 provider

public interface DemoService {
    public String sayHello(String name);
}
 <dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService"/>

配置限流規則
首先介紹下sentinel的限流規則

一條限流規則主要由下面幾個因素組成,我們可以組合這些元素來實現不同的限流效果:
resource:資源名,即限流規則的作用對象
count: 限流閾值
grade: 限流閾值類型(QPS 或併發線程數)
limitApp: 流控針對的調用來源,若爲 default 則不區分調用來源
strategy: 調用關係限流策略
controlBehavior: 流量控制效果(直接拒絕、Warm Up、勻速排隊)

這裏的resource在不同的情況下配置的規則也不相同,而與dubbo整合的情況下,resource的粒度可以分爲兩種粒度

限流粒度可以是服務接口和服務方法兩種粒度:
服務接口:resourceName 爲 接口全限定名,如 com.alibaba.csp.sentinel.demo.dubbo.FooService
服務方法:resourceName 爲 接口全限定名:方法簽名,如 com.alibaba.csp.sentinel.demo.dubbo.FooService:sayHello(java.lang.String)

比如我想DemoService這個服務接口的QPS進行限流,不限制請求來源,被限流的請求直接拒絕且每秒只接受20的QPS,那麼我的限流規則應該如下:

[
  {
    "resource": "org.apache.dubbo.demo.DemoService",
    "controlBehavior": 0,
    "count": 20.0,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0
  }
]

介紹完如何編寫限流規則,下一步就是如何配置這些規則使其起效,sentinel將不同來源的限流規則抽象成一個個數據源且支持動態更新,其基礎抽象類爲(com.alibaba.csp.sentinel.datasource.AbstractDataSource),還提供了一個抽象接口(com.alibaba.csp.sentinel.datasource.Converter)進行源數據到限流規則(com.alibaba.csp.sentinel.slots.block.flow.FlowRule)的轉換。sentinel提供了多種數據源的實現,包括文件,zookeeper,redis等,這裏介紹最簡單也是最常用的靜態文件配置方式,對動態配置感興趣的可以參考官方文檔

靜態文件方式配置
首先在工程的resource目錄下準備一份json格式的配置文件(其它格式也可以,解析規則是由開發者自行編寫的,怎麼方便怎麼來),內容就是一個json數組:
在這裏插入圖片描述

[
  {
    "resource": "org.apache.dubbo.demo.DemoService",
    "controlBehavior": 0,
    "count": 20.0,
    "grade": 1,
    "limitApp": "default",
    "strategy": 0
  }
]

編寫代碼解析配置文件,然後將配置規則載入內存

private Converter<String, List<FlowRule>> flowRuleListParser = s -> JSON.parseObject(s, new TypeReference<List<FlowRule>>() {});

private void loadRules() throws Exception {
        ClassLoader classLoader = getClass().getClassLoader();
        String flowRulePath = URLDecoder.decode(classLoader.getResource("FlowRule.json").getFile(), "UTF-8");
        log.info(flowRulePath);

        FileRefreshableDataSource<List<FlowRule>> flowRuleDataSource = new FileRefreshableDataSource<>(flowRulePath, flowRuleListParser);
        FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
    }

其它幾類規則的載入方式也是相同的這裏不再贅述,流控規則載入完成後,我們的dubbo rpc接口就能受到sentinel的保護啦,最後一步啓動應用,加入以下參數(接入sentinel dashboard需要)

-Dcsp.sentinel.dashboard.server=127.0.0.1:9999 -Dproject.name=dubbo_provider -Dcsp.sentinel.api.port=8719 -Djava.net.preferIPv4Stack=true

dubbo consumer接入

consumer不需要配置限流規則,配置相對簡單
同樣需要引入sentinel依賴

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-transport-simple-http</artifactId>
            <version>1.5.1</version>
        </dependency>

進行dubbo消費者的配置,爲了更加準確的觀測結果,需要關閉重試機制(retries=“0”)

<dubbo:reference id="demoService" check="false" retries="0" interface="org.apache.dubbo.demo.DemoService"/>

同時發出50個請求

public class Application {
    private static final Logger log = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml");
        context.start();
        DemoService demoService = context.getBean("demoService", DemoService.class);

        for (int i = 0; i < 50; i++) {
            new Thread(() -> {
                String hello = demoService.sayHello("dubbo");
                log.info("result: " + hello);
            }).start();
        }
    }
}

啓動應用,若想在dashboard中進行實時監控,啓動參數也需要加入以下參數

-Dcsp.sentinel.dashboard.server=127.0.0.1:9999 -Dproject.name=dubbo_provider -Djava.net.preferIPv4Stack=true

此時可以看到控制檯出現大量FlowException異常
觀察sentinel的流控日誌sentinel-block.log
默認位於~/logs/csp下
在這裏插入圖片描述
先介紹下日誌各個字段的含義

2019-10-12 15:54:11:時間戳;
1:序號;
org.apache.dubbo.demo.DemoService:資源描述符;
XXXException:表示被限制的種類。FlowException 表示被限流,DegradeException 表示被降級,SystemException 表示被系統保護
default:規則上配置的限制應用;
origin:實際被限制的來源應用,可能爲空字符串;
30,0:30 代表這一秒內限流降級發生的次數,0 無含義(可忽略)。

觀察sentinel dashboard的實時監控數據
在這裏插入圖片描述
可以看到結果都符合預期,sentitinel確實起到了限流的作用。


結語

以上只是sentinel最簡單的一個單機版本的限流例子,接下來的博客中會逐步介紹它的降級規則,熔斷恢復,集羣流控,網關流控,多維度限流的能力。由於其與dubbo都經由alibaba開發並開源,在衆多dubbo構建的微服務體系下,相信會是比hystrix更好的選擇。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章