sentinel+springboot+zookeeper集成,通过dashboard简单使用限流功能
好久没有写博客了,这几天调研了阿里开源的sentinel限流工具,据说双十一采用的也是此功能,调研了几天遇到了不少坑,主要集成一下,便于大家了解。sentinel的原理这里不介绍,为何要使用zookeeper来说一下,不使用zookeeper这些配置中心的话相当于直接通过dashboard调用server端,这样每次的限流配置只是在java的内存中生效,在项目重启之后,信息就丢失了,所以需要一..
好久没有写博客了,这几天调研了阿里开源的sentinel限流工具,据说双十一采用的也是此功能,调研了几天遇到了不少坑,主要集成一下,便于大家了解。
sentinel的原理这里不介绍,为何要使用zookeeper来说一下,不使用zookeeper这些配置中心的话相当于直接通过dashboard调用server端,这样每次的限流配置只是在java的内存中生效,在项目重启之后,信息就丢失了,所以需要一个数据源去存储这些信息,因为我们原来的项目中使用了zookeeper,所以这里介绍些zookeeper的使用
首先说下server端,在pom下引入sentinel的集成包
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>1.5.1.RELEASE</version>
</dependency>
注意版本号,springboot2.0以上要用2.X的版本,引用此dependency之后不需要按照官网上在去引用其他jar包,此包下包含的信息包括如下包
此处有两个坑
1.结合sentinel自带的dashboard在使用时必须和使用的版本一直,如上图中为1.7.0版本,则dashboard也必须为1.7.0,否则点击规则调用会报错
2.还有一个更深的坑是fastjson的版本也必须一致,否则点击规则后会不生效,也没有错误提示....sentinel的版本是1.2.62。如果不希望修改自己引用fastjson版本号,需要下载dashboard的源码修改fastjson版本,版本必须一致才可以
使用zookeeper的时候需要引入
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-zookeeper</artifactId>
<version>1.7.0</version>
</dependency>
此处也需要注意保持版本号一致
spring-cloud-starter-alibaba-sentinel这个集成很强大,我们并不需要去初始化任何bean对象,因为在启动的时候会自动加载上,所以只需要配置控制台和zookeeper的数据读取方式
控制台配置:
在application.yml下添加
spring:
application:
name: test
cloud:
sentinel:
transport:
port: 9303
dashboard: 192.168.2.86:8010
#heartbeatIntervalMs:
eager: true
enabled: true
#datasource:
#ds1:
#file:
#file: classpath:sentinel/flow-rule.json
#data-type: json
#rule-type: flow
port的概念:在项目和控制台之间通讯有个心跳信息,其实是单独启动了一个http的server在和控制台保持连接,所以需要单独开通一个端口号,dashboard即代表对应的控制台地址,以保持通讯
zookeeper配置
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.zookeeper.ZookeeperDataSource;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
/**
* @author zhangrui
* @createDate 2020/1/14 0014
*/
@Slf4j
@Component
public class ZookeeperSentinelConfig {
@Value("${spring.application.name}")
private String appName;
@Value("${zookeeper.servers}")
private String zookeeperAddress;
@PostConstruct
public void loadRules() {
/*try {
//需要转换成流的形式加载
File file = ResourceUtils.getFile("classpath:sentinel/flow-rule.json");
//读取本地配置
ReadableDataSource<String, List<FlowRule>> flowRuleDataSourceLocal = new FileRefreshableDataSource<>(file,
source -> JSON.parseObject(
source,
new TypeReference<List<FlowRule>>() {
}
));
FlowRuleManager.register2Property(flowRuleDataSourceLocal.getProperty());
} catch (Exception e) {
log.error("init localRules failed");
log.error(e.getMessage(), e);
}*/
//final String remoteAddress = "127.0.0.1:2181,192.168.0.2:2181";
final String path = "/sentinel_rule_config/" + appName;
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new ZookeeperDataSource<>(zookeeperAddress, path,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}
}
此处zookeeper可以是集群,也可是单点配置,都是支持的。注释里包含了读取本地json文件的配置,感兴趣的可以试试,不过由于springboot最后是由jar包启动,所以打包后启动有问题,目前还没有解决...
重要的配置是这里:
final String path = "/sentinel_rule_config/" + appName;
最后在dashboard中进行配置,需要保持一致。
在这里项目配置完毕,需要配置控制台
去官网下载对应的jar包源码,因为代码有几处坑,所以必须修改代码解决...
打开源码,一个正规的springboot的项目
找到生成Id的地方如下
@Component
public class InMemGatewayFlowRuleStore extends InMemoryRuleRepositoryAdapter<GatewayFlowRuleEntity> {
private static AtomicLong ids = new AtomicLong(0);
@Override
protected long nextId() {
return ids.incrementAndGet();
}
}
修改为:
@Component
public class InMemGatewayFlowRuleStore extends InMemoryRuleRepositoryAdapter<GatewayFlowRuleEntity> {
private static AtomicLong ids = new AtomicLong(System.currentTimeMillis());
@Override
protected long nextId() {
return ids.incrementAndGet();
}
}
原因是因为dashboard每次以0为计数,这样会导致推送的规则覆盖之前的信息,所以必须修改这里,有好几处这样生成规则的地方,都需要进行修改
之后将pom文件中的zookeeper设置注释掉
nacos和apollo也是类似的~
在test文件中找到已经包含的zookeeper类,粘贴至项目中
此处还有一个坑,打开FlowRuleZookeeperProvider
修改为如下:
@Override
public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
String path = ZookeeperConfigUtil.getPath(app);
Stat stat = zkClient.checkExists().forPath(path);
if (stat == null) {
zkClient.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath(path, null);
}
byte[] data = CollectionUtils.isEmpty(rules) ? "[]".getBytes() : converter.convert(rules).getBytes();
zkClient.setData().forPath(path, data);
}
其实就是将publish中判断path的地方在provider中进行了添加,否则在查询时zookeeper可能会报错
之后确定ConfigUtil中的root_path和项目中保持一致
config中的zookeeper地址和项目保持一致
之后打开FlowControllerV2,指定两个接口的引用改为zookeeper的引用
之后再打开sidebar.html,将原来flowV1改为flow,并去掉一个判断,改为永久可见,如下图
更改完以上配置之后,即可重新打包进行部署
启动命令如下:
nohup java -Xmx512M -Xms512M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./jvm-dump.hprof -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:./logs/gc.log -XX:-OmitStackTraceInFastThrow -Dserver.port=8010 -Dcsp.sentinel.dashboard.server=192.168.2.86:8010 -Dproject.name=sentinel-dashboard -Dcsp.sentinel.log.dir=./logs/ -jar sentinel-dashboard.jar
server.port需要和项目配置地址保持一致,否则会找不到项目
之后启动控制台,看到对应的项目,即可配置限流功能,在客户端或dashboard启动后限流依旧生效
文章参考信息:
官网地址:
https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
简易使用:
https://github.com/alibaba/Sentinel/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8
主流框架适配
https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#spring-cloud
官方springcloud支持
https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
改造控制台存储规则
https://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-Sentinel
动态规则拓展
https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95
常见错误
https://github.com/alibaba/Sentinel/wiki/FAQ
本地新建bean持久化
https://www.cnblogs.com/zhangpan1244/p/11228020.html
springcloud配置
https://blog.csdn.net/cdy1996/article/details/87391609
https://blog.csdn.net/u010391342/article/details/86678637
https://tianyalei.blog.csdn.net/article/details/89916891
https://blog.csdn.net/tianyaleixiaowu/article/details/94442906
源码解析:
https://www.jianshu.com/p/0e218ef7f505
https://www.jianshu.com/p/6ee4b7bdb844
zookeeper改造
https://blog.csdn.net/tianyaleixiaowu/article/details/94442906
https://blog.csdn.net/rodbate/article/details/89763669
更多推荐
所有评论(0)