Redis实现参数的集中式管理
来源:互联网 发布:金融行业数据分析软件 编辑:程序博客网 时间:2024/05/01 13:17
发布订阅功能,并且Redis本身提供了缓存和持久化的功能,本文将介绍通过Redis实现简单的参数集中式管理,一起来看看吧,希望对大家学习redis有所帮助。
Maven引入
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.4.0</version>
</dependency>
目标
1.可以同时配置监听多个节点如/app1,/app2;
2.希望只需要配置如/app1,就能够监听其子节点如/app1/modual1以及子节点的子节点如/app1/modual1/xxx/…;
3.服务器启动能获取当前指定父节点下的所有子节点数据;
4.在添加节点或者在更新节点数据的时候能够动态通知,这样代码中就能够实时获取最新的数据;
5.spring配置中可以从Zookeeper中读取参数进行初始化。
虽然在实现的方式上有点区别,但是最终达成的目标是一致的,同样列出了这5条目标
实现
RedisWatcher主要用来和Redis进行连接,然后对监听的节点进行初始化,模糊订阅需要监听的节点,最后接受数据的变更,更新本地数据,存储数据等。
1.同时配置监听多个节点
提供一个字符串数组给用户用来添加需要监听的节点:
private String[] keyPatterns;
2.能够监听其子节点以及子节点的子节点
使用Redis提供的psubscribe命令,订阅一个或多个符合给定模式的频道,提供了模糊订阅的功能
private void watcherPaths() {
new Thread(new Runnable() {
@Override
public void run() {
jedis.psubscribe(new JedisPubSub() {
@Override
public void onMessage(String channel, String message) {
try {
keyValueMap.put(channel, message);
LOGGER.info("key = " + channel + ",value = " + message);
} catch (Exception e) {
LOGGER.error("onMessage error", e);
}
}
@Override
public void onPMessage(String arg0, String arg1, String arg2) {
System.out.println("onPMessage=>" + arg0 + "=" + arg1 + "="
+ arg2);
}
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
LOGGER.info("onPSubscribe=>" + pattern + "=" + subscribedChannels);
}
@Override
public void onPUnsubscribe(String arg0, int arg1) {
}
@Override
public void onSubscribe(String arg0, int arg1) {
}
@Override
public void onUnsubscribe(String arg0, int arg1) {
}
}, getSubKeyPatterns());
}
}).start();
}
提供了使用匹配符*的模糊匹配功能,组装带*号的匹配字符串
/** * 获取订阅的模糊channel * * @return */
private String[] getSubKeyPatterns() {
String[] subKeyPatterns = new String[keyPatterns.length];
for (int i = 0; i < keyPatterns.length; i++) {
subKeyPatterns[i] = keyPatterns[i] + "*";
}
return subKeyPatterns;
}
3.服务器启动初始化节点数据
通过使用keys命令来获取匹配节点的数据(keys命令可能引发性能问题,根据实际情况使用)
private void initKeyValues() {
for (String keyPattern : keyPatterns) {
Setkeys = jedis.keys(keyPattern + "*");
for (String key : keys) {
String value = jedis.get(key);
keyValueMap.put(key, value);
LOGGER.info("init key = " + key + ",value = " + value);
}
}
}
4.监听节点数据的变更
目标2中通过psubscribe命令,使用模糊订阅来监听数据的变更,onMessage用来接受变更的数据
5.spring配置中可以从Redis中读取参数进行初始化
public class RedisPropPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
private RedisWatcher rediswatcher;
@Override
protected Properties mergeProperties() throws IOException {
return loadPropFromRedis(super.mergeProperties());
}
/**
* 从Redis中加载配置的常量
*
* @param result
* @return
*/
private Properties loadPropFromRedis(Properties result) {
rediswatcher.watcherKeys();
rediswatcher.fillProperties(result);
return result;
}
}
通过以上的处理,可以使用如下简单的配置来达到目标:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xmlns:aop="http://www.springframework.org/schema/aop";
xmlns:tx="http://www.springframework.org/schema/tx";
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">;
<bean id="rediswatcher" class="zh.maven.DynamicConf.redis.RedisWatcher">
<property name="keyPatterns" value="/a2,/a3" />
</bean>
<bean id="propertyConfigurer" class="zh.maven.DynamicConf.redis.RedisPropPlaceholderConfigurer">
<property name="rediswatcher" ref="rediswatcher"></property>
</bean>
<bean id="person" class="zh.maven.DynamicConf.Person">
<property name="name">
<value>${/a2/m1}</value>
</property>
<property name="address">
<value>${/a3/m1/v2}</value>
</property>
<property name="company">
<value>${/a3/m1/v2/t2}</value>
</property>
</bean>
</beans>
测试
1.启动Redis服务器
redis-server.exe
2.启动Redis客户端进行初始化数据
redis-cli.exe
redis 127.0.0.1:6379> set /a2/m1 zhaohui
OK
redis 127.0.0.1:6379> set /a3/m1/v2 nanjing
OK
redis 127.0.0.1:6379> set /a3/m1/v2/t2 codingo
OK
3.启动Main类
public class Main {
public static void main(String[] args) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "spring-config.xml" });
Person person = (Person) context.getBean("person");
System.out.println(person.toString());
}
}
4.启动RedisPublish
定时发布数据,同时查看集群节点的Main类日志输出
public class RedisPublish {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
int i = 0;
while (true) {
jedis.publish("/a2/b4/c1" + i, "message_" + System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
}
}
日志输出如下:
2017-08-30 10:44:00 - init key = /a2/m1,value = zhaohui
2017-08-30 10:44:00 - init key = /a3/m1/v2,value = nanjing
2017-08-30 10:44:00 - init key = /a3/m1/v2/t2,value = codingo
2017-08-30 10:44:00 - onPSubscribe=>/a2*=1
2017-08-30 10:44:00 - onPSubscribe=>/a3*=2
2017-08-30 10:44:00 - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@4bad4a49: defining beans [rediswatcher,propertyConfigurer,person]; root of factory hierarchy
name = zhaohui,address = nanjing,company = codingo
onPMessage=>/a2*=/a2/b4/c10=message_1504061045414
onPMessage=>/a2*=/a2/b4/c11=message_1504061047458
onPMessage=>/a2*=/a2/b4/c12=message_1504061049458
onPMessage=>/a2*=/a2/b4/c13=message_1504061051458
来源: Coding狗
- Redis实现参数的集中式管理
- Zookeeper实现参数的集中式管理
- shiro安全框架扩展教程--如何扩展实现集中式session管理(redis,memcached等)
- Redis 实现Tomcat7集群扩展,session集中管理
- 实现多台linux的集中管理
- 【Python】使用代码对redis的key进行集中管理
- sna集中式session管理方案实现
- SpringBoot初始教程之Redis集中式Session管理(四)
- SpringBoot初始教程之Redis集中式Session管理(四)
- Spring Boot项目利用Redis实现集中式缓存
- 实现现代化邮政的集中管理与监控
- Redis服务的集中监控
- 意尔康:连锁专卖店如何实现集中式管理
- 接下来会普及流行能实现《集中授权集中管理,分级授权逐级管理》的标准化权限系统
- 接下来会普及流行能实现《集中授权集中管理,分级授权逐级管理》的标准化权限系统
- 数据集中参数的设置
- HDFS集中式的缓存管理原理与代码剖析
- HDFS集中式的缓存管理原理与代码剖析
- HDU 2159 FATE【二维背包+完全背包】
- 注销手机号,存在重大安全问题
- JS基础学习day1
- java按值传递(2)两整数交换
- NSNotificationCenter
- Redis实现参数的集中式管理
- LintCode:M-两个链表的交叉
- 关于操作 Python 列表,Top10最常见问答
- mybatis的选择查询,模糊查询
- 树莓派3.5寸屏幕和hdmi显示切换的方法
- STM32-modbus rtu 之主机程序
- Linux运维学习之路(5)Linux用户管理
- Fragment嵌套Fragment, TabLayout + ViewPager实现页面切换滑动
- java 时间类SimpleDateFormat,Date