使用RocketMQ的客戶端使用


RocketMQ提供了強大的消息系統功能,RocketMQ提供了java客戶端,可以提供使用。下面代碼來自RocketMQ4.0.0中的example代碼。


Producer消息生產端:

public class Producer {
	public static void main(String[] args) {
		// 創建一個Produer Group
		DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
		// 指定NameServer地址
		producer.setNamesrvAddr("192.168.1.163:9876");
		try {
			// 啓動producer
			producer.start();
			// 創建一個Message ,並指定topic、Tag和消息主體
			Message msg = new Message("ZZZZWWWW", "TagA",
					("Hello RocketMQ ").getBytes(RemotingHelper.DEFAULT_CHARSET));
			//向broker發送一個消息
			SendResult sendResult = producer.send(msg);
			System.out.printf("%s%n", sendResult);
		} catch (MQClientException | UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (RemotingException e) {
			e.printStackTrace();
		} catch (MQBrokerException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
        //當produer不再使用時,關閉produer
		producer.shutdown();
	}
}


Consumer消息消費端代碼:

public class Consumer {

    public static void main(String[] args) throws InterruptedException, MQClientException {


        //指定一個Consumer Group 來創建一個consumer
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name");

        //指定NameServer 地址,consumer和NameServer建立長鏈接,並且獲取topic信息以及broker的ip和地址
        consumer.setNamesrvAddr("192.168.1.163:9876");
        //指定消費offset的位置。TIMESTAMP表示從consumer建立後,producer向broker新發送的消息開始
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_TIMESTAMP);
        //指定消費topic,和過濾的TAG
        consumer.subscribe("ZZZZWWWW", "*");
        //註冊一個回調函數,當comsumer接收到消息時,執行的動作
        consumer.registerMessageListener(new MessageListenerConcurrently() {

            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                ConsumeConcurrentlyContext context) {
                System.out.printf(Thread.currentThread().getName() + " Receive New Messages: " + msgs + "%n");
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        //啓動comsumer實例
        consumer.start();
        System.out.printf("Consumer Started.%n");
    }
}


代碼分析:

在Consumer端註冊了一個MessageListener 接口實現,當Consumer端接收到異步分發的消息後,會執行MessageListener中的方法。


MessageListener提供了MessageListenerConcurrently 和MessageListenerOrderly 兩種策略。


根據MessageListenerConcurrently 和MessageListenerOrderly兩種策略,當pull到消息後,消息會被push到ConsumeMessageConcurrentlyService 和ConsumeMessageOrderlyService 被消費掉。


1、ConsumeMessageConcurrentlyService  ,其實內部爲一個ThreadPoolExecutor線程池,每一個Message會被轉換成一個任務class ConsumeRequest implements Runnable .ConsumerRequest Task 會提交到ThreadPoolExecutor中等待被並行執行。

在ConsumerMessageConcurrentlyService 內部,會根據ConsumeConcurrentlyStatus 處理狀態的結果,來繼續處理後續的事情processConsumeResult。


2、ConsumerMessageOrderlyService 裏面也是一個線程緩存池,在ConsumerRequest  Task任務中對每一個MessageQueue進行加鎖,從而保證順序消費。

同時,processConsumeResult也會處理消費失敗的情況。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章