sentinel整合控制台和動態規則
控制台的下載和啟動
首先可以到這個地址去下載控制台:
https://github.com/alibaba/Sentinel/releases/tag/v1.8.0
下載下來得到的是一個jar包,jar包啟動命令:
java -Dserver.port=18080 -Dcsp.sentinel.dashboard.server=localhost:18080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar
參數解析:
配置項 | 類型 | 默認值 | 最小值 | 描述 |
---|---|---|---|---|
auth.enabled | boolean | true | - | 是否開啟登錄鑒權,僅用於日常測試,生產上不建議關閉 |
sentinel.dashboard.auth.username | String | sentinel | - | 登錄控制台的用戶名,默認為 sentinel |
sentinel.dashboard.auth.password | String | sentinel | - | 登錄控制台的密碼,默認為 sentinel |
csp.sentinel.dashboard.server | String | 把信息上傳到控制台上面。 |
注意:如果加了csp.sentinel.dashboard.server的話,才會有左面的sentine-dashboard選項的。sentine-dashboard其實就是我們指定的project-name,不過基本上控制台還是別加了這個,因為沒什么意義。
sentinel整合控制台:
spring-boot層面的整合
pom.xml添加依賴:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>${sentinel.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-web-servlet</artifactId>
<version>${sentinel.version}</version>
</dependency>
啟動類:
@SpringBootApplication
public class DemoApplication implements ApplicationContextAware {
static {
System.setProperty("csp.sentinel.dashboard.server","localhost:18080"); //指定控制台的地址
System.setProperty("project.name","sentinel-boot"); //指定sentinel的名字
}
public static ApplicationContext applicationContext;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class,args);
}
}
注意:啟動時加入 JVM 參數 -Dcsp.sentinel.dashboard.server=consoleIp:port
指定控制台地址和端口。若啟動多個應用,則需要通過 -Dcsp.sentinel.api.port=xxxx
指定客戶端監控 API 的端口(默認是 8719)。如果沒有設置api端口而且8719端口被占用的話,他會往8719端口開始遞增。直到找到沒有占用的端口為止
配置類,需要加上這個過濾器來做監控:
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean sentinelFilterRegistration() {
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
registration.setFilter(new CommonFilter());
registration.addUrlPatterns("/*");
registration.setName("sentinelFilter");
registration.setOrder(1);
return registration;
}
}
contorller端:
@RestController
@RequestMapping("/web")
public class WebController {
@GetMapping("/sayhello")
public String sayhello(){
return "sayhello";
}
}
效果如下:
注意:
-
需要發送一個請求到http://127.0.0.1:8888/web/sayhello才能顯示出來
-
有人就會問了,規則是包含了:資源名字和一些規則的參數的。比如我定義了一個hello的資源名,規則是qps=2,失敗策略是快速失敗,但是我代碼中都沒有引用這個hello資源名啊。如果是web服務的話,比如我們上面路徑是/web/sayHello,我們可以直接定義/web/sayhello為資源名。然后配置規則,他也能對/web/sayhello這個路徑起到流控控制的作用
-
如果在sentinel內置的規則也能顯示在控制台的頁面上。
效果如下:
我們可以通過去頁面上配置規則就可以達到動態的修改規則了。但是很遺憾的是:修改完的規則只能保存到sentinel(不是控制台)的內存中。當sentinel重新啟動后,這些規則就會丟失掉。如果我們需要存起來的話,請看跟nacos的結合
spring-cloud層面的整合
跟spring-cloud結合就簡單很多了。
引入依賴:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
application.yml文件配置:
spring:
cloud:
sentinel:
transport:
port: 8719 #指定客戶端監控 API 的端口
dashboard: localhost:18080 #控制台的地址
application:
name: sentinel-cloud
server:
port: 8701
只需要這么一配置就可以實現和控制台整合了。如果項目是spirng-cloud的話,建議直接使用這個整合就性了。
sentinel整合nacos
nacos有配置中心的功能,只要我們sentinel這邊監聽nacos的配置信息的變化(配置信息就是規則信息)。就可以實現了動態調整sentinel的規則了。並且再次啟動的時候,我們是直接讀取nacos上的配置信息。所以能起到一個持久化的作用。
需要的依賴如下:
<dependencies>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId>
</dependency>
</dependencies>
動態規則的配置
private static String serverAddr = "localhost:8848";
private static String groupId = "Sentinel:Demo";
private static String dataId = "flowRule:nacos-demo";
//讀取nacos里面的規則並且使用這規則
public static void loadRule(){
ReadableDataSource dataSource = new NacosDataSource(serverAddr, groupId, dataId, new Converter<String, List<FlowRule>>() {
//把nacos讀到的信息,轉成List<FlowRule>
@Override
public List<FlowRule> convert(String source) {
// List<FlowRule> flowRules = JSONObject.parseObject(s, new TypeReference<List<FlowRule>>() {});
return JSONObject.parseArray(s, FlowRule.class);
}
});
FlowRuleManager.register2Property(dataSource.getProperty());
}
原理其實就是:監聽groupId是Sentinel:Demo,dataId是flowRule:nacos-demo的配置信息,如果nacos上該配置信息改變的時候就會觸發convert方法。入參的字符串其實就是nacos上的配置信息,只要我們把配置信息轉換成相應的規則返回就能達到效果了
效果如下:
當我們啟動項目或者修改nacos的配置文件,就會觸發convert方法。上面就是觸發傳入的s是什么的效果圖。
這是我發送到nacos的配置的測試類:
public class NacosConfigSender {
//設置配置的規則到nacos上。 groupId: Sentinel:Demo dataId: com.alibaba.csp.sentinel.demo.flow.rule
public static void main(String[] args) throws Exception {
final String remoteAddress = "localhost";
final String groupId = "Sentinel:Demo";
final String dataId = "flowRule:nacos-demo";
final String rule = "[\n"
+ " {\n"
+ " \"resource\": \"TestResource\",\n"
+ " \"controlBehavior\": 0,\n"
+ " \"count\": 5.0,\n"
+ " \"grade\": 1,\n"
+ " \"limitApp\": \"default\",\n"
+ " \"strategy\": 0\n"
+ " }\n"
+ "]";
ConfigService configService = NacosFactory.createConfigService(remoteAddress);
System.out.println(configService.publishConfig(dataId, groupId, rule));
}
}
sentinel整合控制台和nacos
整體的架構就像上面的圖片一樣。首先:
- sentinel控制台在頁面上修改了規則后,然后把該規則發送到nacos的配置中心上
- 因為sentinel客戶端監聽了nacos上面的配置中心,所以就能等到修改后的規則,從而得到動態修改規則。
但是官方提供的sentinel的jar包不支持這個功能。需要我們去修改一下它的源嗎,不過也是很簡單的。不需要擔心,如果不想自己寫的話,可以直接要我的修改完的sentinel控制台。地址:https://gitee.com/gzgyc/sentinel-dashboard.git
下面我就說一下怎么改造把。官方提供了流量控制的例子:
1.rule目錄下提供了nacos,apollo,zookeeper這些官方例子,我們先把nacos這個官方例子目錄移到上面去先
2.然后在pom.xml文件里,去掉這個
3.修改FlowControllerV2文件。把publisher和provider修改成nacos的
4.sidebar.html 流控規則路由從 dashboard.flowV1 改成 dashboard.flow 即可
控制台改造完成,啟動即可(這個只是修改了流量控制的規則而已,其他的規則可以看我的github)。
注意點:
-
上面控制台的改造的點有:
-
添加了FlowControllerV2,這個類地址是/v2/flow。
-
前端那里把dashboard.flowV1 改成 dashboard.flow,即是讓前端請求FlowControllerV2,下面是源碼的截圖
-
-
要留意頁面是否發送請求的是/v2/flow前綴。可以看到下圖為啥有個單機頁面,單機頁面其實就是沒有結合nacos的時候功能。所以千萬要注意這個位置。注意:基於上面的這個改造,單機頁面是沒有回到單機頁面這個按鈕的。
問題:規則會保存到nacos的哪個groupId,dataId中:
答:由下圖可以知道是groupId: "SENTINEL_GROUP" , dataId: appName + "-flow-rules"。
只要我們sentinel的客戶端監聽這個groupId和dataId就可以了。所以代碼如下:
@Configuration
public class NacosConfig {
//讀取nacos里面的規則並且使用這規則
@PostConstruct
public static void loadRule(){
String serverAddr = "localhost:8848";
String groupId = "SENTINEL_GROUP";
String dataId = "sentinel-nacos-dashboard-flow-rules";
ReadableDataSource dataSource = new NacosDataSource(serverAddr, groupId, dataId, new Converter<String, List<FlowRule>>() {
//把nacos讀到的信息,轉成List<FlowRule>
@Override
public List<FlowRule> convert(String s) {
// List<FlowRule> flowRules = JSONObject.parseObject(s, new TypeReference<List<FlowRule>>() {});
return JSONObject.parseArray(s, FlowRule.class);
}
});
FlowRuleManager.register2Property(dataSource.getProperty());
}
}
注意:這里只是改造了流量控制而已,其他的規則還沒有規則。想要改造其他的規則,可以看我改造的控制台代碼。
簡單談談改造降級策略的控制台應該怎么搞
查詢操作:
這個類我是參考flowRuleNacosProvider類寫的。
改造前的邏輯:
- sentinelApiClient.fetchDegradeRuleOfMachine(app, ip, port): 跟sentinel客戶端通訊拿到客戶端上面的規則
- repository.saveAll(rules): 把拿到的規則保存到自己的內存中
改造后的邏輯:
- ruleProvider.getRules(app): 直接去nacos上面拿取。然后返回
增刪改操作:
改造前:
- 對內存中的規則進行增刪改操作
- 增刪改操作成功后,獲取該appName的所有的降級熔斷規則,然后跟sentinel客戶端通訊,推送最新的規則給sentinel客戶端。
改造后:
- 對內存中的規則進行增刪改操作
- 增刪改操作成功后,獲取該appName的所有的降級熔斷規則,推送到nacos上。
具體的看我的gitee:
控制台的地址:https://gitee.com/gzgyc/sentinel-dashboard.git
sentinel代碼地址:https://gitee.com/gzgyc/dubbo-demo.git