redis + db 实现全局配置管理 多服务单节点
数据库配置 数据,redis 做缓存 。在启动的时候将数据同步到redis 。数据库修改配置后 要不重启服务 ,要不调用接口刷新 。配置只是简单的key value ,value 中可以直接写value 或者写json串(复杂的)。集合的形式 可以 直接写json 或者 配置相同的 key 不同的value。
数据库表结构
CREATE TABLE
configuration_dictionaries
(
id
int(11) NOT NULL AUTO_INCREMENT,
key
varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT ‘配置key’,
value
varchar(800) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
describe
varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT ‘配置描述’,
creation_time
datetime DEFAULT CURRENT_TIMESTAMP COMMENT ‘创建时间’,
PRIMARY KEY (id
) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT=‘配置字典表’;
初始化缓存
@Component
public class ConfigurationDictionariesCache implements CommandLineRunner{
public static Configurations configurations = new Configurations();
private static String CONFIF_CODE = "configCode:";
public static StringRedisTemplate getRedisTemplate() {
return ApplicationContextProvider.getBeanIgnoreCase("ArticleStringRedisTemplate", StringRedisTemplate.class);
}
public static ConfigurationDictionariesMapper getConfiguration() {
return ApplicationContextProvider.getBean(ConfigurationDictionariesMapper.class);
}
// 初始化缓配置缓存
public static void initializeCache() {
Set<String> keys = getRedisTemplate().keys(CONFIF_CODE + "*");
getRedisTemplate().delete(keys);
ListOperations<String, String> operations = getRedisTemplate().opsForList();
List<ConfigurationDictionaries> configs = getConfiguration().selectAll();
for (ConfigurationDictionaries configurationDictionaries : configs) {
if (StringUtils.isEmpty(configurationDictionaries.getKey())) {
continue;
}
operations.leftPush(CONFIF_CODE + configurationDictionaries.getKey(), configurationDictionaries.getValue());
}
}
//单配置刷新
public static boolean initializeCodeCache(String key) {
List<ConfigurationDictionaries> config = getConfiguration().selectByPrimaryKeyCode(key);
getRedisTemplate().delete(CONFIF_CODE + key);
if (null != config) {
ListOperations<String, String> operations = getRedisTemplate().opsForList();
for (ConfigurationDictionaries config1 : config) {
operations.leftPush(CONFIF_CODE + config1.getKey(), config1.getValue());
}
return true;
}
return false;
}
public static boolean initializeCodeCache(String key,List<String> values) {
getRedisTemplate().delete(CONFIF_CODE + key);
if (null != values&&!values.isEmpty()) {
ListOperations<String, String> operations = getRedisTemplate().opsForList();
for (String config1 : values) {
operations.leftPush(CONFIF_CODE + key, config1);
}
return true;
}
return false;
}
public static boolean initializeCodeCache(String key,String value) {
getRedisTemplate().delete(CONFIF_CODE + key);
if (value != null&& !StringUtils.isEmpty(value)) {
ListOperations<String, String> operations = getRedisTemplate().opsForList();
operations.leftPush(CONFIF_CODE + key, value);
return true;
}
return false;
}
public static class Configurations {
public static Object get(String key) {
Long num = getRedisTemplate().opsForList().size(CONFIF_CODE + key);
if (num.equals(0L)) {
return null;
} else if (num.equals(1L)) {
return getRedisTemplate().opsForList().range(CONFIF_CODE + key, 0, num).get(0);
} else {
return getRedisTemplate().opsForList().range(CONFIF_CODE + key, 0, num);
}
}
}
@Override
public void run(String... args) throws Exception {
initializeCache();
}
}
Controller 接口提供缓存刷新
@Api(tags="缓存刷新")
@RestController
@RequestMapping("/api/configCache")
public class ConfigurationDictionariesCacheController {
@Autowired
private ConfigurationDictionariesMapper configuration;
@PostMapping("/init")
public Object init() {
ConfigurationDictionariesCache.initializeCache();
return configuration.selectAll();
}
@PostMapping("/updateKey")
public Object updateKey(@RequestParam(value = "key", required = false)String key) {
Map<String, Object> map = new HashMap<String, Object>();
boolean result= ConfigurationDictionariesCache.initializeCodeCache(key);
map.put("status", result);
map.put("body", ConfigurationDictionariesCache.configurations.get(key));
return map;
}
}
mybatis 相关代码
@Mapper
public interface ConfigurationDictionariesMapper {
List<ConfigurationDictionaries> selectAll();
List<ConfigurationDictionaries> selectByPrimaryKeyCode(String key);
void updateConfigurationList(List<ConfigurationDictionaries> configurations);
void updateConfiguration(ConfigurationDictionaries configuration);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dao.mapper.ConfigurationDictionariesMapper">
<resultMap id="BaseResultMap" type="com.dao.model.ConfigurationDictionaries">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="key" jdbcType="VARCHAR" property="key" />
<result column="value" jdbcType="VARCHAR" property="value" />
<result column="describe" jdbcType="VARCHAR" property="describe" />
<result column="creation_time" jdbcType="TIMESTAMP" property="creationTime" />
</resultMap>
<sql id="Base_Column_List">
id, `key` , `value`, `describe`, creation_time
</sql>
<select id="selectAll" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from configuration_dictionaries
</select>
<select id="selectByPrimaryKeyCode" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from configuration_dictionaries
where `key` = #{key,jdbcType=VARCHAR}
</select>
<update id="updateConfigurationList" parameterType="java.util.List">
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
update configuration_dictionaries
<set>
`value`='${item.value}'
</set>
where `key` = '${item.key}'
</foreach>
</update>
<update id="updateConfiguration" parameterType="com.dao.model.ConfigurationDictionaries">
update configuration_dictionaries set `value`='${value}' where `key` = '${key}'
</update>
</mapper>
实体类
public class ConfigurationDictionaries {
private Integer id;
private String key;
private String value;
private String describe;
private Date creationTime;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key == null ? null : key.trim();
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value == null ? null : value.trim();
}
public String getDescribe() {
return describe;
}
public void setDescribe(String describe) {
this.describe = describe == null ? null : describe.trim();
}
public Date getCreationTime() {
return creationTime;
}
public void setCreationTime(Date creationTime) {
this.creationTime = creationTime;
}
}
调用及 其他服务 访问缓存
客户端
public class ConfigurationDictionariesCache {
public static Configurations configurations = new Configurations();
private static String CONFIF_CODE = "configCode:";
public static StringRedisTemplate getRedisTemplate() {
return ApplicationContextProvider.getBean(StringRedisTemplate.class);
}
public static class Configurations {
//返回两种形式 string (单独key ) 或 list(相同的key 以list 返回)
public static Object get(String key) {
Long num = getRedisTemplate().opsForList().size(CONFIF_CODE + key);
if (num.equals(0L)) {
return null;
} else if (num.equals(1L)) {
return getRedisTemplate().opsForList().range(CONFIF_CODE + key, 0, num).get(0);
} else {
return getRedisTemplate().opsForList().range(CONFIF_CODE + key, 0, num);
}
}
}
}
获取配置数据
//json 用工具进行转换
(String)ConfigurationDictionariesCache.Configurations.get("key");
(List)ConfigurationDictionariesCache.Configurations.get("key");