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更好的選擇。