一、ActiveMQ工作模式
点对点
点对点模型(基于队列 Point to Point,PTP) 每个消息只能有一个消费者。消息的生产者和消费者之间没有时间上的 相关性.可以有多个发送者,但只能被一个消费者消费。 一个消息只能被一个接受者接受一次 生产者把消息发送到队列中(Queue),接受者无需订阅,当接受者未接受到消息时就会处于阻塞状态
发布者/订阅者模型
(基于主题的Publish/Subscribe,pub/sub) 每个消息可以有多个消费者。 生产者和消费者之间有时间上的相关性。订阅一个主题的消费者只能消 费自它订阅之后发布的消息. 允许多个接受者,类似于广播的方式 生产者将消息发送到主题上(Topic) 接受者必须先订阅 注:持久化订阅者:特殊的消费者,告诉主题,我一直订阅着,即使网络断开,消息服务器也记住所有持久化订阅者,如果有新消息,也会知道必定有人回来消费
二、使用步骤
1.生产者
代码如下(示例):
import org.springframework.jms.core.JmsTemplate;
import java.util.concurrent.TimeUnit;
public class Receiver {
@Autowired
private JmsTemplate jmsTemplate;
public void Sender(Order order) {
//时间
long retryTime = 1000L;
MqOrder mqOrder = MqOrder.builder().orderId(order.getId()).failRetryNum(1).build();
//重试订单
log.info("下单mq重试次数:1,重试时间 {}", TimeUnit.SECONDS.toMillis(retryTime));
//MqCommonConstant.TRAVEL_ZYB_FAIL_RETRY_ORDER 点对点接收的目的地
jmsTemplate.convertAndSend(MqCommonConstant.TRAVEL_ZYB_FAIL_RETRY_ORDER, JsonUtils.toJson(mqOrder),
//秒转毫秒
new ScheduleMessagePostProcessor(TimeUnit.SECONDS.toMillis(retryTime)));
}
}
2.消费者
代码如下(示例):
import org.springframework.jms.annotation.JmsListener;
@Slf4j
@Component
public class Receiver{
@JmsListener(destination = MqCommonConstant.TRAVEL_ZYB_FAIL_RETRY_ORDER)
public void orderMq(String recOrderMessage, Session session) {
try {
session.commit();
} catch (JMSException e) {
log.error(e.getMessage(), e);
}
log.info("接收到的消息OrderMqListener {}", recOrderMessage);
MqOrder recOrder = JsonUtils.fromJson(recOrderMessage, MqOrder.class);
Order order = orderMapper.selectById(recOrder.getOrderId());
log.error("需要的数据", order);
//业务处理
}
}
3MessagePostProcessor 信息发布处理器
代码如下(示例):
import org.apache.activemq.ScheduledMessage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jms.core.MessagePostProcessor;
import javax.jms.JMSException;
import javax.jms.Message;
public class ScheduleMessagePostProcessor implements MessagePostProcessor {
private long delay = 0L;
private String corn = null;
public ScheduleMessagePostProcessor(long delay) {
this.delay = delay;
}
public ScheduleMessagePostProcessor(String cron) {
this.corn = cron;
}
@Override
public Message postProcessMessage(Message message) throws JMSException {
if (delay > 0) {
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
}
if (!StringUtils.isEmpty(corn)) {
message.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_CRON, corn);
}
return message;
}
}