需求场景:分布式项目中,每个子项目有各自的 user 数据库, 在综合管理系统中存放这所有用户信息, 为了保持综合管理系统用户的完整性,

    子系统添加用户后将用户信息以json格式保存至redis,然后发布到消息到消息通道,综合管理系统监控到子系统发布的消息前往redis

    获取出用户信息保存到自己的数据库

1)redis配置

 spring:
redis:
#数据库索引
database: 5
host: 127.0.0.1
port:
password: 123456
jedis:
pool:
#最大连接数
max-active:
#最大阻塞等待时间(负数表示没限制)
#最大空闲
max-idle:
#最小空闲
min-idle:

2)集成redis , 初始化redis组件

 package com.bigcustomer.configs;

 import com.bigcustomer.utils.redisUtil.RedisService;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; /**
* @author :CX
* @Date :Create in 2018/8/15 14:03
* @Effect :
*/ @Configuration
@EnableCaching//开启注解
public class RedisConfig extends CachingConfigurerSupport { private static Logger logger = LoggerFactory.getLogger(RedisConfig.class);
// 自定义的配置类, 存放了通道地址
@Autowired
private BaseConfig baseConfig; /**
*@参数
*@返回值
*@创建人 cx
*@创建时间
*@描述 //初始化监听器
*/
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) { RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//配置监听通道
container.addMessageListener(listenerAdapter, new PatternTopic(baseConfig.getRedisAisle()));// 通道的名字
logger.info("初始化监听成功,监听通道:【"+baseConfig.getRedisAisle()+"】");
return container;
} /**
*@参数
*@返回值
*@创建人 cx
*@创建时间
*@描述 利用反射来创建监听到消息之后的执行方法
*/
@Bean
MessageListenerAdapter listenerAdapter(RedisService receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
} // /**
// *@参数
// *@返回值
// *@创建人 cx
// *@创建时间
// *@描述 控制线程用的
// */
// @Bean
// Receiver receiver(CountDownLatch latch) {
// return new Receiver(latch);
// }
//
// @Bean
// CountDownLatch latch() {
// return new CountDownLatch(1);
// } /**
*@参数
*@返回值
*@创建人 cx
*@创建时间
*@描述 //使用默认的工厂初始化redis操作String模板
*/
@Bean
StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
/**
*@参数
*@返回值
*@创建人 cx
*@创建时间
*@描述 //使用默认的工厂初始化redis操作map模板
*/
@Bean
RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(jackson2JsonRedisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashKeySerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template; }
}

3 ) 操作string 和 map 的dao封装

 package com.bigcustomer.utils.redisUtil;

 import com.alibaba.fastjson.JSON;
