Sentinel簡介
隨着微服務的流行,服務與服務之間的穩定性變得越來越重要。Sentinel以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。
Sentinel具有如下特性:
- 豐富的應用場景:承接了阿里巴巴近十年的雙十一大促流量的核心場景,例如秒殺,可以實時熔斷下游不可用服務。
- 完備的實時監控:同時提供實時的監控功能。可以在控制台中看到接入應用的單台機器秒級數據,甚至500台以下規模的集群的匯總運行情況。
- 廣泛的開源生態:提供開箱即用的與其他開源框架/庫的整合模塊,例如與 SpringCloud 、Dubbo、 gRPC的整合。
- 完善的 SPI 擴展點:提供簡單易用、完善的 SPI 擴展點。可以通過實現擴展點,快速的定制邏輯。
一、安裝Sentinel控制台
Sentinel控制台是一個輕量級的控制台應用,它可用於實時查看單機資源監控及集群資源匯總,並提供了一系列的規則管理功能,如流控規則、降級規則、熱點規則等。
從官網下載Sentinel,這里使用的是sentinel-dashboard-1.7.2.jar文件,下載地址:
https://github.com/alibaba/Sentinel/releases
下載完成后再命令行輸入以下命令運行Sentinel控制台:
java -jar sentinel-dashboard-1.7.2.jar
Sentinel控制台默認運行在8080端口上,登錄賬號和密碼均為sentinel,通過如下地址進行訪問:http://localhost:8080
Sentinel控制台可以查看單台機器的實時監控數據。
二、創建springboot-sentinel模塊
這里我們創建一個springboot-sentinel模塊,用於演示Sentinel的熔斷與限流功能。
在pom.xml中添加相關依賴,這里我們使用Nacos作為注冊中心,所以需要同時引入Nacos的依賴。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
在application.yml中添加相關配置,主要是配置了Nacos和Sentinel控制台地址:
server:
port: 8401
spring:
application:
name: springboot-sentinel
cloud:
nacos:
discovery:
namespace: dev
server-addr: 192.168.0.130:8848
sentinel:
transport:
# 配置Sentinel dashborad地址
dashboard: http://localhost:8080
port: 8719
datasource:
- nacos:
server-addr: 192.168.0.130:8848
data-id: ${spring.application.name}-flow-rules
group-id: DEFAULT_GROUP
data-type: json
rule-type: flow
service-url:
user-service: http://192.168.0.130:8501
management:
endpoints:
web:
exposure:
include: '*'
feign:
sentinel:
enabled: true
三、限流功能
Sentinel Starter 默認為所有的 HTTP 服務提供了限流埋點,我們也可以通過使用@SentinelResource來自定義一些限流行為。
四、創建RateLimitController類
用於測試熔斷和限流功能。
package com.lee.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.lee.handle.CustomBlockHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/rateLimit")
public class RateLimitController {
/**
* 按資源名稱限流,需要指定限流處理邏輯
*
* @return
*/
@GetMapping("/byResource")
@SentinelResource(value = "byResource", blockHandler = "handleException")
public Map<String,Object> byResource() {
Map<String,Object> result = new HashMap<>();
result.put("name","按資源名稱限流");
result.put("code",200);
return result ;
}
/**
* 按url限流,有默認的限流處理邏輯
*
* @return
*/
@GetMapping("byUrl")
@SentinelResource(value = "byUrl", blockHandler = "handleException")
public Map<String,Object> byUrl() {
Map<String,Object> result = new HashMap<>();
result.put("name","按url限流");
result.put("code",200);
return result ;
}
public Map<String,Object> handleException(BlockException exception) {
Map<String,Object> result = new HashMap<>();
result.put("name",exception.getClass().getCanonicalName());
result.put("code",200);
return result ;
}
@GetMapping("/customBlockHandler")
@SentinelResource(value = "customBlockHandler", blockHandler = "handleException", blockHandlerClass = CustomBlockHandler.class)
public Map<String,Object> blockHandler() {
Map<String,Object> result = new HashMap<>();
result.put("name","限流成功");
result.put("code",200);
return result ;
}
}
1.根據資源名稱限流
我們可以根據@SentinelResource注解中定義的value(資源名稱)來進行限流操作,但是需要指定限流處理邏輯。
流控規則可以在Sentinel控制台進行配置,由於我們使用了Nacos注冊中心,我們先啟動Nacos和sentinel-service;
由於Sentinel采用的懶加載規則,需要我們先訪問下接口,Sentinel控制台中才會有對應服務信息,我們先訪問下該接口:
http://localhost:8401/rateLimit/byUrl
在Sentinel控制台配置流控規則,根據@SentinelResource注解的value值:
快速訪問上面的接口,可以發現返回了自己定義的限流處理信息:
2.根據URL限流
我們還可以通過訪問的URL來限流,會返回默認的限流處理信息。
在Sentinel控制台配置流控規則,使用訪問的URL:
多次訪問該接口,會返回默認的限流處理結果:http://localhost:8401/rateLimit/byUrl
3.自定義限流處理邏輯
我們可以自定義通用的限流處理邏輯,然后在@SentinelResource中指定。
創建 CustomBlockHandler 類用於自定義限流處理邏輯:
package com.lee.handle;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import java.util.HashMap;
import java.util.Map;
public class CustomBlockHandler {
public static Map<String,Object> handleException(BlockException exception) {
Map<String,Object> result = new HashMap<>();
result.put("name","自定義限流信息");
result.put("code",200);
return result ;
}
}
在RateLimitController中自定義限流處理邏輯:
package com.lee.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.lee.handle.CustomBlockHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/rateLimit")
public class RateLimitController {
@GetMapping("/customBlockHandler")
@SentinelResource(value = "customBlockHandler", blockHandler = "handleException", blockHandlerClass = CustomBlockHandler.class)
public Map<String,Object> blockHandler() {
Map<String,Object> result = new HashMap<>();
result.put("name","限流成功");
result.put("code",200);
return result ;
}
}
五、熔斷功能
Sentinel 支持對服務間調用進行保護,對故障應用進行熔斷操作,這里我們使用RestTemplate來調用springboot-provider服務所提供的接口來演示下該功能。
springboot-provider服務提供的接口非常簡單:
package com.lee.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class TestController {
@GetMapping("/user/{id}")
public Map<String,Object> getInfo(@PathVariable(value = "id") String id) {
if("1".equals(id)) {
throw new RuntimeException("remote func is fail");
}
Map<String,Object> result = new HashMap<>();
result.put("reqData",id);
result.put("code","200");
return result ;
}
}
創建RestTemplate
package com.lee.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class CusConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
添加 CircleBreakerController 類,定義對springboot-provider提供接口的調用:
package com.lee.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/breaker")
public class CircleBreakerController {
private static final Logger LOGGER = LoggerFactory.getLogger(CircleBreakerController.class);
@Autowired
private RestTemplate restTemplate;
@Value("${service-url.user-service}")
private String userServiceUrl;
@GetMapping("/fallback/{id}")
@SentinelResource(value = "fallback", fallback = "handleFallback")
public Map<String,Object> fallback(@PathVariable Long id) {
Map<String,Object> forObject = restTemplate.getForObject(userServiceUrl + "/user/{1}", Map.class, id);
System.out.println(forObject);
return forObject;
}
@GetMapping("/fallbackException/{id}")
@SentinelResource(value = "fallbackException", fallback = "handleFallback2", exceptionsToIgnore = {NullPointerException.class})
public Map<String,Object> fallbackException(@PathVariable Long id) {
if (id == 1) {
throw new IndexOutOfBoundsException();
} else if (id == 2) {
throw new NullPointerException();
}
return restTemplate.getForObject(userServiceUrl + "/user/{1}", Map.class, id);
}
public Map<String,Object> handleFallback(Long id) {
Map<String,Object> result = new HashMap<>();
result.put("name","service degradation");
result.put("code",200);
return result ;
}
public Map<String,Object> handleFallback2(Long id, Throwable e) {
LOGGER.error("handleFallback2 id:{},throwable class:{}", id, e.getClass());
Map<String,Object> result = new HashMap<>();
result.put("name","service degradation");
result.put("code",200);
return result ;
}
}
啟動springboot-provider和springboot-sentinel服務:
如果id為1 的情況會返回服務降級結果:
http://localhost:8401/breaker/fallback/1
id為2時正常返回:
由於我們使用了 exceptionsToIgnore 參數忽略了 NullPointerException ,所以我們訪問接口報空指針時不會發生服務降級:
http://localhost:8401/breaker/fallbackException/2
六、與Feign結合使用
Sentinel也適配了Feign組件,我們使用Feign來進行服務間調用時,也可以使用它來進行熔斷。
首先我們需要在pom.xml中添加Feign相關依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在application.yml文件中打開Sentinel對Feign的支持:
# 打開sentinel對feign的支持
feign:
sentinel:
enabled: true
在應用啟動類上添加@EnableFeignClients啟動Feign的功能;
創建一個UserService接口,用於定義對springboot-provider服務的調用:
package com.lee.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.Map;
@FeignClient(value = "springboot-provider", fallback = UserFallbackService.class)
public interface UserService {
@GetMapping("/user/{id}")
Map<String,Object> getInfo(@PathVariable Long id);
}
創建UserFallbackService類實現UserService接口,用於處理服務降級邏輯:
package com.lee.service;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class UserFallbackService implements UserService {
@Override
public Map<String,Object> getInfo(Long id){
Map<String,Object> result = new HashMap<>();
result.put("name","service lower level");
result.put("code",200);
return result ;
}
}
在UserFeignController中使用UserService通過Feign調用springboot-provider服務中的接口:
package com.lee.controller;
import com.lee.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
@RequestMapping("/user")
public class UserFeignController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public Map<String,Object> getUser(@PathVariable Long id) {
return userService.getInfo(id);
}
}
在啟動類SentinelServiceApplication添加@EnableFeignClients注解
package com.lee;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
調用如下接口會發生服務降級,返回服務降級處理信息:http://localhost:8401/user/1
七、使用Nacos存儲規則
默認情況下,當我們在Sentinel控制台中配置規則時,控制台推送規則方式是通過API將規則推送至客戶端並直接更新到內存中。一旦我們重啟應用,規則將消失。下面我們介紹下如何將配置規則進行持久化,以存儲到Nacos為例。
1. 原理示意圖
首先我們直接在配置中心創建規則,配置中心將規則推送到客戶端;
Sentinel控制台也從配置中心去獲取配置信息。
2. 功能演示
先在pom.xml中添加相關依賴:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
修改application.yml配置文件,添加Nacos數據源配置:
spring:
application:
name: springboot-sentinel
cloud:
nacos:
discovery:
namespace: dev
server-addr: 192.168.0.130:8848
sentinel:
transport:
# 配置Sentinel dashborad地址
dashboard: http://localhost:8080
port: 8719
datasource:
- nacos:
server-addr: 192.168.0.130:8848
data-id: ${spring.application.name}-flow-rules
group-id: DEFAULT_GROUP
data-type: json
rule-type: flow
在Nacos中添加配置:
添加配置信息如下:
[
{
"app":"springboot-sentinel",
"clusterConfig":{
"fallbackToLocalWhenFail":true,
"sampleCount":10,
"strategy":0,
"thresholdType":0,
"windowIntervalMs":1000
},
"clusterMode":false,
"controlBehavior":0,
"count":1,
"gmtCreate":1617343597193,
"gmtModified":1617343597193,
"grade":1,
"id":1,
"ip":"192.168.0.130",
"limitApp":"default",
"port":8720,
"resource":"byUrl",
"strategy":0
}
]
常規參數解釋:
- resource:資源名稱;
- limitApp:來源應用;
- grade:閾值類型,0表示線程數,1表示QPS;
- count:單機閾值;
- strategy:流控模式,0表示直接,1表示關聯,2表示鏈路;
- controlBehavior:流控效果,0表示快速失敗,1表示Warm Up,2表示排隊等待;
- clusterMode:是否集群。
發現Sentinel控制台已經有了如下限流規則:
快速訪問測試接口,可以發現返回了限流處理信息:
到這已基本完成對sentinel的基本使用。現在從nacos修改的配置信息能夠同步到sentinel,但是從sentinel控制台修改的數據卻無法同步到nacos中,這樣兩邊都修改數據信息的話,對導致非常嚴重的后果。
3. Sentinel Dashboard集成Nacos實現規則同步
Sentinel Dashboard的流控規則下的所有操作,都會調用Sentinel-Dashboard源碼中的FlowControllerV1類,這個類中包含流控規則本地化 的CRUD操作。
另外,在com.alibaba.csp.sentinel.dashboard.controller.v2包下存在一個FlowControllerV2類,這個類同樣提供流控規則的CRUD,和V1版本不同的是,它可以實現指定數據源的規則拉取和發布。
@RestController
@RequestMapping(value = "/v2/flow")
public class FlowControllerV2 {
private final Logger logger = LoggerFactory.getLogger(FlowControllerV2.class);
@Autowired
private InMemoryRuleRepositoryAdapter<FlowRuleEntity> repository;
@Autowired
@Qualifier("flowRuleDefaultProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleDefaultPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
FlowControllerV2依賴以下兩個非常重要的類:
- DynamicRuleProvider: 動態規則的拉取,從指定數據源中獲取流控規則后在Sentinel Dashboard中展示。
- DynamicRulePublisher: 動態規則的發布,將在Sentinel Dashboard中修改的規則同步到指定數據源中。
我們可以擴展這兩個類,然后集成Nacos來實現Sentinel Dashboard規則的同步。
4. Sentinel Dashboard源碼修改
源碼下載地址:https://github.com/alibaba/Sentinel/releases
修改源碼,具體步驟如下:
- 使用IDEA工具打開sentinel-dashboard工程。
- 在pom.xml中把 sentinel-datasource-nacos 依賴的
注釋掉。 - 修改resources/app/scripts/directives/sidebar/sidebar.html文件中下面這段代碼,將dashboard.flowV1改成dashboard.flow,也就是去掉V1。修改之后,會調用FlowControllerV2中的接口。如果不修改,則調用FlowControllerV1中的接口(也可自行修改接口實現)
- 在com.alibaba.csp.sentinel.dashboard.rule包中創建一個nacos包,並創建一個類用來加載外部化配置。
package com.alibaba.csp.sentinel.dashboard.rule.nacos;
public final class NacosConfigUtil {
public static final String GROUP_ID = "SENTINEL_GROUP";
public static final String FLOW_DATA_ID_POSTFIX = "-flow-rules";
public static final String PARAM_FLOW_DATA_ID_POSTFIX = "-param-rules";
public static final String CLUSTER_MAP_DATA_ID_POSTFIX = "-cluster-map";
/**
* cc for `cluster-client`
*/
public static final String CLIENT_CONFIG_DATA_ID_POSTFIX = "-cc-config";
/**
* cs for `cluster-server`
*/
public static final String SERVER_TRANSPORT_CONFIG_DATA_ID_POSTFIX = "-cs-transport-config";
public static final String SERVER_FLOW_CONFIG_DATA_ID_POSTFIX = "-cs-flow-config";
public static final String SERVER_NAMESPACE_SET_DATA_ID_POSTFIX = "-cs-namespace-set";
private NacosConfigUtil() {}
}
- 創建一個NacosConfig 配置類
package com.alibaba.csp.sentinel.dashboard.rule.nacos;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigFactory;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.Properties;
/**
* @author Eric Zhao
* @since 1.4.0
*/
@Configuration
public class NacosConfig {
@Value("${sentinel.nacos.serverAddr}")
private String nacosAddr ;
@Bean
public Converter<List<FlowRuleEntity>, String> flowRuleEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter<String, List<FlowRuleEntity>> flowRuleEntityDecoder() {
return s -> JSON.parseArray(s, FlowRuleEntity.class);
}
@Bean
public ConfigService nacosConfigService() throws Exception {
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR,nacosAddr);
return NacosFactory.createConfigService(properties);
}
}
- 實現動態從Nacos配置中心獲取流控規則
@Component("flowRuleNacosProvider")
public class FlowRuleNacosProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {
@Autowired
private Converter<String, List<FlowRuleEntity>> converter;
@Value("${sentinel.nacos.group-id}")
private String groupId ;
@Autowired
private ConfigService configService ;
@Override
public List<FlowRuleEntity> getRules(String appName) throws Exception {
// Properties properties = new Properties();
// properties.put(PropertyKeyConst.SERVER_ADDR, nacosAddr);
// ConfigService configService = NacosFactory.createConfigService(properties);
// String rules = configService.getConfig(appName + NacosConfigUtil.FLOW_DATA_ID_POSTFIX, groupId, 5000);
// String serverAddr = "192.168.0.130:8848";
// String dataId = "springboot-sentinel-flow-rules";
// String group = "DEFAULT_GROUP";
// Properties properties = new Properties();
// properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
// ConfigService configService = NacosFactory.createConfigService(properties);
// String rules = configService.getConfig(dataId, group, 5000);
System.out.println(appName+NacosConfigUtil.FLOW_DATA_ID_POSTFIX);
String rules = configService.getConfig(appName + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
groupId, 5000);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return converter.convert(rules);
}
}
- 創建一個流控規則發布類,在Sentinel Dashboard上修改完配置后,需要調用該發布方法將數據持久化到Nacos中。
@Component("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {
@Autowired
private Converter<List<FlowRuleEntity>, String> converter;
@Value("${sentinel.nacos.group-id}")
private String groupId ;
@Autowired
private ConfigService configService ;
@Override
public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
// String serverAddr = "192.168.0.241:8848";
// String dataId = "springboot-docker-flow-rules";
// String group = "DEFAULT_GROUP";
// Properties properties = new Properties();
// properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
// ConfigService configService = NacosFactory.createConfigService(properties);
//
// configService.publishConfig(dataId,group,converter.convert(rules));
configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
groupId, converter.convert(rules));
}
}
- 修改FlowControllerV2類,將上面配置的兩個類注入進來,表示規則的拉取和規則的發布統一用我們前面定義的兩個實例,然后將FlowControllerV2這個類中的代碼覆蓋FlowControllerV1的代碼。
@RestController
@RequestMapping(value = "/v2/flow")
public class FlowControllerV2 {
private final Logger logger = LoggerFactory.getLogger(FlowControllerV2.class);
@Autowired
private InMemoryRuleRepositoryAdapter<FlowRuleEntity> repository;
@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
- 在application.properties文件中添加Nacos服務相關配置:
sentinel.nacos.serverAddr=192.168.0.241:8848
sentinel.nacos.namespace=
sentinel.nacos.group-id=DEFAULT_GROUP
- 打包
mvn clean package
- 修改sentinel控制台數據,則會同步到nacos中
修改前
修改后
nacos中
項目地址(包含編譯好的sentinel1.7.2版本的dashboard):https://gitee.com/enthusiasts/sentinel-nacos.git
參考文章:
https://blog.csdn.net/ThinkWon/article/details/103770879
https://www.jianshu.com/p/deb7daa715af