前文介绍了Sentinel相关的核心概念,本文开始动手对规则管理推送进行改造。

这里挑选流控规则模式改造为示例

Sentinel Dashboard 改造

  1. com.alibaba.csp.sentinel.dashboard.rule.nacos新建NacosConfig.java

    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.PropertyKeyConst;
    import com.alibaba.nacos.api.config.ConfigFactory;
    import com.alibaba.nacos.api.config.ConfigService;
    import lombok.Getter;
    import lombok.Setter;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration; import java.util.List;
    import java.util.Properties; /**
    * @wiki https://github.com/eacdy/Sentinel-Dashboard-Nacos
    * add by tam
    */
    @Configuration
    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 ConfigService nacosConfigService() throws Exception {
    NacosProperties nacosProperties = nacosProperties();
    Properties properties = new Properties();
    properties.put(PropertyKeyConst.SERVER_ADDR, nacosProperties.getServerAddr());
    if (!nacosProperties.getNamespace().isEmpty()) {
    properties.put(PropertyKeyConst.NAMESPACE, nacosProperties.getNamespace());
    }
    return ConfigFactory.createConfigService(properties);
    } @Bean
    @ConfigurationProperties(prefix = "spring.cloud.sentinel.datasource.nacos")
    public NacosProperties nacosProperties() {
    return new NacosProperties();
    } @Getter
    @Setter
    public static class NacosProperties {
    private String serverAddr;
    private String namespace;
    private String groupId;
    }
    }

    这里主要接收三个参数 serverAddr: nacos服务器地址,namespace:nacos命名空间,groupId:nacos分组

    application.properties里新增配置

    spring.cloud.sentinel.datasource.nacos.server-addr=172.16.1.20:8848
    spring.cloud.sentinel.datasource.nacos.groupId=DEFAULT_GROUP
    spring.cloud.sentinel.datasource.nacos.namespace=wuyan_local
  2. 同级目录下新增NacosConfigUtil.java

    package com.alibaba.csp.sentinel.dashboard.rule.nacos;
    
    import com.alibaba.csp.sentinel.dashboard.util.JSONUtils;
    import com.alibaba.nacos.api.config.ConfigService;
    import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.RuleEntity;
    import com.alibaba.fastjson.JSON;
    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.exception.NacosException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component; import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors; /**
    * @wiki https://github.com/eacdy/Sentinel-Dashboard-Nacos
    * add by tam
    */
    @Component
    public class NacosConfigUtil {
    @Autowired
    private NacosConfig.NacosProperties nacosProperties; public static final String FLOW_DATA_ID_POSTFIX = "-flow-rules";
    public static final String DEGRADE_DATA_ID_POSTFIX = "-degrade-rules";
    public static final String SYSTEM_DATA_ID_POSTFIX = "-system-rules";
    public static final String PARAM_FLOW_DATA_ID_POSTFIX = "-param-flow-rules";
    public static final String AUTHORITY_DATA_ID_POSTFIX = "-authority-rules";
    public static final String GATEWAY_FLOW_DATA_ID_POSTFIX = "-gateway-flow-rules";
    public static final String GATEWAY_API_DATA_ID_POSTFIX = "-gateway-api-rules";
    public static final String DASHBOARD_POSTFIX = "-dashboard";
    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"; /**
    * 将规则序列化成JSON文本,存储到Nacos server中
    *
    * @param configService nacos config service
    * @param app 应用名称
    * @param postfix 规则后缀 eg.NacosConfigUtil.FLOW_DATA_ID_POSTFIX
    * @param rules 规则对象
    * @throws NacosException 异常
    */
    public <T> void setRuleStringToNacos(ConfigService configService, String app, String postfix, List<T> rules) throws NacosException {
    AssertUtil.notEmpty(app, "app name cannot be empty");
    if (rules == null) {
    return;
    } List<Rule> ruleForApp = rules.stream()
    .map(rule -> {
    RuleEntity rule1 = (RuleEntity) rule;
    //System.out.println(rule1.getClass());
    Rule rule2 = rule1.toRule();
    //System.out.println(rule2.getClass());
    return rule2;
    })
    .collect(Collectors.toList()); // 存储,给微服务使用
    String dataId = genDataId(app, postfix);
    configService.publishConfig(
    dataId,
    nacosProperties.getGroupId(),
    JSON.toJSONString(ruleForApp)
    ); // 存储,给控制台使用
    configService.publishConfig(
    dataId + DASHBOARD_POSTFIX,
    nacosProperties.getGroupId(),
    JSONUtils.toJSONString(rules)
    );
    } /**
    * 从Nacos server中查询响应规则,并将其反序列化成对应Rule实体
    *
    * @param configService nacos config service
    * @param appName 应用名称
    * @param postfix 规则后缀 eg.NacosConfigUtil.FLOW_DATA_ID_POSTFIX
    * @param clazz 类
    * @param <T> 泛型
    * @return 规则对象列表
    * @throws NacosException 异常
    */
    public <T> List<T> getRuleEntitiesFromNacos(ConfigService configService, String appName, String postfix, Class<T> clazz) throws NacosException {
    String rules = configService.getConfig(
    genDataId(appName, postfix) + DASHBOARD_POSTFIX,
    //genDataId(appName, postfix),
    nacosProperties.getGroupId(),
    3000
    );
    if (StringUtil.isEmpty(rules)) {
    return new ArrayList<>();
    }
    return JSONUtils.parseObject(clazz, rules);
    } private static String genDataId(String appName, String postfix) {
    return appName + postfix;
    }

    注意这里的dataId完整的为 【appId(即客户端spring.application.name配置应用名)+ -flow-rules

    这个很重要,客户端在集成nacos的sentinel配置时这个要对应

  3. com.alibaba.csp.sentinel.dashboard.rule.nacos.flow目录下新建FlowRuleNacosProvider.java

    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.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
    * add by tam
    */
    @Component("flowRuleNacosProvider")
    public class FlowRuleNacosProvider implements DynamicRuleProvider<List<FlowRuleEntity>> { @Autowired
    private ConfigService configService; @Autowired
    private NacosConfigUtil nacosConfigUtil; @Override
    public List<FlowRuleEntity> getRules(String appName) throws Exception {
    return nacosConfigUtil.getRuleEntitiesFromNacos(
    this.configService,
    appName,
    NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
    FlowRuleEntity.class
    );
    }
    }

    这个类主要从Nacos拉取规则信息

  4. com.alibaba.csp.sentinel.dashboard.rule.nacos.flow目录下新建FlowRuleNacosPublisher.java

    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.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
    * add by tam
    */
    @Component("flowRuleNacosPublisher")
    public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> { @Autowired
    private ConfigService configService; @Autowired
    private NacosConfigUtil nacosConfigUtil; @Override
    public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
    nacosConfigUtil.setRuleStringToNacos(
    this.configService,
    app,
    NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
    rules
    );
    }
    }
  5. 修改com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2

    	@Autowired
    @Qualifier("flowRuleNacosProvider")
    private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
    @Autowired
    @Qualifier("flowRuleNacosPublisher")
    private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;

    主要增加 @Qualifier("flowRuleNacosProvider")@Qualifier("flowRuleNacosPublisher")

