集羣搭建
namesrv 之間無狀態的 每個broker都要向所有的namesrv 上報自己的狀態
broker 分爲主從 爲0 是主節點 一個主節點 可以有多個從節點
同步消息
同步等待消息已經發出
/**
* 發送同步消息
*/
public class SyncProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("group1");
producer.setNamesrvAddr(Common.WIN.getIpAddress());
producer.start();
for (int i = 0; i < 10; i++) {
Message msg = new Message("springboot-mq", "Tag1", ("Hello World" + i).getBytes());
SendResult result = producer.send(msg);
SendStatus status = result.getSendStatus();
System.out.println("發送結果:" + result);
TimeUnit.SECONDS.sleep(1);
}
producer.shutdown();
}
}
異步消息
設置回調函數 來監聽發送的情況
/**
* 發送異步消息
*
*/
public class AsyncProducer {
public static void main(String[] args) throws Exception {
//1.創建消息生產者producer,並制定生產者組名
DefaultMQProducer producer = new DefaultMQProducer("group1");
//2.指定Nameserver地址
producer.setNamesrvAddr(Common.WIN.getIpAddress());
//3.啓動producer
producer.start();
for (int i = 0; i < 10; i++) {
Message msg = new Message("base", "Tag2", ("Hello World" + i).getBytes());
producer.send(msg, new SendCallback() {
public void onSuccess(SendResult sendResult) {
System.out.println("發送結果:" + sendResult);
}
public void onException(Throwable e) {
System.out.println("發送異常:" + e);
}
});
TimeUnit.SECONDS.sleep(1);
}
//6.關閉生產者producer
producer.shutdown();
}
}
發送單向消息
單向消息 用在發送結果不是很重要的業務場景
/**
* 發送單向消息
*/
public class OneWayProducer {
public static void main(String[] args) throws Exception, MQBrokerException {
DefaultMQProducer producer = new DefaultMQProducer("group1");
producer.setNamesrvAddr(Common.WIN.getIpAddress());
producer.start();
for (int i = 0; i < 3; i++) {
Message msg = new Message("base", "Tag3", ("Hello World,單向消息" + i).getBytes());
producer.sendOneway(msg);
TimeUnit.SECONDS.sleep(5);
}
producer.shutdown();
}
}
發送順序消息
保證順序就是 將同一個業務產生的消息 發送至同一個消息隊列 發送的時候可以選擇消息隊列 取餘或哈希
發送端
public class Producer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("group1");
producer.setNamesrvAddr(Common.WIN.getIpAddress());
producer.start();
//構建消息集合
List<OrderStep> orderSteps = OrderStep.buildOrders();
//發送消息
for (int i = 0; i < orderSteps.size(); i++) {
String body = orderSteps.get(i) + "";
Message message = new Message("OrderTopic", "Order", "i" + i, body.getBytes());
/**
* 參數一:消息對象
* 參數二:消息隊列的選擇器
* 參數三:選擇隊列的業務標識(訂單ID)
*/
SendResult sendResult = producer.send(message, new MessageQueueSelector() {
/**
* @param mqs:隊列集合
* @param msg:消息對象
* @param arg:業務標識的參數
* @return
*/
@Override
public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
long orderId = (long) arg;
long index = orderId % mqs.size();
return mqs.get((int) index);
}
}, orderSteps.get(i).getOrderId());
System.out.println("發送結果:" + sendResult);
}
producer.shutdown();
}
}
接收端
在接收端 註冊的是 順序消費監聽器
public class Consumer {
public static void main(String[] args) throws MQClientException {
//1.創建消費者Consumer,制定消費者組名
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");
//2.指定Nameserver地址
consumer.setNamesrvAddr(Common.WIN.getIpAddress());
//3.訂閱主題Topic和Tag
consumer.subscribe("OrderTopic", "*");
//4.註冊消息監聽器
consumer.registerMessageListener(new MessageListenerOrderly() {
@Override
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
for (MessageExt msg : msgs) {
System.out.println("線程名稱:【" + Thread.currentThread().getName() + "】:" + new String(msg.getBody()));
}
return ConsumeOrderlyStatus.SUCCESS;
}
});
//5.啓動消費者
consumer.start();
System.out.println("消費者啓動");
}
}
發送事務消息
producer 發送消息之後 屬於半消息 短暫時間內 對消費者不可見
producer 可以對消息進行提交和回滾
mqservev會對消息進行回查 來檢測消息的狀態
發送端 需要註冊 事務監聽器
public class Producer {
public static void main(String[] args) throws Exception {
//1.創建消息生產者producer,並制定生產者組名
TransactionMQProducer producer = new TransactionMQProducer("group5");
//2.指定Nameserver地址
producer.setNamesrvAddr(Common.WIN.getIpAddress());
//添加事務監聽器
producer.setTransactionListener(new TransactionListener() {
/**
* 在該方法中執行本地事務
* @param msg
* @param arg
* @return
*/
@Override
public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
if (StringUtils.equals("TAGA", msg.getTags())) {
return LocalTransactionState.COMMIT_MESSAGE;
} else if (StringUtils.equals("TAGB", msg.getTags())) {
return LocalTransactionState.ROLLBACK_MESSAGE;
} else if (StringUtils.equals("TAGC", msg.getTags())) {
return LocalTransactionState.UNKNOW;
}
return LocalTransactionState.UNKNOW;
}
/**
* 該方法時MQ進行消息事務狀態回查
* @param msg
* @return
*/
@Override
public LocalTransactionState checkLocalTransaction(MessageExt msg) {
System.out.println("消息的Tag:" + msg.getTags());
return LocalTransactionState.COMMIT_MESSAGE;
}
});
//3.啓動producer
producer.start();
String[] tags = {"TAGA", "TAGB", "TAGC"};
for (int i = 0; i < 3; i++) {
//4.創建消息對象,指定主題Topic、Tag和消息體
/**
* 參數一:消息主題Topic
* 參數二:消息Tag
* 參數三:消息內容
*/
Message msg = new Message("TransactionTopic", tags[i], ("Hello World" + i).getBytes());
//5.發送消息
SendResult result = producer.sendMessageInTransaction(msg, null);
//發送狀態
SendStatus status = result.getSendStatus();
System.out.println("發送結果:" + result);
//線程睡1秒
TimeUnit.SECONDS.sleep(2);
}
//6.關閉生產者producer
//producer.shutdown();
}
}
消費端
public class Consumer {
public static void main(String[] args) throws Exception {
//1.創建消費者Consumer,制定消費者組名
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");
//2.指定Nameserver地址
consumer.setNamesrvAddr(Common.WIN.getIpAddress());
//3.訂閱主題Topic和Tag
consumer.subscribe("TransactionTopic", "*");
//4.設置回調函數,處理消息
consumer.registerMessageListener(new MessageListenerConcurrently() {
//接受消息內容
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
for (MessageExt msg : msgs) {
System.out.println("consumeThread=" + Thread.currentThread().getName() + "," + new String(msg.getBody()));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
//5.啓動消費者consumer
consumer.start();
System.out.println("生產者啓動");
}
}
與Spring Boot 集成
01 引入jar包
<properties>
<rocketmq-spring-boot-starter-version>2.0.3</rocketmq-spring-boot-starter-version>
</properties>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${rocketmq-spring-boot-starter-version}</version>
</dependency>
02 消費者
其中 集成的RocketMQLister T 是發送的消息類型
@Component
@RocketMQMessageListener(topic = "springboot-mq",consumerGroup = "springboot-mq-consumer-1")
public class Consumer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
log.info("Receive message:"+message);
}
}