DLX(死信队列)+TTL(消息生存时间)
1.mq配置(rabbitConfig)
@Configuration
public class RabbitConfig {
@Bean(RabbitMqConstant.INM_MARKET_EXCHANGE)
public DirectExchange directExchange(){
return new DirectExchange(RabbitMqConstant.INM_MARKET_EXCHANGE,true,false);
}
/**
* 待启动活动延迟队列和死信队列 (死信队列和普通队列用了同一个交换机,如果不是同一个,修改“x-dead-letter-exchange”的值)
*/
@Bean(RabbitMqConstant.MARKET_DELAY_ACTIVATION_ACTIVITY_QUEUE_NAME)
public Queue delayActivationQueue(){
Map<String, Object> args = new HashMap<>(3);
args.put("x-dead-letter-exchange", RabbitMqConstant.INM_MARKET_EXCHANGE);
args.put("x-dead-letter-routing-key", RabbitMqConstant.MARKET_DELAY_ACTIVATION_ACTIVITY_DL_QUEUE_ROUTING_KEY);
return new Queue(RabbitMqConstant.MARKET_DELAY_ACTIVATION_ACTIVITY_QUEUE_NAME,true,false,false,args);
}
@Bean(RabbitMqConstant.MARKET_DELAY_ACTIVATION_ACTIVITY_DL_QUEUE_NAME)
public Queue delayActivationSLQueue(){
return new Queue(RabbitMqConstant.MARKET_DELAY_ACTIVATION_ACTIVITY_DL_QUEUE_NAME,true);
}
@Bean
public Binding delayActivationBinding(@Qualifier(RabbitMqConstant.MARKET_DELAY_ACTIVATION_ACTIVITY_QUEUE_NAME) Queue queue,
@Qualifier(RabbitMqConstant.INM_MARKET_EXCHANGE) DirectExchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(RabbitMqConstant.MARKET_DELAY_ACTIVATION_ACTIVITY_QUEUE_ROUTING_KEY);
}
@Bean
public Binding delayActivationSLBinding(@Qualifier(RabbitMqConstant.MARKET_DELAY_ACTIVATION_ACTIVITY_DL_QUEUE_NAME) Queue queue,
@Qualifier(RabbitMqConstant.INM_MARKET_EXCHANGE) DirectExchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(RabbitMqConstant.MARKET_DELAY_ACTIVATION_ACTIVITY_DL_QUEUE_ROUTING_KEY);
}
2.生产者
public void sentMarketActivationActivityMsg(MarketActivityMQDTO activityMQDTO) {
log.info("当前时间:{},activationActivity:{}", new Date().toString(), JSON.toJSONString(activityMQDTO));
try {
String str = objectMapper.writeValueAsString(activityMQDTO);
Message message = MessageBuilder
.withBody(str.getBytes())
.setContentType(MessageProperties.CONTENT_TYPE_JSON)
.setMessageId(StringUtil.getUUid())
.build();
Long timeInterval = getTimeInterval(activityMQDTO, 1);
BizException.isTrue(timeInterval < 0, "活动开始小于当前时间");
rabbitTemplate.convertAndSend(RabbitMqConstant.INM_MARKET_EXCHANGE, RabbitMqConstant.MARKET_DELAY_ACTIVATION_ACTIVITY_QUEUE_ROUTING_KEY, message, a -> {
log.info("Activation---timeInterval:" + timeInterval);
a.getMessageProperties().setExpiration(timeInterval + "");
return a;
});
} catch (JsonProcessingException e) {
log.info("发送活动消息到延迟队列失败:{}", JSON.toJSONString(activityMQDTO));
e.printStackTrace();
}
}
3.消费者
@RabbitListener(queues = RabbitMqConstant.MARKET_DELAY_ACTIVATION_ACTIVITY_DL_QUEUE_NAME)
public void receiveMarketActivation(Message message, Channel channel) {
long tag = message.getMessageProperties().getDeliveryTag();
String messageId = message.getMessageProperties().getMessageId();
try {
log.info("receiveMarketActivation.tag:{},messageId:{}", tag, messageId);
MarketActivityMQDTO activityMQDTO = objectMapper.readValue(message.getBody(), MarketActivityMQDTO.class);
log.info("当前时间:{},activation-死信队列收到消息:{}", new Date().toString(), JSON.toJSONString(activityMQDTO));
// if (activityMQDTO.getActivityType() == Constant.ACTIVITY_TYPE_ZFYLHD) {
// MarketPayPolitelyActivity payPolitelyActivity = marketPayActivityService.lambdaQuery().eq(MarketPayPolitelyActivity::getId, activityMQDTO.getActivityId()).one();
// if (payPolitelyActivity.getActivityStatus() == Constant.ACTIVITY_STATUS_WKS && DateUtil.getDifferMillisecond(payPolitelyActivity.getStartTime(), new Date()) >= 0) {
// payPolitelyActivity.setActivityStatus(Constant.ACTIVITY_STATUS_JXZ);
// }
// payPolitelyActivity.setModifyTime(new Date());
// marketPayActivityService.updateById(payPolitelyActivity);
// }
channel.basicAck(tag, false);
// rabbitMqSent.sentMarketEndActivityMsg(activityMQDTO);
} catch (Exception e) {
log.error(e.getMessage());
try {
channel.basicReject(tag, false);
} catch (IOException ex) {
log.error(e.getMessage());
}
throw new BizException("活动激活失败");
}
log.info("receiveMarketActivation------------------------end");
}
rabbitmq_delayed_message_exchange插件实现延迟队列
1.mq配置
使用插件时,注意配置交换机时使用CustomExchange ,Type必须为x-delayed-message,并且添加参数x-delayed-type为direct,如:
在生产者中设置过期时间时,需要Header的属性x-delay,如:
@Configuration
public class RabbitConfig {
/**
* 激活活动
*
* @return
*/
@Bean(RabbitMqConstant.INM_MARKET_ACTIVATION_EXCHANGE)
public CustomExchange activationExchange() {
Map<String, Object> args = new HashMap<>(3);
args.put("x-delayed-type", "direct");
return new CustomExchange(RabbitMqConstant.INM_MARKET_ACTIVATION_EXCHANGE, "x-delayed-message", true, false, args);
}
@Bean(RabbitMqConstant.MARKET_PLUGIN_ACTIVATION_ACTIVITY_QUEUE_NAME)
public Queue pluginActivationQueue() {
return new Queue(RabbitMqConstant.MARKET_PLUGIN_ACTIVATION_ACTIVITY_QUEUE_NAME, true);
}
@Bean
public Binding delayActivationBinding(@Qualifier(RabbitMqConstant.MARKET_PLUGIN_ACTIVATION_ACTIVITY_QUEUE_NAME) Queue queue,
@Qualifier(RabbitMqConstant.INM_MARKET_ACTIVATION_EXCHANGE) CustomExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(RabbitMqConstant.MARKET_PLUGIN_ACTIVATION_ACTIVITY_QUEUE_ROUTING_KEY).noargs();
}
}
2.生产者
public void sentMarketActivationActivityMsg(MarketActivityMQDTO activityMQDTO) {
log.info("当前时间:{},activationActivity:{}", new Date().toString(), JSON.toJSONString(activityMQDTO));
try {
String str = objectMapper.writeValueAsString(activityMQDTO);
Message message = MessageBuilder
.withBody(str.getBytes())
.setContentType(MessageProperties.CONTENT_TYPE_JSON)
.setMessageId(StringUtil.getUUid())
.build();
Long timeInterval = getTimeInterval(activityMQDTO, 1);
BizException.isTrue(timeInterval < 0, "活动开始小于当前时间");
rabbitTemplate.convertAndSend(RabbitMqConstant.INM_MARKET_ACTIVATION_EXCHANGE, RabbitMqConstant.MARKET_PLUGIN_ACTIVATION_ACTIVITY_QUEUE_ROUTING_KEY, message, a -> {
log.info("Activation---timeInterval:" + timeInterval);
a.getMessageProperties().setHeader("x-delay",timeInterval);
return a;
});
} catch (JsonProcessingException e) {
log.info("发送活动消息到延迟队列失败:{}", JSON.toJSONString(activityMQDTO));
e.printStackTrace();
}
}
3.消费者
@RabbitListener(queues = RabbitMqConstant.MARKET_PLUGIN_ACTIVATION_ACTIVITY_QUEUE_NAME)
public void receiveMarketActivation(Message message, Channel channel) {
long tag = message.getMessageProperties().getDeliveryTag();
String messageId = message.getMessageProperties().getMessageId();
try {
log.info("receiveMarketActivation.tag:{},messageId:{}", tag, messageId);
MarketActivityMQDTO activityMQDTO = objectMapper.readValue(message.getBody(), MarketActivityMQDTO.class);
log.info("当前时间:{},activation-队列收到消息:{}", new Date().toString(), JSON.toJSONString(activityMQDTO));
// if (activityMQDTO.getActivityType() == Constant.ACTIVITY_TYPE_ZFYLHD) {
// MarketPayPolitelyActivity payPolitelyActivity = marketPayActivityService.lambdaQuery().eq(MarketPayPolitelyActivity::getId, activityMQDTO.getActivityId()).one();
// if (payPolitelyActivity.getActivityStatus() == Constant.ACTIVITY_STATUS_WKS && DateUtil.getDifferMillisecond(payPolitelyActivity.getStartTime(), new Date()) >= 0) {
// payPolitelyActivity.setActivityStatus(Constant.ACTIVITY_STATUS_JXZ);
// }
// payPolitelyActivity.setModifyTime(new Date());
// marketPayActivityService.updateById(payPolitelyActivity);
// }
channel.basicAck(tag, false);
// rabbitMqSent.sentMarketEndActivityMsg(activityMQDTO);
} catch (Exception e) {
log.error(e.getMessage());
try {
channel.basicReject(tag, false);
} catch (IOException ex) {
log.error(e.getMessage());
}
throw new BizException("活动激活失败");
}
log.info("receiveMarketActivation------------------------end");
}