Sentinel接入客户端

项目如果是SpringCloud项目在pom文件里引入

		<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency> <dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

bootstrap.properties新增如下配置

server.port=8002
spring.application.name=qetesh-openapi
spring.cloud.nacos.discovery.server-addr=172.16.1.20:8848
spring.cloud.nacos.discovery.namespace=wuyan_local spring.cloud.sentinel.transport.dashboard=localhost:8888
spring.cloud.sentinel.eager=true
spring.cloud.sentinel.datasource.ds1.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.ds1.nacos.dataId=${spring.application.name}-flow-rules
spring.cloud.sentinel.datasource.ds1.nacos.namespace=wuyan_local
spring.cloud.sentinel.datasource.ds1.nacos.groupId=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow

注意三个参数 serverAddrnamespacegroupId 和Dashboard的保持一致

并且spring.cloud.sentinel.datasource.ds1.nacos.rule-type 值为flow(流控)

在启动类增加如下代码

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; @SpringBootApplication
@EnableDiscoveryClient
public class QeteshOpenapiApplication { public static void main(String[] args) {
SpringApplication.run(QeteshOpenapiApplication.class, args);
} @RestController
static class TestController { @SentinelResource("ken2")
@GetMapping("/hello")
public String hello() {
return "itweek.top";
} } }

启动项目访问接口,在DashBoard里就能看到相关的配置

在流控规则里新增如下配置,

这时在nacos也会有相应的配置

多次访问接口会出现 即代表流控规则限流成功