import com.bigcustomer.biguser.service.BigUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component; import javax.annotation.Resource;
import java.util.Map; /**
* @author :CX
* @Date :Create in 2018/8/15 14:19
* @Effect : redisDAO封裝
*/
@Component
public class MyRedisDao { private static Logger logger = LoggerFactory.getLogger(BigUserService.class);
@Resource
private StringRedisTemplate template; @Resource
private RedisTemplate redisTemplate; //大客户信息同步到redis时保存的map的key
private final String BIG_USER_REDIS_KEY = "CM:CHANNELCUSTOMER"; /**
* @参数
* @返回值
* @创建人 cx
* @创建时间
* @描述 大客户添加成功后存到redis
*/
public boolean setMap(Map<String , Object> map) { try {
redisTemplate.opsForHash().putAll(BIG_USER_REDIS_KEY
, map);
logger.info("同步大客户信息到redis 成功!userId【" + map.get("funiqueid")+ "】");
return true;
} catch (Exception e) {
e.printStackTrace();
}
logger.info("同步大客户信息到redis 失败!userId【" + map.get("funiqueid")+ "】");
return false;
} public Object getMap(String key) { try {
Object o = redisTemplate.opsForHash().get(BIG_USER_REDIS_KEY, key);
if (null != o) {
return o;
}
} catch (Exception e) {
e.printStackTrace();
}
logger.info("获取大客户信息到失败!");
return null;
} /**
* @参数
* @返回值 存在 = true , 不纯在false
* @创建人 cx
* @创建时间
* @描述 判断是否存在 该key对应的值
*/
public boolean isNull(String key) {
return template.hasKey(key);
} /**
* @参数
* @返回值
* @创建人 cx
* @创建时间
* @描述 设置值 和 过期时间 单位秒
*/
public boolean setValue(String key, Object val, long expire) {
if (!this.isNull(key)) {
//不存在
String jsonString = JSON.toJSONString(val);
template.opsForValue().set(key, jsonString, expire);
logger.info("***************************成功在缓存中插入:" + key);
return true;
} else {
logger.info("***************************【" + key + "】已经存在缓存");
return false;
}
} /**
* @参数
* @返回值
* @创建人 cx
* @创建时间
* @描述 删除
*/
public boolean del(String key) {
return template.delete(key);
} /**
* @参数
* @返回值
* @创建人 cx
* @创建时间
* @描述 插入直接覆盖
*/
public boolean setValue(String key, Object val) {
//不存在
String jsonString = JSON.toJSONString(val);
// 去掉多余的 “
String replace = jsonString.replace("\"", "");
template.opsForValue().set(key, replace);
logger.info("***************************成功在缓存中插入:" + key);
return true;
} /**
* @参数
* @返回值
* @创建人 cx
* @创建时间
* @描述 获取对应key 的值
*/
public String getValue(String key) {
if (!this.isNull(key)) { //不存在
logger.info("***************************【" + key + "】不存在缓存");
return null;
} else {
return template.opsForValue().get(key);//根据key获取缓存中的val
}
} }

4) 消息发布和监听的服务类

 package com.bigcustomer.utils.redisUtil;

 import com.bigcustomer.configs.BaseConfig;
import huashitech.kissucomponent.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; /**
* @author :CX
* @Date :Create in 2018/8/23 10:22
* @Effect : redis 通道消息发送和监听接受
*/
@Service
public class RedisService extends BaseService { @Autowired
private StringRedisTemplate template;
@Autowired
private BaseConfig baseConfig;
@Autowired
RedisService redisService; /**
*@参数
*@返回值
*@创建人 cx
*@创建时间
*@描述 向默认通道发送消息
*/
public void setMessage( Long funiqueid) { template.convertAndSend(baseConfig.getRedisAisle(),
baseConfig.getRedisMessageName() +funiqueid);
} /**
*@参数
*@返回值
*@创建人 cx
*@创建时间
*@描述 接受监听到的消息
*/
public void receiveMessage(String message) {
logger.info("接收redis通道消息:"+message);
}
}

5) 使用

 dao.getTransactionManager().doTransaction((TransactionStatus s) -> {
//插入数据库
int insert = dao.insert(tbCmChannelcustomerModel);
// 加入缓存
HashMap<String, Object> map = new HashMap<>();
map.put(tbCmChannelcustomerModel.getFuniqueid().toString()
, JSON.toJSONString(tbCmChannelcustomerModel));
redisDao.setMap(map);
// 发布redis通知消息
redisService.setMessage(tbCmChannelcustomerModel.getFuniqueid());
});

