sentinel學習第一章:sentinel資料持久化到influxdb,實現流控和服務降級規則持久化到nacos,並實現推模式將規則推送到服務
技術標籤:監控程式
首先說明為啥要寫該博文,其實網上已經有很多相識文章,github上的sentinel文件也有相關說明,但是本人覺得太零散了,感覺寫的不好,所以特此總結,讓大家少踩點坑,一步到位。對過程不感興趣的可以直接拉到底部獲取已經配置好了的專案github地址
第一步:建立sentinel專案
去github上拉取sentinel原始碼(https://github.com/alibaba/Sentinel),如果嫌棄阿里開源的sentinel原始碼太多無用的其他專案也可以去碼雲上找個sentinel專案
第二步:資料持久化到influxdb
我們需要將qps相關資料持久化到influxdb,sentinel預設只儲存5分鐘內的qps監控,這些資料放在記憶體中,這肯定不滿足要求,所以我們準備用時序資料庫influxdb來儲存qps的訪問資料。
安裝influxdb的過程我這裡就不說了,網上一大堆,沒有什麼難度。
主要說一下sentinel-dashboard專案中怎麼配置,
1、在pom.xml中引入依賴
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
<version>2.15</version>
</dependency>
2、建立一個com.alibaba.csp.sentinel.dashboard.repository.metric.InfluxDb 包,包名字也可以不一樣,因為這不是重點,重點是在該包中建立InfluxDbConfig、InfluxdbMetricEntity、InfluxDbUtils、InInfluxdbMetricsRepository這四個類,
package com.alibaba.csp.sentinel.dashboard.repository.metric.InfluxDb;
import org.influxdb.InfluxDB;
import org.influxdb.InfluxDBFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
@Configuration
public class InfluxDbConfig {
@Value("${spring.influx.url:''}")
private String influxDBUrl;
@Value("${spring.influx.user:''}")
private String userName;
@Value("${spring.influx.password:''}")
private String password;
@Value("${spring.influx.database:''}")
private String database;
@Bean
public InfluxDB influxDB(){
InfluxDB influxDB = InfluxDBFactory.connect(influxDBUrl, userName, password);
try {
/**
* 非同步插入:
* enableBatch這裡第一個是point的個數,第二個是時間,單位毫秒
* point的個數和時間是聯合使用的,如果滿100條或者2000毫秒
* 滿足任何一個條件就會發送一次寫的請求。
*/
influxDB.setDatabase(database)
.enableBatch(100,2000, TimeUnit.MILLISECONDS);
} catch (Exception e) {
e.printStackTrace();
} finally {
influxDB.setRetentionPolicy("autogen");
}
influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);
return influxDB;
}
}
package com.alibaba.csp.sentinel.dashboard.repository.metric.InfluxDb;
import org.influxdb.annotation.Column;
import org.influxdb.annotation.Measurement;
import java.time.Instant;
/**
* @author zhipeng.zhang
* https://blog.52itstyle.vip
*/
@Measurement(name = "sentinelInfo")
public class InfluxdbMetricEntity {
@Column(name = "time")
private Instant time;
@Column(name = "gmtCreate")
private Long gmtCreate;
@Column(name = "gmtModified")
private Long gmtModified;
/**
* 監控資訊的時間戳
*/
@Column(name = "app", tag = true)
private String app;
@Column(name = "resource", tag = true)
private String resource;
@Column(name = "timestamp")
private Long timestamp;
@Column(name = "passQps")
private Long passQps;//通過qps
@Column(name = "successQps")
private Long successQps;//成功qps
@Column(name = "blockQps")
private Long blockQps;//限流qps
@Column(name = "exceptionQps")
private Long exceptionQps;//異常qps
/**
* 所有successQps的rt的和
*/
@Column(name = "rt")
private double rt;
/**
* 本次聚合的總條數
*/
@Column(name = "count")
private int count;
@Column(name = "resourceCode")
private int resourceCode;
public static InfluxdbMetricEntity copyOf(InfluxdbMetricEntity oldEntity) {
InfluxdbMetricEntity entity = new InfluxdbMetricEntity();
entity.setApp(oldEntity.getApp());
entity.setGmtCreate(oldEntity.getGmtCreate());
entity.setGmtModified(oldEntity.getGmtModified());
entity.setTimestamp(oldEntity.getTimestamp());
entity.setResource(oldEntity.getResource());
entity.setPassQps(oldEntity.getPassQps());
entity.setBlockQps(oldEntity.getBlockQps());
entity.setSuccessQps(oldEntity.getSuccessQps());
entity.setExceptionQps(oldEntity.getExceptionQps());
entity.setRt(oldEntity.getRt());
entity.setCount(oldEntity.getCount());
entity.setResource(oldEntity.getResource());
return entity;
}
public synchronized void addPassQps(Long passQps) {
this.passQps += passQps;
}
public synchronized void addBlockQps(Long blockQps) {
this.blockQps += blockQps;
}
public synchronized void addExceptionQps(Long exceptionQps) {
this.exceptionQps += exceptionQps;
}
public synchronized void addCount(int count) {
this.count += count;
}
public synchronized void addRtAndSuccessQps(double avgRt, Long successQps) {
this.rt += avgRt * successQps;
this.successQps += successQps;
}
/**
* {@link #rt} = {@code avgRt * successQps}
*
* @param avgRt average rt of {@code successQps}
* @param successQps
*/
public synchronized void setRtAndSuccessQps(double avgRt, Long successQps) {
this.rt = avgRt * successQps;
this.successQps = successQps;
}
public Long getGmtCreate() {
return gmtCreate;
}
public void setGmtCreate(Long gmtCreate) {
this.gmtCreate = gmtCreate;
}
public Long getGmtModified() {
return gmtModified;
}
public void setGmtModified(Long gmtModified) {
this.gmtModified = gmtModified;
}
public Long getTimestamp() {
return timestamp;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
public String getResource() {
return resource;
}
public void setResource(String resource) {
this.resource = resource;
this.resourceCode = resource.hashCode();
}
public Long getPassQps() {
return passQps;
}
public void setPassQps(Long passQps) {
this.passQps = passQps;
}
public Long getBlockQps() {
return blockQps;
}
public void setBlockQps(Long blockQps) {
this.blockQps = blockQps;
}
public Long getExceptionQps() {
return exceptionQps;
}
public void setExceptionQps(Long exceptionQps) {
this.exceptionQps = exceptionQps;
}
public double getRt() {
return rt;
}
public void setRt(double rt) {
this.rt = rt;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getResourceCode() {
return resourceCode;
}
public Long getSuccessQps() {
return successQps;
}
public void setSuccessQps(Long successQps) {
this.successQps = successQps;
}
public Instant getTime() {
return time;
}
public void setTime(Instant time) {
this.time = time;
}
public String getApp() {
return app;
}
public void setApp(String app) {
this.app = app;
}
@Override
public String toString() {
return "InfluxdbMetricEntity{" +
", gmtCreate=" + gmtCreate +
", gmtModified=" + gmtModified +
", timestamp=" + timestamp +
", resource='" + resource + '\'' +
", passQps=" + passQps +
", blockQps=" + blockQps +
", successQps=" + successQps +
", exceptionQps=" + exceptionQps +
", rt=" + rt +
", count=" + count +
", resourceCode=" + resourceCode +
'}';
}
}
package com.alibaba.csp.sentinel.dashboard.repository.metric.InfluxDb;
import org.influxdb.InfluxDB;
import org.influxdb.dto.Pong;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class InfluxDbUtils {
@Autowired
public InfluxDB influxDB;
/**
* 測試連線是否正常
* @return true 正常
*/
public boolean ping() {
boolean isConnected = false;
Pong pong;
try {
pong = influxDB.ping();
if (pong != null) {
isConnected = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return isConnected;
}
}
package com.alibaba.csp.sentinel.dashboard.repository.metric.InfluxDb;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.MetricEntity;
import com.alibaba.csp.sentinel.dashboard.repository.metric.MetricsRepository;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import org.influxdb.InfluxDB;
import org.influxdb.dto.BatchPoints;
import org.influxdb.dto.Point;
import org.influxdb.dto.Query;
import org.influxdb.dto.QueryResult;
import org.influxdb.impl.InfluxDBResultMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* Caches metrics data in a period of time in Influxdb.
* 參考:https://github.com/influxdata/influxdb-java
* 參考:https://blog.52itstyle.vip/archives/4460
* @author zhipeng.zhang
* https://blog.52itstyle.vip
*/
@Component("inInfluxdbMetricsRepository")
public class InInfluxdbMetricsRepository implements MetricsRepository<MetricEntity> {
@Autowired
public InfluxDB influxDB;
@Override
public synchronized void save(MetricEntity metric) {
try {
Point point = Point
.measurement("sentinelInfo")
.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
.tag("app",metric.getApp())//tag 資料走索引
.tag("resource",metric.getResource())//tag 資料走索引
.addField("gmtCreate", metric.getGmtCreate().getTime())
.addField("gmtModified", metric.getGmtModified().getTime())
.addField("timestamp", metric.getTimestamp().getTime())
.addField("passQps", metric.getPassQps())
.addField("successQps", metric.getSuccessQps())
.addField("blockQps", metric.getBlockQps())
.addField("exceptionQps", metric.getExceptionQps())
.addField("rt", metric.getRt())
.addField("count", metric.getCount())
.addField("resourceCode", metric.getResourceCode())
.build();
influxDB.write(point);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public synchronized void saveAll(Iterable<MetricEntity> metrics) {
if (metrics == null) {
return;
}
BatchPoints batchPoints = BatchPoints.builder()
.tag("async", "true")
.consistency(InfluxDB.ConsistencyLevel.ALL)
.build();
metrics.forEach(metric->{
Point point = Point
.measurement("sentinelInfo")
/**
* 這裡使用毫秒
* 但是從客戶端過來的請求可能是多個(部分靜態資源沒有被過濾掉)
* 導致資料唯一標識重複,後面資源的把前面的覆蓋點
* 如果還有覆蓋資料就使用微妙,保證 time 和 tag 唯一就可以
* 但是有個問題,使用微妙會導致查詢時間有問題,建議這裡過濾掉靜態請求
* 或者客戶端遮蔽
*/
.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
.tag("app",metric.getApp())//tag 資料走索引
.tag("resource",metric.getResource())//tag 資料走索引
.addField("gmtCreate", metric.getGmtCreate().getTime())
.addField("gmtModified", metric.getGmtModified().getTime())
.addField("timestamp", metric.getTimestamp().getTime())
.addField("passQps", metric.getPassQps())
.addField("successQps", metric.getSuccessQps())
.addField("blockQps", metric.getBlockQps())
.addField("exceptionQps", metric.getExceptionQps())
.addField("rt", metric.getRt())
.addField("count", metric.getCount())
.addField("resourceCode", metric.getResourceCode())
.build();
batchPoints.point(point);
});
influxDB.write(batchPoints);
}
@Override
public synchronized List<MetricEntity> queryByAppAndResourceBetween(String app, String resource, long startTime, long endTime) {
List<MetricEntity> results = new ArrayList<>();
if (StringUtil.isBlank(app)) {
return results;
}
String command = "SELECT * FROM sentinelInfo WHERE app='"+app+"' AND resource = '"+resource+"' AND gmtCreate>"+startTime+" AND gmtCreate<"+endTime;
Query query = new Query(command);
QueryResult queryResult = influxDB.query(query);
InfluxDBResultMapper resultMapper = new InfluxDBResultMapper(); // thread-safe - can be reused
List<InfluxdbMetricEntity> influxResults = resultMapper.toPOJO(queryResult, InfluxdbMetricEntity.class);
try {
influxResults.forEach(entity->{
MetricEntity metric = new MetricEntity();
BeanUtils.copyProperties(entity,metric);
metric.setTimestamp(new Date(entity.getTimestamp()));
metric.setGmtCreate(new Date(entity.getGmtCreate()));
metric.setGmtModified(new Date(entity.getGmtModified()));
results.add(metric);
});
} catch (Exception e) {
e.printStackTrace();
}
return results;
}
@Override
public synchronized List<String> listResourcesOfApp(String app) {
List<String> results = new ArrayList<>();
if (StringUtil.isBlank(app)) {
return results;
}
//最近一分鐘的指標(實時資料)
final long minTimeMs = System.currentTimeMillis() - 1000 * 60;
String command = "SELECT * FROM sentinelInfo WHERE app='"+app+"' AND gmtCreate>"+minTimeMs;
Query query = new Query(command);
QueryResult queryResult = influxDB.query(query);
InfluxDBResultMapper resultMapper = new InfluxDBResultMapper(); // thread-safe - can be reused
List<InfluxdbMetricEntity> influxResults = resultMapper.toPOJO(queryResult, InfluxdbMetricEntity.class);
try {
if (CollectionUtils.isEmpty(influxResults)) {
return results;
}
Map<String, InfluxdbMetricEntity> resourceCount = new HashMap<>(32);
for (InfluxdbMetricEntity metricEntity : influxResults) {
String resource = metricEntity.getResource();
if (resourceCount.containsKey(resource)) {
InfluxdbMetricEntity oldEntity = resourceCount.get(resource);
oldEntity.addPassQps(metricEntity.getPassQps());
oldEntity.addRtAndSuccessQps(metricEntity.getRt(), metricEntity.getSuccessQps());
oldEntity.addBlockQps(metricEntity.getBlockQps());
oldEntity.addExceptionQps(metricEntity.getExceptionQps());
oldEntity.addCount(1);
} else {
resourceCount.put(resource, InfluxdbMetricEntity.copyOf(metricEntity));
}
}
//排序
results = resourceCount.entrySet()
.stream()
.sorted((o1, o2) -> {
InfluxdbMetricEntity e1 = o1.getValue();
InfluxdbMetricEntity e2 = o2.getValue();
int t = e2.getBlockQps().compareTo(e1.getBlockQps());
if (t != 0) {
return t;
}
return e2.getPassQps().compareTo(e1.getPassQps());
})
.map(Map.Entry::getKey)
.collect(Collectors.toList());
} catch (Exception e) {
e.printStackTrace();
}
return results;
}
}
3、找到MetricFetcher、MetricController這兩個類,在如圖這個地方加上@Qualifier註解,兩個類都要加,別漏了
@Qualifier("inInfluxdbMetricsRepository")
4、在application.properties配置檔案中新增influxdb的相關配置,至此資料就持久化到influxdb了
spring.influx.url=http://127.0.0.1:8086
spring.influx.user=admin
spring.influx.password=admin
spring.influx.database=sentinel_log
第三步:流控規則持久化到nacos
1、建立com.alibaba.csp.sentinel.dashboard.rule.nacos.flow包和com.alibaba.csp.sentinel.dashboard.rule.nacos.degrade
2、flow包建立FlowRuleNacosProvider、FlowRuleNacosPublisher類,這是用來做流控規則持久化到nacos的
package com.alibaba.csp.sentinel.dashboard.rule.nacos.flow;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @author Eric Zhao
* @since 1.4.0
*/
@Component("flowRuleNacosProvider")
public class FlowRuleNacosProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private Converter<String, List<FlowRuleEntity>> converter;
@Override
public List<FlowRuleEntity> getRules(String appName) throws Exception {
String rules = configService.getConfig(appName + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
NacosConfigUtil.GROUP_ID, 3000);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return converter.convert(rules);
}
}
package com.alibaba.csp.sentinel.dashboard.rule.nacos.flow;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author Eric Zhao
* @since 1.4.0
*/
@Component("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private Converter<List<FlowRuleEntity>, String> converter;
@Override
public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
NacosConfigUtil.GROUP_ID, converter.convert(rules));
}
}
3、在degrade包建立兩個類DegradeRuleNacosProvider、DegradeRuleNacosPublisher,這是用來做服務降級規則持久化到nacos的
package com.alibaba.csp.sentinel.dashboard.rule.nacos.flow;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author Eric Zhao
* @since 1.4.0
*/
@Component("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private Converter<List<FlowRuleEntity>, String> converter;
@Override
public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
NacosConfigUtil.GROUP_ID, converter.convert(rules));
}
}
package com.alibaba.csp.sentinel.dashboard.rule.nacos.degrade;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.dashboard.rule.nacos.NacosConfigUtil;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author Eric Zhao
* @since 1.4.0
*/
@Component("degradeRuleNacosPublisher")
public class DegradeRuleNacosPublisher implements DynamicRulePublisher<List<DegradeRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private Converter<List<DegradeRuleEntity>, String> converter;
@Override
public void publish(String app, List<DegradeRuleEntity> rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
configService.publishConfig(app + NacosConfigUtil.DEGRADE_DATA_ID_POSTFIX,
NacosConfigUtil.GROUP_ID, converter.convert(rules));
}
}
4、覆蓋com.alibaba.csp.sentinel.dashboard.rule.nacos包下的NacosConfig、NacosConfigUtil類
package com.alibaba.csp.sentinel.dashboard.rule.nacos;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
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.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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
@EnableConfigurationProperties(NacosPropertiesConfiguration.class)
public class NacosConfig {
@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 Converter<List<DegradeRuleEntity>, String> DegradeRuleEntityEntityEncoder() {
return JSON::toJSONString;
}
@Bean
public Converter<String, List<DegradeRuleEntity>> DegradeRuleEntityEntityDecoder() {
return s -> JSON.parseArray(s, DegradeRuleEntity.class);
}
@Bean
public ConfigService nacosConfigService(NacosPropertiesConfiguration nacosPropertiesConfiguration) throws NacosException {
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, nacosPropertiesConfiguration.getServerAddr());
properties.put(PropertyKeyConst.NAMESPACE, nacosPropertiesConfiguration.getNamespace());
return ConfigFactory.createConfigService(properties);
}
}
package com.alibaba.csp.sentinel.dashboard.rule.nacos;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.RuleEntity;
import com.alibaba.csp.sentinel.dashboard.util.JSONUtils;
import com.alibaba.csp.sentinel.slots.block.Rule;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Eric Zhao
* @since 1.4.0
*/
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 DEGRADE_DATA_ID_POSTFIX = "-degrade-rules";
public static final String PARAM_FLOW_DATA_ID_POSTFIX = "-param-rules";
public static final String CLUSTER_MAP_DATA_ID_POSTFIX = "-cluster-map";
public static final String DASHBOARD_POSTFIX = "-dashboard";
/**
* 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() {}
}
5、在application.properties配置檔案中,增加nacos地址的配置
#nacos地址,ip+埠
sentinel.nacos.serverAddr=127.0.0.1:8848
#nacos的namespace
sentinel.nacos.namespace=64746c36-1234-4321-3211-28cb912345
6、最後感興趣的同學可以直接拉取我已經建立好的在github上的專案
地址:https://github.com/tansitao110/sentinel
第四步:在微服務的配置檔案中加入nacos相關配置
1、pom.xml中引入nacos、sentinel相關配置
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2、配置檔案中配置sentinel、nacos的相關流控推送規則
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080
datasource:
#流控、降級規則推模式配置
flow:
nacos:
server-addr: 127.0.0.1:8080
dataId: ${spring.application.name}-flow-rules
namespace: 64746c36-1234-4321-1234-28cb92446e20
rule-type: flow
groupId: SENTINEL_GROUP
degrade:
nacos:
server-addr: 127.0.0.1:8080
dataId: ${spring.application.name}-degrade-rules
namespace: 64746c36-1234-4321-1234-28cb92446e20
rule-type: degrade
groupId: SENTINEL_GROUP