欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

sentinel学习第一章:sentinel数据持久化到influxdb,实现流控和服务降级规则持久化到nacos,并实现推模式将规则推送到服务

程序员文章站 2022-06-19 17:43:37
首先说明为啥要写该博文,其实网上已经有很多相识文章,github上的sentinel文档也有相关说明,但是本人觉得太零散了,感觉写的不好,所以特此总结,让大家少踩点坑,一步到位。对过程不感兴趣的可以直接拉到底部获取已经配置好了的项目github地址第一步:创建sentinel项目去github上拉取sentinel源码(https://github.com/alibaba/Sentinel),如果嫌弃阿里开源的sentinel源码太多无用的其他项目也可以去码云上找个sentinel项目第二步:数据持久...

首先说明为啥要写该博文,其实网上已经有很多相识文章,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注解,两个类都要加,别漏了

sentinel学习第一章:sentinel数据持久化到influxdb,实现流控和服务降级规则持久化到nacos,并实现推模式将规则推送到服务

@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

本文地址:https://blog.csdn.net/tansitao110/article/details/111990270

相关标签: 监控程序