springboot2.X 集成redis+消息发布订阅的更多相关文章

  1. 【spring boot】【redis】spring boot 集成redis的发布订阅机制

    一.简单介绍 1.redis的发布订阅功能,很简单. 消息发布者和消息订阅者互相不认得,也不关心对方有谁. 消息发布者,将消息发送给频道(channel). 然后是由 频道(channel)将消息发送 ...

  2. php实现redis消息发布订阅

    基础介绍 Pub/Sub功能(means Publish, Subscribe)即发布及订阅功能 基于事件的系统中,Pub/Sub是目前广泛使用的通信模型,它采用事件作为基本的通信机制,提供大规模系统 ...

  3. redis 实现发布订阅的功能

    redis 除了作为缓存的功能外还可以用作消息中间件的功能,这片博客主要是介绍一下 redis 整合spring 实现消息的发布和订阅功能: 1:redis依赖,依赖两个包,redis 包, spri ...

  4. springboot集成redis实现消息发布订阅模式-双通道(跨多服务器)

    基础配置参考https://blog.csdn.net/llll234/article/details/80966952 查看了基础配置那么会遇到一下几个问题: 1.实际应用中可能会订阅多个通道,而一 ...

  5. Redis 学习(三) —— 事务、消息发布订阅

    一.Redis事务 Redis 提供的事务机制与传统的数据库事务有些不同,传统数据库事务必须维护以下特性:原子性(Atomicity), 一致性(Consistency),隔离性(Isolation) ...

  6. 【springboot】【redis】springboot+redis实现发布订阅功能,实现redis的消息队列的功能

    springboot+redis实现发布订阅功能,实现redis的消息队列的功能 参考:https://www.cnblogs.com/cx987514451/p/9529611.html 思考一个问 ...

  7. redis实现消息发布/订阅

    redis实现简单的消息发布/订阅模式. 消息订阅者: package org.common.component; import org.slf4j.Logger; import org.slf4j. ...

  8. 基于Redis消息的订阅发布应用场景

    目录 基于Redis消息的订阅发布应用场景 1.应用背景 2.困境 2.1 锁表风险 2.2 实时性差 2.3 增加编程复杂性 2.4 实时效果 3.解决方案 3.1 前端传值给服务端 3.2 服务端 ...

  9. redis的发布订阅模式

    概要 redis的每个server实例都维护着一个保存服务器状态的redisServer结构 struct redisServer {     /* Pubsub */     // 字典,键为频道, ...

随机推荐

  1. MVC,MVP设计模式

    什么是MVP MVP是模型(Model).视图(View).主持人(Presenter)的缩写,分别代表项目中3个不同的模块. 模型(Model):负责处理数据的加载或者存储,比如从网络或本地数据库获 ...

  2. css系列之box-sizing

    转载自:http://zh.learnlayout.com/box-sizing.html 人们慢慢的意识到传统的盒子模型不直接,所以他们新增了一个叫做 box-sizing 的CSS属性.当你设置一 ...

  3. PHP获取文件后缀名

    PHP获取文件后缀名是PHP学习者常见的一种操作,无论是在面试过程中还是PHP新手自学中.PHP获取文件后缀名都是很普遍的需要掌握的一个知识点. 下面我们就给大家总结介绍PHP获取文件扩展名也就是后缀 ...

  4. python 全栈开发,Day80(博客系统分析,博客主页展示)

    一.博客系统分析 数据库的构建 首先,我们分析一个博客系统的功能: 一个博客可以有多个标签(多对多) 一个博客可以有多条评论(一对多) 一个博客只可以有一个类别(多对一) 接下来,我们分析关系的属性: ...

  5. 接口隔离原则(Interface Segregation Principle, ISP)

    使用多个专门的接口,而不使用单一的总接口 接口隔离有两种定义: Clients should not be forced to depend upon interfaces that they don ...

  6. POJ 3421 X-factor Chains (因式分解+排列组合)

    题意:一条整数链,要求相邻两数前一个整除后一个.给出链尾的数,求链的最大长度以及满足最大长度的不同链的数量. 类型:因式分解+排列组合 算法:因式分解的素因子个数即为链长,链中后一个数等于前一个数乘以 ...

  7. codeforces 758D Ability To Convert【DP】

    在N进制下给你一个数,要你转换成最小的十进制数; 状态转移方程:从前向后 dp[j]表示j位前数列的最小十进制数 dp[j]=min(dp[j],dp[i]*n+x) 程序: #include < ...

  8. zjoi 小星星

    题解: dp很容易想 f[i][j][s]表示匹配到了i点 对应点为j点,状态为s 那么这样的时间复杂度为(3^n*n^2) 然后会发现这其实可以转化为可以重复利用元素的子集卷积 http://www ...

  9. optional

    public class Test { public static void main(String[] args) { People people = new People(); Optional& ...

  10. KNN分类算法实现手写数字识别

    需求: 利用一个手写数字“先验数据”集,使用knn算法来实现对手写数字的自动识别: 先验数据(训练数据)集: ♦数据维度比较大,样本数比较多. ♦ 数据集包括数字0-9的手写体. ♦每个数字大约有20 ...