消息中间件-rocketMq-api学习

作为程序员,要时刻记得去学习。

这一讲主要是结合rocketmq的原生api,进行学习。

  • 首先去官网下载rocketmq源码,参照源码,建立生产者,消费者。
    消息中间件-rocketMq-api学习_第1张图片

生产者生产模式:

  • producer同步发送消息
package org.apache.rocketmq.example.quickstart;

import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
public class Producer {
     

    public static void main(String[] args) throws MQClientException, InterruptedException {
     
        
        DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
        
        producer.setNamesrvAddr("192.168.0.11:9876;192.168.0.13:9876");

        producer.start();

        for (int i = 0; i < 20; i++) {
     
            try {
     
                Message msg = new Message("TopicTest",
                        "TagA",
                        ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET)
                );
                
                SendResult sendResult = producer.send(msg);

                System.out.printf("%s%n", sendResult);
            } catch (Exception e) {
     
                e.printStackTrace();
                Thread.sleep(1000);
            }
        }
        producer.shutdown();
    }
}

  • producer异步发送
package org.apache.rocketmq.example.simple;

import java.io.UnsupportedEncodingException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;

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

        DefaultMQProducer producer = new DefaultMQProducer("Jodie_Daily_test");
         producer.setNamesrvAddr("192.168.0.11:9876;192.168.0.13:9876");
        producer.start();
        producer.setRetryTimesWhenSendAsyncFailed(0);

        int messageCount = 100;
        final CountDownLatch countDownLatch = new CountDownLatch(messageCount);
        for (int i = 0; i < messageCount; i++) {
     
            try {
     
                final int index = i;
                Message msg = new Message("Jodie_topic_1023",
                    "TagA",
                    "OrderID188",
                    "Hello world".getBytes(RemotingHelper.DEFAULT_CHARSET));
                producer.send(msg, new SendCallback() {
     
                    @Override
                    public void onSuccess(SendResult sendResult) {
     
                        countDownLatch.countDown();
                        System.out.printf("%-10d OK %s %n", index, sendResult.getMsgId());
                    }

                    @Override
                    public void onException(Throwable e) {
     
                        countDownLatch.countDown();
                        System.out.printf("%-10d Exception %s %n", index, e);
                        e.printStackTrace();
                    }
                });
            } catch (Exception e) {
     
                e.printStackTrace();
            }
        }
        System.out.println("等待他们执行完,我在执行~~~~~~");
        countDownLatch.await(5, TimeUnit.SECONDS);
        producer.shutdown();
    }
}
  • prdoducer单向发送
package org.apache.rocketmq.example.quickstart;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
public class Producer {
     
    public static void main(String[] args) throws MQClientException, InterruptedException {
     

        DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");

        producer.setNamesrvAddr("192.168.0.11:9876;192.168.0.13:9876");

        producer.start();

        for (int i = 0; i < 20; i++) {
     
            try {
     
                Message msg = new Message("TopicTest",
                        "TagA",
                        ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET)
                );
               producer.sendOneway(msg);
            } catch (Exception e) {
     
                e.printStackTrace();
                Thread.sleep(1000);
            }
        }
        producer.shutdown();
    }
}

现在来讲讲三种方式有什么区别:

  • 同步发送send(msg)方法有返回值,但是需要关注接口调用的返回值。也可以认为如果调用过程的某一刻是阻塞的。

消息中间件-rocketMq-api学习_第2张图片
异步发送send(msg,sendResultBack),这种做法主要是不需要每次主动等待调用的结果,可以去处理其它逻辑。

  • demo里面用了CountDownLatch:主要是让一个线程等待其他线程执行完后在执行。
  • 主要是为了模拟异步发送的效果,maIn线程先打印这个输出,但是发送的回调是在后面完成的。证明了,main没有故意等待消息发送的成功与否,而线程去做了其他的事情。
    发送失败成功与否都会回调,然后调用countDownLatch.countDown()方法,messageCount 减一
    直到messageCount =0,此时才会继续执行producer.shutDown();
 int messageCount = 100;
 final CountDownLatch countDownLatch = new CountDownLatch(messageCount);

消息中间件-rocketMq-api学习_第3张图片

  • 单向发送表示:只管发,不关心结果
    producer.sendOneway(msg);

- 消费者消费模式:

消费者模式一般有pull和push:

首先看push模式
官方提供的消费push消费demo:

package org.apache.rocketmq.example.sample;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

import java.util.List;
public class PushConsumer {
     
    public static void main(String[] args) throws InterruptedException, MQClientException {
     
    //DefaultMQPushConsumer 官方提供的消费类
    DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("CID_JODIE_1");
    //设置一些参数
    consumer.setNamesrvAddr("192.168.0.11:9876;192.168.0.13:9876");
    consumer.subscribe("TopicTest", "*");
    consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
    //wrong time format 2017_0422_221800
    consumer.setConsumeTimestamp("20181109221800");
    //注入监听器,消息推送过来,消费消息
    consumer.registerMessageListener(new MessageListenerConcurrently() {
     

    @Override
       public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
       ConsumeConcurrentlyContext context) {
     
           System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
           return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
  // 启动消费者
   consumer.start();
     System.out.printf("Consumer Started.%n");
    }
}

再看pull模式:

package org.apache.rocketmq.example.sample;
import org.apache.rocketmq.client.consumer.DefaultMQPullConsumer;
import org.apache.rocketmq.client.consumer.PullResult;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageQueue;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class PullConsumer {
     
    private static final Map<MessageQueue, Long> OFFSE_TABLE = new HashMap<MessageQueue, Long>();

    public static void main(String[] args) throws MQClientException {
     
        DefaultMQPullConsumer consumer = new DefaultMQPullConsumer("please_rename_unique_group_name_5");
        consumer.setNamesrvAddr("192.168.0.11:9876;192.168.0.13:9876");
        consumer.start();
        Set<MessageQueue> mqs = consumer.fetchSubscribeMessageQueues("TopicTest");
        for (MessageQueue mq : mqs) {
     
            System.out.printf("Consume from the queue: %s%n", mq);
            SINGLE_MQ:
            while (true) {
     
                try {
     
                    PullResult pullResult =
                        consumer.pullBlockIfNotFound(mq, null, getMessageQueueOffset(mq), 32);
                    System.out.printf("%s%n", pullResult);
                    putMessageQueueOffset(mq, pullResult.getNextBeginOffset());
                    switch (pullResult.getPullStatus()) {
     
                        case FOUND:
                            break;
                        case NO_MATCHED_MSG:
                            break;
                        case NO_NEW_MSG:
                            break SINGLE_MQ;
                        case OFFSET_ILLEGAL:
                            break;
                        default:
                            break;
                    }
                } catch (Exception e) {
     
                    e.printStackTrace();
                }
            }
        }
        consumer.shutdown();
    }
    private static long getMessageQueueOffset(MessageQueue mq) {
     
        Long offset = OFFSE_TABLE.get(mq);
        if (offset != null)
            return offset;
        return 0;
    }
    private static void putMessageQueueOffset(MessageQueue mq, long offset) {
     
        OFFSE_TABLE.put(mq, offset);
    }

}

你可能感兴趣的:(rocketmq,java)