上一篇做了简单的zuul集成Sentinel,是在zuul代码中直接写的rule规则,无法完成动态变化的功能。
那么和普通的实例限流一样,zuul的限流也支持动态的。
话不多说,直接上代码,在pom中,把我注释掉的部分给放开。
还是在原来的config类里加上这一个方法
private void initZookeeperApis() {
final String remoteAddress = "127.0.0.1:2181";
final String path = "/sentinel_zuul_rule_config/zuulConfig";
//监听zookeeper,使用zookeeper的规则
ReadableDataSource<String, Set<GatewayFlowRule>> flowRuleDataSource = new ZookeeperDataSource<>(remoteAddress, path,
source -> JSON.parseObject(source, new TypeReference<Set<GatewayFlowRule>>() {
}));
GatewayRuleManager.register2Property(flowRuleDataSource.getProperty());
}
把原来的基于内存的方法给注释掉,使用这个基于zookeeper的。
这样就配置完了,以后所有基于zookeeper的path的变动,都会刷新zuul的配置。
我们搞个测试类:
public class ZookeeperConfigSender {
private static final int RETRY_TIMES = 3;
private static final int SLEEP_TIME = 1000;
public static void main(String[] args) throws Exception {
final String remoteAddress = "localhost:2181";
final String rule = "[\n"
+ " {\n"
+ " \"resource\": \"baobao_api\",\n"
+ " \"resourceMode\": 1,\n"
+ " \"controlBehavior\": 0,\n"
+ " \"count\": 1.0,\n"
+ " \"grade\": 1,\n"
+ " }\n"
+ "]";
CuratorFramework zkClient = CuratorFrameworkFactory.newClient(remoteAddress, new ExponentialBackoffRetry
(SLEEP_TIME, RETRY_TIMES));
zkClient.start();
String path = "/sentinel_zuul_rule_config/zuulConfig";
Stat stat = zkClient.checkExists().forPath(path);
if (stat == null) {
zkClient.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath(path, null);
}
zkClient.setData().forPath(path, rule.getBytes());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
zkClient.close();
}
}
这里构建个GatewayFlowRule对象的集合的json,发送给zookeeper即可。
运行一下就可以看到规则已生效。
如果你觉得拼json字符串比较麻烦,可以构建Set<GatewayFlowRule>对象,然后转成json也行。
注意!这里就不能用dashboard那个界面了,那个界面构建的对象字段和zuul要求的GatewayFlowRule对象字段不一样。
如果你也想用界面来控制,可以自己做个界面。