生产环境Sentinel改造实践(二):规则管理推送改造的更多相关文章

  1. React 与 Redux 在生产环境中的实践总结

    React 与 Redux 在生产环境中的实践总结 前段时间使用 React 与 Redux 重构了我们360netlab 的 开放数据平台.现将其中一些技术实践经验总结如下: Universal 渲 ...

  2. Redash(开源轻量级商业智能) 生产环境部署及实践 (without docker)

    一直在调研一个轻量级开源的 BI 系统.之前我们生产环境使用的 aliyun 的 QuickBi,也调研了另外一个 airflow 的开源商业智能 superset.不得不承认 QuickBI 正在日 ...

  3. 生产环境 tidb部署实践

    TiDB 简介 TiDB 是 PingCAP 公司受 Google Spanner / F1 论文启发而设计的开源分布式 HTAP (Hybrid Transactional and Analytic ...

  4. 前端通信:SSE设计方案(二)--- 服务器推送技术的实践以及一些应用场景的demo(包括在线及时聊天系统以及线上缓存更新,代码热修复案例)

    距离上一篇博客,这篇文章的发布大概过了整整三个月.我也从饿了么度过了试用期,成为了正式员工.刚进来恰好遇到项目底层改造和迁移,将项目从angular全部迁移到vue上,所以适应这边的节奏和业务的开发任 ...

  5. 阿里巴巴微服务与配置中心技术实践之道 配置推送 ConfigurationManagement ConfigDrivenAnyting

    阿里巴巴微服务与配置中心技术实践之道 原创: 坤宇 InfoQ 2018-02-08 在面向分布式的微服务系统中,如何通过更高效的配置管理方式,帮助微服务系统架构持续"无痛"的演进 ...

  6. AndroidStudio离线打包MUI集成JPush极光推送并在java后端管理推送

    1.AndroidStudio离线打包MUI 如何离线打包请参看上篇随笔<AndroidStudio离线打包MUI> 2.集成极光推送 官方文档:https://docs.jiguang. ...

  7. Win10环境下使用Flask配合Celery异步推送实时/定时消息(Socket.io)/2020年最新攻略

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_163 首先得明确一点,和Django一样,在2020年Flask 1.1.1以后的版本都不需要所谓的三方库支持,即Flask-Ce ...

  8. git 分支管理 推送本地分支到远程分支等

    1.创建本地分支 local_branch git branch local_branch 2.创建本地分支local_branch 并切换到local_branch分支 git checkout - ...

  9. Spring Cloud Alibaba学习笔记(7) - Sentinel规则持久化及生产环境使用

    Sentinel 控制台 需要具备下面几个特性: 规则管理及推送,集中管理和推送规则.sentinel-core 提供 API 和扩展接口来接收信息.开发者需要根据自己的环境,选取一个可靠的推送规则方 ...

  10. Dubbo Mesh 在闲鱼生产环境中的落地实践

    本文作者至简曾在 2018 QCon 上海站以<Service Mesh 的本质.价值和应用探索>为题做了一次分享,其中谈到了 Dubbo Mesh 的整体发展思路是“借力开源.反哺开源” ...

随机推荐

  1. Linux_进程理解、状态与优先级(详细版)

    1.进程的概念 课本概念:程序的一个执行实例,正在执行的程序等. 内核观点:担当分配系统资源(CPU时间,内存)的实体. 其实:进程=内核的相关管理数据结构(task_struct.页表等)+程序的代 ...

  2. C#/.NET/.NET Core技术前沿周刊 | 第 11 期(2024年10.21-10.31)

    前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...

  3. NOIP2024模拟11:忠于自我

    NOIP2024模拟11:忠于自我 T1 一句话题意:有若干个容量为 \(L\) 的包,从左往右装物品,当前包还能装则装,否则必须重开一个包装进去,对于\(\forall i \in [1,n]\), ...

  4. Mysql篇-Buffer Pool中的三大链表

    为什么要有 Buffer Pool? 虽然说 MySQL 的数据是存储在磁盘里的,但是也不能每次都从磁盘里面读取数据,这样性能是极差的. 要想提升查询性能,那就加个缓存.所以,当数据从磁盘中取出后,缓 ...

  5. 配置NVIDIA Container Runtime和容器运行GPUStack教程

    GPUStack 是一个设计用于运行大模型的开源 GPU 集群管理器,提供私有部署的大模型服务,支持大语言模型.Embedding 文本嵌入模型.Reranker 重排序模型.Vision 多模态模型 ...

  6. 微信小程序原生AI运动(动作)检测识别解决方案

    前几年受疫情影响,人员流动受限,反而让"AI运动"概念风靡一时.空前火爆.目前已经在AI运动锻炼.体育教学.线上运动主题活动等场景中,成功得到了应用,并获得了广大互联网用户的认可. ...

  7. 5. Spring Cloud OpenFeign 声明式 WebService 客户端的超详细使用

    5. Spring Cloud OpenFeign 声明式 WebService 客户端的超详细使用 @ 目录 5. Spring Cloud OpenFeign 声明式 WebService 客户端 ...

  8. MMORPG技能管线设计经验总结

    导语: 表现丰富.机制多变的技能作为MMORPG游戏战斗体验的核心组成部分,是吸引玩家的一大亮点,本文总结了在MMORPG技能系统设计上的一些经验,供大家参考. 1.设计思路 早期的MMORPG手游中 ...

  9. ThreeJs-03材质进阶

    一.uv贴图 在3D计算机图形学中,UV映射是一种将2D纹理映射到3D模型表面的方法.在这里,"U"和"V"代表了2D纹理空间的坐标,这与2D笛卡尔坐标系统中的 ...

  10. k8s之常见问题汇总

    1.服务器中的k8s已经被移除,但是磁盘依然有占用, 于是将其卸载并删除操作 [root@k8s-node2 k8s_node]# rm -rf /var/lib/kubelet rm: cannot ...