Redis提供有【pub sub】功能,即我们常说的发布和订阅
Redis的pub sub功能相较于常见的RabbitMQ等消息中间件还是有一些差异,在使用前需要进行甄别,确认是否适用当前项目,毕竟技术选型脱离现实是耍流氓。
-
订阅方: 订阅某个channel后,当有消息发布至channel中时,订阅方会接收到推送而来的消息。(订阅时,channel名可以是明确的,也可以是通配的方式)
-
发布方: 向指定的channel发布一条message。
关于【pub sub】功能,Redis共提供了六个命令:
- PUBLISH:发布消息
- SUBSCRIBE:订阅指定channel
- PSUBSCRIBE:通配方式订阅channel
- UNSUBSCRIBE:取消订阅指定channel
- PUNSUBSCRIBE:通配方式取消订阅channel
- PUBSUB:查看订阅与发布状态信息
Springboot项目使用Redis pub sub功能
网上有很多这方面的文章,这里就不贴了,使用难度不大。
注意点
由于服务基本都是多实例部署,当实例中订阅了某个channel时,也就意味着多个实例都订阅了同一个channel,于是就会导致同一个消息会被多个实例同时消费,产生了重复处理的情况。
此时不管是做订阅方的幂等,还是分布式锁,还是配置文件增加开关控制,都会增加开发和运维的复杂度,同时增加很大不确定性。
这时候Redis其实还有一种变相的替代方案:Redis list,利用PUSH POP方式来实现队列。
- 生产方使用lpush命令,向指定list中左侧增加一个元素。
- 消费方写一个死循环,使用brpop命令,从指定list中右侧获取一个元素
这样等于使用了一个有序的list方式,实现一个先进先出的队列。
对应spring-data-redis的方法:
- redisTemplate.opsForList().leftPush(key, msg);
- redisTemplate.opsForList().rightPop(key, timeout, unit);
@Component
@Slf4j
public class RedisPublisherDemo {
@Autowired
private StringRedisTemplate redisTemplate;
public void redisListLeftPush(String key, String msg) {
redisTemplate.opsForList().leftPush(key, msg);
}
}
@Component