现有项目需要做一个长连接通讯,我打算采用netty+通讯队列实现,
通讯队列最初打算用rabbitMQ或者kafaka,但是考虑到实施的同事的项目部署的问题,就该为现有的redis了,采用的是redis队列
@Component
public class RedisClient {
private static Logger logger = LoggerFactory.getLogger(RedisClient.class);
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
/** ---------------------------------- redis消息队列 ---------------------------------- */
/**
* 存值
* @param key 键
* @param value 值
* @return
*/
public boolean lpush(String key, Object value) {
try {
redisTemplate.opsForList().leftPush(key, value);
return true;
} catch (Exception e) {
logger.error("e:",e);
return false;
}
}
/**
* 取值 - <rpop:非阻塞式>
* @param key 键
* @return
*/
public Object rpop(String key) {
try {
return redisTemplate.opsForList().rightPop(key);
} catch (Exception e) {
logger.error("e:",e);
return null;
}
}
/**
* 取值 - <brpop:阻塞式> - 推荐使用
* @param key 键
* @param timeout 超时时间
* @param timeUnit 给定单元粒度的时间段
* TimeUnit.DAYS //天
* TimeUnit.HOURS //小时
* TimeUnit.MINUTES //分钟
* TimeUnit.SECONDS //秒
* TimeUnit.MILLISECONDS //毫秒
* @return
*/
public Object brpop(String key, long timeout, TimeUnit timeUnit) {
try {
return redisTemplate.opsForList().rightPop(key, timeout, TimeUnit.SECONDS);
} catch (Exception e) {
logger.error("e:",e);
return null;
}
}
/**
* 查看值
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public List<Object> lrange(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
logger.error("e:",e);
return null;
}
}
启动两个线程,一个生产者,一个消费者(消费者轮询调用取数据的方法和java 队列pop方法一样,获取值并移除
也可以使用redis的发布和订阅模式:
参考地址: https://blog.csdn.net/u014046563/article/details/80907124
https://www.cnblogs.com/powerwu/p/11505481.html
发布和订阅模式,不便于动态扩展,部署比较繁琐,我现在的公司做传统业务,为了方便实施所以采用的是队列,集群部署将所有的节点信息保存再注册中心,注册的中心可以自己实现,可以用redis也可以用zk。
来源:oschina
链接:https://my.oschina.net/u/3971821/blog/4352376