我第一次接触到这种类似于mq的消息队列的redis的用法(我是菜鸡开发)
对于绝大多数场景下redis能够实现更多的用处,除了作为缓存或者保护数据库提升速度之外,合理的用法让他代替mq的消息队列,如果你想节约学习成本,或者懒懒的当一个码农-->开始吧
按照我公司的大牛来说,这种写法比mq更轻便,mq是比较重型的写法,如果项目中没有mq的话会比较适用于这种写法,无需开荒mq用法
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener
像我们项目中直接继承一个类然后Alt+Enter直接实现父类方法就变成了类似于mq的交换机监听机制
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); }
对于应用来说,上述方法不用在意,重写onMessage这个方法即可
在onMessage方法中,
@Override public void onMessage(Message message, byte[] pattern) { if (expiredKey.startsWith(RedisKey.DEDUCTION_SHOPACCOUNT)){ String orderId_price = expiredKey.substring(expiredKey.lastIndexOf(":") + 1); String orderId = orderId_price.split("&")[0]; String price = orderId_price.split("&")[1]; if (!RedisUtil.tryLock("DEDUCTION_SHOPACCOUNT_time" +orderId, 3)) { throw new HzsxBizException("999999", "防止销毁2次监听"+orderId); } log.info("用户订单信息更新"+orderId); UserOrders one = userOrdersDao.getOne(Wrappers.<UserOrders>lambdaQuery().eq(UserOrders::getOrderId, orderId)); if (StrUtil.isNotEmpty(price)){ one.setOrderPrice(new BigDecimal(price)); userOrdersDao.updateById(one); } return; } }
像上面一样整上几个if,运用一些切割字符串的方法,拿到想要的信息,如果你想要监听多个消息,或者实现延时队列,也不用装上延时队列的插件,也不用重新学习mq,只需要设置redis消息的过期时间后再这里监听过期的key就可以了
咱们要注意的是,为了防止对一个消息二次重复监听,特别的分布式服务,使用setNx或者tryLock是很有必要的,更需要注意的是执行完匹配后,一定要return掉,不然会继续向下执行无用代码,降低效率或者key设置相同的情况下出先逻辑错误
很菜很菜的一个程序员
ps:记得cv上另一个bean
@Configuration public class RedisListenerConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); return container; } }