做网站的技术哪个简单,长沙seo优化首选,西安直播室网站建设,烟台网站推广哪家好B站视频讲解
学习链接#x1f517; 文章目录 一、理论二、实践2-1、dashboard 请求Redis2-1-1、依赖、配置文件引入2-1-2、常量定义2-1-3、改写唯一id2-1-4、新Provider和Publisher2-1-5、改写V2 2-2、应用服务改造2-2-1、依赖、配置文件引入2-2-2、注册监听器 三、源码获取3…B站视频讲解
学习链接 文章目录 一、理论二、实践2-1、dashboard 请求Redis2-1-1、依赖、配置文件引入2-1-2、常量定义2-1-3、改写唯一id2-1-4、新Provider和Publisher2-1-5、改写V2 2-2、应用服务改造2-2-1、依赖、配置文件引入2-2-2、注册监听器 三、源码获取3-1、使用3-2、获取方式 四、参考 上一篇讲Sentinel的时候是用dashboard直接和服务进行交互实时的新增/删除限流规则所有的规则都存储在应用服务的内存中每次重启服务之后再刷新dashboard就没有对应规则信息了。
这当然不是我们希望看到的如果想要长久的保存规则有且只有一个办法那就是规则数据持久化。 一、理论 既然dashboard可以把规则推送到服务端那服务端就可以拿到规则去持久化到硬盘上文件、MySQL…怎么说呢这看起来不是个好办法首先它很low其次也不好解决分布式系统数据一致性的问题。那换一种思路dashboard先把规则推送给A再由A把规则下发到各个具体的应用服务。这样A就相当于一种中心存储解决了数据存储的问题同时A实时下发给应用服务解决了数据一致性的问题。
这个A官方给出了几种实现Nacos、ZooKeeper、Apollo、Redis。理论上是可以自己去重写做到任何实现 第一种方式就不推荐了下面基于方式二来做实践这里选用Redis来主要是目前电脑只安装了Redis原理是一样的。 下面是官方给出的图要理解是先把规则给到A再由A去下发规则。所以需要修改dashboard源码让它先请求A 想深入了解的可以参看下面的文档
https://github.com/alibaba/Sentinel/wiki/动态规则扩展https://github.com/alibaba/Sentinel/wiki/在生产环境中使用-Sentinel 二、实践 基于上面的分析需要分两步改造
让dashboard把规则数据推送给Redis应用服务接受Redis的下发基于Redis的发布订阅功能
注会在Redis定义一个Key用来存储最终的规则数据还会定义一个通道用来实时推送规则数据 2-1、dashboard 请求Redis 从Github下载dashboard源码https://github.com/alibaba/Sentinel/releases
默认情况下dashboard限流策略请求的是这个 v1 接口官方还提供了一个 v2这个v2就是持久化的接口基于不同的持久化策略只需要在 v2的版本里面替换对应的 DynamicRuleProvider、DynamicRulePublisher 2-1-1、依赖、配置文件引入 1、Redis-starter 引入
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactIdversion${spring.boot.version}/version
/dependency2、配置文件修改
spring.redis.host127.0.0.1
spring.redis.port6379
spring.redis.database03、Redis配置
Configuration
public class RedisConfig {Beanpublic RedisTemplateString, Object redisTemplate(RedisConnectionFactory factory) {RedisTemplateString, Object redisTemplate new RedisTemplateString, Object();redisTemplate.setConnectionFactory(factory);redisTemplate.setEnableTransactionSupport(true);GenericJackson2JsonRedisSerializer jsonRedisSerializer new GenericJackson2JsonRedisSerializer();StringRedisSerializer stringRedisSerializer new StringRedisSerializer();redisTemplate.setValueSerializer(jsonRedisSerializer);redisTemplate.setKeySerializer(stringRedisSerializer);redisTemplate.setHashKeySerializer(stringRedisSerializer);redisTemplate.setHashValueSerializer(jsonRedisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate;}
}2-1-2、常量定义 public final class Constants {// 最终规则是存储的keypublic static final String RULE_FLOW_PREFIX sentinel:rule:flow:xdx;// Redis的订阅发布功能需要一个通道public static final String RULE_FLOW_CHANNEL_PREFIX sentinel:channel:flow:xdx;// 每一个规则都需要唯一id基于Redis生成idpublic static final String RULE_FLOW_ID_KEY sentinel:id:flow:xdx;
}2-1-3、改写唯一id import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;Component
public class RedisIdGenerator {Autowiredprivate RedisTemplateString, Object redisTemplate;public long nextId(String key) {return redisTemplate.opsForValue().increment(key, 1);}
}2-1-4、新Provider和Publisher Provider的目的是读取Redis的内存数据
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;import java.util.Collections;
import java.util.List;import static com.alibaba.csp.sentinel.dashboard.xdx.Constants.RULE_FLOW_PREFIX;Component(flowRuleRedisProvider)
public class FlowRuleRedisProvider implements DynamicRuleProviderListFlowRuleEntity {private final Logger logger LoggerFactory.getLogger(FlowRuleRedisProvider.class);Autowiredprivate RedisTemplateString, Object redisTemplate;Overridepublic ListFlowRuleEntity getRules(String appName) throws Exception {Assert.notNull(appName, 应用名称不能为空);logger.info(拉取redis流控规则开始: {}, appName);String key RULE_FLOW_PREFIX;String ruleStr (String)redisTemplate.opsForValue().get(key);if(StringUtils.isEmpty(ruleStr)) {return Collections.emptyList();}ListFlowRuleEntity rules JSON.parseArray(ruleStr, FlowRuleEntity.class);logger.info(拉取redis流控规则成功, 规则数量: {}, rules.size());return rules;}
}每次规则变动都把最新规则存到Redis里面去并使用Redis通道发布
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;import java.util.List;import static com.alibaba.csp.sentinel.dashboard.xdx.Constants.RULE_FLOW_CHANNEL_PREFIX;
import static com.alibaba.csp.sentinel.dashboard.xdx.Constants.RULE_FLOW_PREFIX;Component(flowRuleRedisPublisher)
public class FlowRuleRedisPublisher implements DynamicRulePublisherListFlowRuleEntity {private final Logger logger LoggerFactory.getLogger(FlowRuleRedisPublisher.class);Autowiredprivate RedisTemplateString, Object redisTemplate;Overridepublic void publish(String app, ListFlowRuleEntity rules) throws Exception {Assert.notNull(app, 应用名称不能为空);Assert.notEmpty(rules, 策略规则不为空);logger.info(推送流控规则开始, 应用名: {}, 规则数量: {}, app, rules.size());String ruleKey RULE_FLOW_PREFIX;String ruleStr JSON.toJSONString(rules);// 数据存储redisTemplate.opsForValue().set(ruleKey, ruleStr);// 数据发布redisTemplate.convertAndSend(RULE_FLOW_CHANNEL_PREFIX, ruleStr);}
}2-1-5、改写V2 刚刚说默认是请求V1版本这里为了简单直接把V1的RequestMapping注释把V2的RequestMapping改成V1可以改前端让它请求到V2把新 V1的Publisher和Provider改成新的Redis版本下图也是每个类的位置 2-2、应用服务改造 https://github.com/alibaba/Sentinel/wiki/动态规则扩展Sentinel 官方已经做了Redis适配使用起来也很简单了 2-2-1、依赖、配置文件引入 1、新增pom文件
dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-redis/artifactIdversion1.8.6/version
/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId
/dependency2、配置文件
spring:redis:host: 127.0.0.1port: 63793、Redis 配置文件和上面一样
Configuration
public class ConfigRedis {Beanpublic RedisTemplateString, Object redisTemplate(RedisConnectionFactory factory) {RedisTemplateString, Object redisTemplate new RedisTemplateString, Object();redisTemplate.setConnectionFactory(factory);redisTemplate.setEnableTransactionSupport(true);GenericJackson2JsonRedisSerializer jsonRedisSerializer new GenericJackson2JsonRedisSerializer();StringRedisSerializer stringRedisSerializer new StringRedisSerializer();redisTemplate.setValueSerializer(jsonRedisSerializer);redisTemplate.setKeySerializer(stringRedisSerializer);redisTemplate.setHashKeySerializer(stringRedisSerializer);redisTemplate.setHashValueSerializer(jsonRedisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate;}
}2-2-2、注册监听器 直接在启动类里面改造就好了
SpringBootApplication
public class App11 implements ApplicationRunner {public static void main(String[] args) {SpringApplication.run(App11.class, args);}public static final String RULE_FLOW_PREFIX sentinel:rule:flow:xdx;public static final String RULE_FLOW_CHANNEL_PREFIX sentinel:channel:flow:xdx;Overridepublic void run(ApplicationArguments args) {ConverterString ,ListFlowRule parser source - {ListFlowRule flowRules new ArrayList();if (source ! null) {String replace source.replace(\\, );String substring replace.substring(1, replace.length() - 1);flowRules JSON.parseArray(substring, FlowRule.class);}return flowRules;};RedisConnectionConfig config RedisConnectionConfig.builder().withHost(127.0.0.1).withPort(6379).build();ReadableDataSourceString, ListFlowRule redisDataSource new RedisDataSource(config, RULE_FLOW_PREFIX, RULE_FLOW_CHANNEL_PREFIX, parser);FlowRuleManager.register2Property(redisDataSource.getProperty());System.out.println(redis-sentinel-持久化开启);}
}三、源码获取 3-1、使用 下面是修改好的sentinel-dashboard和对应的应用服务只需要修改两个服务中的Redis连接地址就可以使用如果你的Redis是 默认的127.0.0.1 和 6379 则无需修改。 3-2、获取方式 关注微信公众号小道仙97回复关键字Sentinel_xdx97 四、参考 https://github.com/all4you/sentinel-tutorial/blob/master/sentinel-practice/sentinel-persistence-rules/sentinel-persistence-rules.mdhttps://sentinelguard.io/zh-cn/blog/use-sentinel-dashboard-in-production.htmlhttps://github.com/alibaba/Sentinel/tree/master/sentinel-extension/sentinel-datasource-redishttps://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95https://github.com/alibaba/Sentinel/tree/master/sentinel-extension/sentinel-datasource-redishttps://www.jianshu.com/p/997a2255ff23https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinelhttps://github.com/alibaba/Sentinel/wiki/Sentinel-%E6%8E%A7%E5%88%B6%E5%8F%B0%EF%BC%88%E9%9B%86%E7%BE%A4%E6%B5%81%E6%8E%A7%E7%AE%A1%E7%90%86%EF%BC%89#%E8%A7%84%E5%88%99%E9%85%8D%E7%BD%AEhttps://blog.csdn.net/qq_42714869/article/details/94553378