最近項目有塊業務要用mq去給其他項目發送消息,由於沒有權限直接登錄阿里雲mq的主頁控制檯,所以就先本地搭建了一個rocketmq,大體上基本一樣的。
由於搭建本地mq的時候生產者和消費者都是在本地,所以就把服務器做到了其他機器上(部署就不說了,網上有好多)
服務器開好,創建好topic,就可以搭建demo去測了。
如圖,用springboot項目整合了,發現阿里雲mq只需要ons-client-1.8.0.Final.jar這個包,日誌包是共需,下圖所示的包幾乎全是rocketmq的包
消費者代碼如下(機器地址這裏我改成了本地的,實際上用的是其他電腦的)
public class TestM {
public static void main(String[] args) throws InterruptedException, MQClientException {
// 實例化 consumer,指定 consumer 組名
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("defaultConsumer");
// 指定 name server
consumer.setNamesrvAddr("127.0.0.1:9876");
// 訂閱1個或多個topic
consumer.subscribe("TopicTest", "*");
// 註冊回調,當收到消息時執行
consumer.registerMessageListener(new MessageListenerConcurrently() {
public ConsumeConcurrentlyStatus consumeMessage(final List<MessageExt> msgs, final ConsumeConcurrentlyContext context) {
System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
for(MessageExt mext : msgs) {
System.out.println("message body: " + new String(mext.getBody()));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}
});
// 啓動 consumer
consumer.start();
System.out.printf("Consumer Started.%n");
System.out.println("-------"+(int)((Math.random()*9+1)*100000));
}
}
生產者代碼如下
public class TestP {
public static void main(String[] args) {
DefaultMQProducer producer = new DefaultMQProducer("demoGroup");
producer.setNamesrvAddr("127.0.0.1:9876");
//producer.setVipChannelEnabled(false);
// 在發送消息前,必須調用 start 方法來啓動 Producer,只需調用一次即可
try {
producer.start();
} catch (MQClientException e) {
e.printStackTrace();
}
//循環發送消息
try {
for (int i = 0; i < 10; i++) {
Message msg = new Message("TopicTest","TagA",("Good!" + i).getBytes("UTF-8"));
SendResult sendResult = producer.send(msg);
// 同步發送消息,只要不拋異常就是成功
if (sendResult != null) {
System.out.println(new Date() + " Send mq message success. Topic is:" + msg.getTopic() + " msgId is: " + sendResult.getMsgId());
}
}
}
catch (Exception e) {
System.out.println("失敗失敗失敗");
// 消息發送失敗,需要進行重試處理,可重新發送這條消息或持久化這條數據進行補償處理
e.printStackTrace();
}
// 在應用退出前,銷燬 Producer 對象
// 注意:如果不銷燬也沒有問題
producer.shutdown();
}
}
二個都啓動,都能收到消息就表示成功了,失敗了就看看是不是機器名,端口,topic不對,一般大概率是這個,還有問題的話就看看是不是被防火請攔到了,關閉下防火請,一般就沒啥問題了。
本地的還算比較成功的,在看看阿里雲mq,開通服務和申請資源是主要麻煩,由於沒權限,所以大家可以去看看這篇博客,特別詳細
https://blog.csdn.net/liuchaoxuan/article/details/83717101
資源申請好後,就可以本地搞個demo試試了,消費者代碼如下
public class ConsumerTest {
public static void main(String[] args) {
Properties properties = new Properties();
// 您在控制檯創建的 Group ID
properties.put(PropertyKeyConst.GROUP_ID, "GID_ID");
// AccessKey 阿里雲身份驗證,在阿里雲服務器管理控制檯創建
properties.put(PropertyKeyConst.AccessKey, ");
// SecretKey 阿里雲身份驗證,在阿里雲服務器管理控制檯創建
properties.put(PropertyKeyConst.SecretKey, "");
// 設置 TCP 接入域名,進入控制檯的實例管理頁面的“獲取接入點信息”區域查看
properties.put(PropertyKeyConst.NAMESRV_ADDR,"");
// 順序消息消費失敗進行重試前的等待時間,單位(毫秒),取值範圍: 10 毫秒 ~ 1800 毫秒
properties.put(PropertyKeyConst.SuspendTimeMillis, "100");
// 消息消費失敗時的最大重試次數
properties.put(PropertyKeyConst.MaxReconsumeTimes, "20");
// 在訂閱消息前,必須調用 start 方法來啓動 Consumer,只需調用一次即可。
OrderConsumer consumer = ONSFactory.createOrderedConsumer(properties);
consumer.subscribe(
// Message 所屬的 Topic
"topic",
// 訂閱指定 Topic 下的 Tags:
// 1. * 表示訂閱所有消息
// 2. TagA || TagB || TagC 表示訂閱 TagA 或 TagB 或 TagC 的消息
"*",
new MessageOrderListener() {
/**
* 1. 消息消費處理失敗或者處理出現異常,返回 OrderAction.Suspend<br>
* 2. 消息處理成功,返回 OrderAction.Success
*/
@Override
public OrderAction consume(Message message, ConsumeOrderContext context) {
System.out.println("message body: " + new String(message.getBody()));
return OrderAction.Success;
}
});
consumer.start();
}
}
生產者代碼如下
public class ProducerTest {
public static void main(String[] args) {
Properties properties = new Properties();
// AccessKey 阿里雲身份驗證,在阿里雲服務器管理控制檯創建
properties.put(PropertyKeyConst.AccessKey,"");
// SecretKey 阿里雲身份驗證,在阿里雲服務器管理控制檯創建
properties.put(PropertyKeyConst.SecretKey, "");
//設置發送超時時間,單位毫秒
properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000");
// 設置 TCP 接入域名,進入控制檯的實例管理頁面的“獲取接入點信息”區域查看
properties.put(PropertyKeyConst.NAMESRV_ADDR,"");
Producer producer = ONSFactory.createProducer(properties);
// 在發送消息前,必須調用 start 方法來啓動 Producer,只需調用一次即可
producer.start();
System.out.println(producer);
//循環發送消息
for (int i = 0; i < 10; i++){
Message msg = new Message();
msg.setTopic("topic");
msg.setBody("Good!".getBytes());
try {
SendResult sendResult = producer.send(msg);
// 同步發送消息,只要不拋異常就是成功
if (sendResult != null) {
System.out.println(new Date() + " Send mq message success. Topic is:" + msg.getTopic() + " msgId is: " + sendResult.getMessageId());
}
}
catch (Exception e) {
// 消息發送失敗,需要進行重試處理,可重新發送這條消息或持久化這條數據進行補償處理
System.out.println(new Date() + " Send mq message failed. Topic is:" + msg.getTopic());
e.printStackTrace();
}
}
// 在應用退出前,銷燬 Producer 對象
// 注意:如果不銷燬也沒有問題
producer.shutdown();
}
}
都啓動,能正常消費消息就表示成功了,如果沒成功,先看看身份驗證的那些參數,topic,tcp接入域名對不對,還有問題,可以ping一下tcp的地址,如果能接通,看看是不是ecc沒通阿里雲,如果還有問題可以在maven引入fastjson包看看,好像老版本的mq需要fastjson,還有問題請自行bing
這次項目中我們只是生產者,所以mq嵌入項目中還是挺簡單的,加包,工具類,用的地方單獨開個線程(不影響業務流程)調一下就完了,以前沒接觸過,正好這次學習了下。