RocketMQ(02)——發送消息的三種方式

發送消息的三種方式

同步發送

Producer在進行消息發送時可以是阻塞的,也可以是非阻塞的。具體對應到發送方式一共有三種,分別是同步、異步和單向的(ONEWAY)。之前介紹的調用send()返回SendResult的方法是阻塞的,它一定要等到Broker進行了響應後纔會返回,才能繼續往下執行。對於下面的代碼就是隻有第一條消息發送完了後,才能發送第二條消息,接着是第三條。這種阻塞發送的方式也叫同步發送,它的整個響應時間還包括可能的重試時間。其內部會默認進行兩次重試,可以通過setRetryTimesWhenSendFailed()指定同步發送時內部最大的重試次數。

@Test
public void testSyncSend() throws Exception {
  //指定Producer的Group爲group1
  DefaultMQProducer producer = new DefaultMQProducer("group1");
  //指定需要連接的Name Server
  producer.setNamesrvAddr(nameServer);
  //發送消息前必須調用start(),其內部會進行一些初始化工作。
  producer.start();
  for (int i = 0; i < 10; i++) {
    //指定消息發送的Topic是topic1。
    Message message = new Message("topic1", ("hello" + i).getBytes());
    //同步發送,發送成功後纔會返回
    SendResult sendResult = producer.send(message);
    if (sendResult.getSendStatus() == SendStatus.SEND_OK) {
      System.out.println("消息發送成功:" + sendResult);
    } else {
      System.out.println("消息發送失敗:" + sendResult);
    }
  }
  //使用完畢後需要把Producer關閉,以釋放相應的資源
  producer.shutdown();
}

異步發送

同步發送時調用send()的線程會阻塞,而異步發送時當前線程是不會阻塞的。發送結果將由一個回調函數進行回調。下面的代碼就是異步發送消息的示例,它與同步發送消息的區別是它在發送消息時多傳遞了一個SendCallback對象,該方法一調用立馬返回,而不需要等待Broker的響應返回。消息發送成功或失敗後將回調SendCallback對象的對應方法。所以對於下面示例而言,第一條消息Broker還沒有確認發送成功時,第二條消息就發送了,第三條消息也是一樣。它們真正在Broker發送成功的順序其實是不確定的。

@Test
public void sendAsync() throws Exception {
  DefaultMQProducer producer = new DefaultMQProducer("group1");
  producer.setNamesrvAddr(nameServer);
  producer.start();
  CountDownLatch latch = new CountDownLatch(10);
  for (int i = 0; i < 10; i++) {
    Message message = new Message("topic1", ("send by async, no." + i).getBytes(RemotingHelper.DEFAULT_CHARSET));
    producer.send(message, new SendCallback() {
      @Override
      public void onSuccess(SendResult sendResult) {
        System.out.println("發送成功:" + message);
        latch.countDown();
      }

      @Override
      public void onException(Throwable throwable) {
        System.out.println("發送失敗");
        latch.countDown();
      }
    });
  }
  latch.await();
  producer.shutdown();
}

通過異步方式發送消息如果失敗了,其內部也是會進行重試的,其最大重試次數是通過setRetryTimesWhenSendAsyncFailed()指定的,默認也是2次。

ONEWAY

除了同步發送和異步發送外,還有一種發送方式叫ONEWAY,它的發送是單向的,即它不需要等待Broker的響應,只管發送即可,而不論發送成功與失敗。通常應用於一些消息不是那麼重要,可丟失的場景。它的發送是通過調用sendOneway()發送的。

@Test
public void sendOneway() throws Exception {
  DefaultMQProducer producer = new DefaultMQProducer("group1");
  producer.setNamesrvAddr(nameServer);
  producer.start();
  for (int i=0; i<10; i++) {
    Message message = new Message("topic1", "tag2", ("message send with oneway, no."+i).getBytes());
    producer.sendOneway(message);
  }
  producer.shutdown();
}

(注:本文是基於Apache RocketMQ4.5.0所寫)

發佈了266 篇原創文章 · 獲贊 175 · 訪問量 178萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章