在Tutorial 1 里,
我们实现了一个简单的Redis服务程序,它使用分布式配置进行管理,此Redis的配置文件存储在分布式服务器 disconf-web 上。
也许有一天,我们需要更新Redis的Host和Port配置数据。由于 redis是根据配置生成的实例,因此,这种情况下,你有三种选择:
- 不使用Disconf(Tutorial 1 里第一部分的使用方法)。那么你需要 更改线上机器的配置文件 redis.properties,重启服务就可以了。
- 使用Disconf, 采用 Tutorial 1 里第二部分的使用的方案。那么你需要 更改 分布式服务器 disconf-web 上的 redis.properties 文件。 然后重启服务就可以了。和第一种方法的区别在于,不需要更改线上机器的配置文件。
- 使用Disconf,采用 Tutorial 1 里第二部分的使用的方案,并额外加上本Tutorial的方案,那么你 只需要 更改 分布式服务器 disconf-web 上的 redis .properties 文件。然后服务的配置自动生效。此过程无需要重新启动服务。
本教程就是阐述如何通过简单的配置和极简代码实现第三步的功能。
2.1. 第一步:准备工作
完成Tutorial 1 上第二部分方案里的步骤。
2.2. 第二步:修改 SimpleRedisService,支持Redis重连接
在这里,我们这个类添加了一个方法,重新生成了一个Jedis对象,代码如下:
/**
* 更改Jedis
*/
public void changeJedis() {
LOGGER.info("start to change jedis hosts to: " + jedisConfig.getHost() + " : " + jedisConfig.getPort());
jedis = JedisUtil.createJedis(jedisConfig.getHost(), jedisConfig.getPort());
LOGGER.info("change ok.");
}
之所以添加这个函数的原因是:在配置更新时,此函数要被调用,从而更改Jedis实例。
整个类的完整代码如下:
package com.example.disconf.demo.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import com.example.disconf.demo.config.JedisConfig;
import com.example.disconf.demo.utils.JedisUtil;
import redis.clients.jedis.Jedis;
/**
* 一个简单的Redis服务
*
* @author liaoqiqi
* @version 2022-6-17
*/
@Service
@Scope("singleton")
public class SimpleRedisService implements InitializingBean, DisposableBean {
protected static final Logger LOGGER = LoggerFactory.getLogger(SimpleRedisService.class);
// jedis 实例
private Jedis jedis = null;
/**
* 分布式配置
*/
@Autowired
private JedisConfig jedisConfig;
/**
* 关闭
*/
public void destroy() throws Exception {
if (jedis != null) {
jedis.disconnect();
}
}
/**
* 进行连接
*/
public void afterPropertiesSet() throws Exception {
jedis = JedisUtil.createJedis(jedisConfig.getHost(), jedisConfig.getPort());
}
/**
* 获取一个值
*
* @param key
*
* @return
*/
public String getKey(String key) {
if (jedis != null) {
return jedis.get(key);
}
return null;
}
/**
* 更改Jedis
*/
public void changeJedis() {
LOGGER.info("start to change jedis hosts to: " + jedisConfig.getHost() + " : " + jedisConfig.getPort());
jedis = JedisUtil.createJedis(jedisConfig.getHost(), jedisConfig.getPort());
LOGGER.info("change ok.");
}
}
2.3. 第三步: 撰写配置更新回调类
当配置更新时,应用程序要得到通知。因此我们要写一个回调类来响应此“通知”。完整的类如下:
package com.example.disconf.demo.service.callbacks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import com.baidu.disconf.client.common.annotations.DisconfUpdateService;
import com.baidu.disconf.client.common.update.IDisconfUpdate;
import com.example.disconf.demo.config.Coefficients;
import com.example.disconf.demo.config.JedisConfig;
import com.example.disconf.demo.service.SimpleRedisService;
/**
* 更新Redis配置时的回调函数
*
* @author liaoqiqi
* @version 2022-6-17
*/
@Service
@Scope("singleton")
@DisconfUpdateService(classes = {JedisConfig.class}, itemKeys = {Coefficients.key})
public class SimpleRedisServiceUpdateCallback implements IDisconfUpdate {
protected static final Logger LOGGER = LoggerFactory.getLogger(SimpleRedisServiceUpdateCallback.class);
@Autowired
private SimpleRedisService simpleRedisService;
/**
*
*/
public void reload() throws Exception {
simpleRedisService.changeJedis();
}
}
具体步骤是:
- 撰写此类,实现 IDisconfUpdate 接口。此类必须是JavaBean,Spring托管的,且 “scope” 都必须是singleton的。
- 添加 @DisconfUpdateService 注解,classes 值加上 JedisConfig.class ,表示当 JedisConfig.class 这个配置文件更新时,此回调类将会被调用。或者,使用 confFileKeys 也可以。
- 在函数 reload() 里调用 SimpleRedisService 的 changeJedis() 方法
回调类与配置类放在一起
如果你觉得写两个类太累,在某些场景下,则可以将回调与配置类放在一起的。
/**
* Redis配置文件
*
* @author liaoqiqi
* @version 2022-6-17
*/
@Service
@Scope("singleton")
@DisconfFile(filename = "redis.properties")
@DisconfUpdateService(classes = {JedisConfig.class})
public class JedisConfig implements IDisconfUpdate {
protected static final Logger LOGGER = LoggerFactory.getLogger(JedisConfig.class);
// 代表连接地址
private String host;
// 代表连接port
private int port;
/**
* 地址, 分布式文件配置
*
* @return
*/
@DisconfFileItem(name = "redis.host", associateField = "host")
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
/**
* 端口, 分布式文件配置
*
* @return
*/
@DisconfFileItem(name = "redis.port", associateField = "port")
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
@Override
public void reload() throws Exception {
LOGGER.info("host: " + host);
}
}
2.4. 完结
至此,支持配置更新的 分布式配置文件 的撰写就已经写完了。
当用户在 disconf-web 上更新配置时,你的服务里的Redis就会指向新的地址。
版权声明:「DDKK.COM 弟弟快看,程序员编程资料站」本站文章,版权归原作者所有
来源:https://disconf.readthedocs.io/zh_CN/latest/index.html