RocketMQ安装与简单使用

写在前面:

1.消息中间件的发展:

第一代以ActiveMQ为代表,遵循JMS(java消息服务)规范                                                                                                  

第二代以RabbitMQ为代表是一个有Erlang语言开发的AMQP(高级消息队列协议)的开源实现                                                

第三代以kafka为代表,是一代高吞吐、高可用的消息中间件,以及RocketMQ

RocketMQ的特点:

1.RocketMQ 是一款分布式、队列模型的消息中间件,具有以下特点:
2.能够保证严格的消息顺序
3.提供丰富的消息拉取模式
4.高效的订阅者水平扩展能力
5.实时的消息订阅机制
6.亿级消息堆积能力
7.分布式高可用的部署架构,满足至少一次消息传递语义 
8.提供 docker 镜像用于隔离测试和云集群部署
9.提供配置、指标和监控等功能丰富的 Dashboard
选用理由:
    a.强调集群无单点,可扩展,任意一点高可用,水平可扩展。
    b.海量消息堆积能力,消息堆积后,写入低延迟。
   c.支持上万个队列
   d.消息失败重试机制
   e.消息可查询
   f.开源社区活跃    

   g.成熟度(经过双十一考验)

RocketMQ物理部署结构:

    

rocketMQ几个概念:

producer:消息生产者,生产者的作用就是将消息发送到 MQ,生产者本身既可以产生消息,如读取文本信息等。也可以对外提供接口,由外部应用来调用接口,再由生产者将收到的消息发送到 MQ

producer group: 生产者组,简单来说就是多个发送同一类消息的生产者称之为一个生产者组。在这里可以不用关心,只要知道有这么一个概念即可,Producer实例可以是多机器、单机器多进程、单进程中的多对象。Producer可以发送多个Topic。处理分布式事务时,也需要Producer集群提高可靠性

consumer : 消息消费者,简单来说,消费 MQ 上的消息的应用程序就是消费者,至于消息是否进行逻辑处理,还是直接存储到数据库等取决于业务需要

consumer group : 消费者组,和生产者类似,消费同一类消息的多个 consumer 实例组成一个消费者组.Consumer实例 的集合。Consumer 实例可以是多机器、但机器多进程、单进程中的多对象。同一个Group中的实例,在集群模式下,以均摊的方式消费;在广播模式下,每个实例都全部消费。

Topic : Topic 是一种消息的逻辑分类,比如说你有订单类的消息,也有库存类的消息,那么就需要进行分类,一个是订单 Topic 存放订单相关的消息,一个是库存 Topic 存储库存相关的消息

Message : Message 是消息的载体。一个 Message 必须指定 topic,相当于寄信的地址。Message 还有一个可选的 tag 设置,以便消费端可以基于 tag 进行过滤消息。也可以添加额外的键值对,例如你需要一个业务 key 来查找 broker 上的消息,方便在开发过程中诊断问题

Tag : 标签可以被认为是对 Topic 进一步细化。一般在相同业务模块中通过引入标签来标记不同用途的消息

Broker : Broker 是 RocketMQ 系统的主要角色,其实就是前面一直说的 MQ。Broker 接收来自生产者的消息,储存以及为消费者拉取消息的请求做好准备

Name Server : Name Server 为 producer 和 consumer 提供路由信息

Push Consumer : 应用通常向Consumer对象注册一个Listener接口,一旦收到消息,Consumer对象立刻回调Listener接口方法。所以,所谓Push指的是客户端内部的回调机制,并不是与服务端之间的机制

Pull Consumer : 应用通常主动调用Consumer从服务端拉消息,然后处理。这用的就是短轮询方式了,在不同情况下,与长轮询各有优点
 

1,linux安装

        官网介绍很详细:

         http://rocketmq.apache.org/docs/quick-start/

       注意:1,一般的启动失败是因为内存不够导致的,需要修改runserver.sh与runbroker.sh.修改地方如下:

runserv.sh

JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

runbroker.sh

JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m"

 2,broker启动的时候需要指定broker的外网ip,启动方式如下:

nohup sh bin/mqbroker -n 172.19.211.119:9876 -c conf/broker.properties  &

broker.properties:

#进入rocketmq根目录
cd incubator-rocketmq/distribution/target/apache-rocketmq
#编写配置文件,并写好配置
echo "brokerIP1=10.19.73.64的外网IP" > broker.properties

 

2,本地demo

2.1 pom.xml

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>4.3.0</version>
</dependency>

2.2 producer

2.2.1 同步调用:

package com.equaker.demo.test.mq;

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;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;


public class Mq_Producer_Test {

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


    /**
     * 同步发送
     */
    public static void Sync_Producer() throws MQClientException, InterruptedException {
        //声明并初始化一个producer
        //需要一个producer group名字作为构造方法的参数,这里为producer1
        DefaultMQProducer producer = new DefaultMQProducer("producer1");

        //设置NameServer地址,此处应改为实际NameServer地址,多个地址之间用;分隔
        //NameServer的地址必须有,但是也可以通过环境变量的方式设置,不一定非得写死在代码里
        producer.setNamesrvAddr("172.26.5.160:9876");
        producer.setSendMsgTimeout(6000);
        //调用start()方法启动一个producer实例
        producer.start();

        //发送10条消息到Topic为TopicTest,tag为TagA,消息内容为“Hello RocketMQ”拼接上i的值
        for (int i = 0; i < 2; i++) {
            try {
                Message msg = new Message("TopicTest",// topic
                        "TagA",// tag
                        ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET)// body
                );

                //调用producer的send()方法发送消息
                //这里调用的是同步的方式,所以会有返回结果
                SendResult sendResult = producer.send(msg);

                //打印返回结果,可以看到消息发送的状态以及一些相关信息
                System.out.println(sendResult);
            } catch (Exception e) {
                e.printStackTrace();
                Thread.sleep(1000);
            }
        }

        //发送完消息之后,调用shutdown()方法关闭producer
        producer.shutdown();
    }

}

2.2.2 异步调用

package com.equaker.demo.test.mq;

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;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;


public class Mq_Producer_Test {

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

    /**
     * 异步发送
     */
    public static void Async_Producer() throws MQClientException, InterruptedException {

        //声明并初始化一个producer
        //需要一个producer group名字作为构造方法的参数,这里为producer1
        DefaultMQProducer producer = new DefaultMQProducer("producer1");

        //设置NameServer地址,此处应改为实际NameServer地址,多个地址之间用;分隔
        //NameServer的地址必须有,但是也可以通过环境变量的方式设置,不一定非得写死在代码里
        producer.setNamesrvAddr("172.26.5.160:9876");
        producer.setSendMsgTimeout(6000);
        //调用start()方法启动一个producer实例
        producer.start();
        int messageCount = 5;
        // 主线程阻塞器
        final CountDownLatch countDownLatch = new CountDownLatch(messageCount);
        //发送10条消息到Topic为TopicTest,tag为TagA,消息内容为“Hello RocketMQ”拼接上i的值
        for (int i = 0; i < messageCount; i++) {
            try {
                Message msg = new Message("TopicTest",// topic
                        "TagA",// tag
                        ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET)// body
                );

                producer.send(msg, new SendCallback() {
                    @Override
                    public void onSuccess(SendResult sendResult) {

                        System.out.println("success: " + sendResult);
                        countDownLatch.countDown();
                    }

                    @Override
                    public void onException(Throwable throwable) {
                        System.out.println("error: " + throwable);
                        countDownLatch.countDown();
                    }
                });

            } catch (Exception e) {
                e.printStackTrace();
                Thread.sleep(1000);
            }
        }
        countDownLatch.await(10, TimeUnit.SECONDS);
        //发送完消息之后,调用shutdown()方法关闭producer
        producer.shutdown();
    }
}

注意:

可能会报错:

1         org.apache.rocketmq.client.exception.MQClientException: No route info of this topic, topic-2
See http://rocketmq.apache.org/docs/faq/ for further details. Exception org.apache.rocketmq.client.exception.MQClientException: No route info of this topic, topic-2
See http://rocketmq.apache.org/docs/faq/ for further details. 

主要是因为rocketMQ异步发送,采用任务模式,及新线程,任务尚未完成就被producer.shutdown();这里我们采用CountDownLatch解决。

2.2.3 单向发送数据

单向传输用于要求中等可靠性的情况,例如日志收集。

适用于某些耗时非常短,但对可靠性要求并不高的场景,例如日志收集。

只发送消息,不等待服务器响应,只发送请求不等待应答。此方式发送消息的过程耗时非常短,一般在微秒级别。

package org.equaker.cache;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;

/**
 * 单向发送消息-RocketMQ
 * 
 * @author EQuaker
 *
 */
public class OnewayProducer_RocketMQ {
	public static void main(String[] args) throws Exception {
		// Instantiate with a producer group name.
		DefaultMQProducer producer = new DefaultMQProducer("group3");
		// Specify name server addresses.
		producer.setNamesrvAddr("外网ip:9876");
		// Launch the instance.
		producer.start();
		for (int i = 0; i < 10; i++) {
			// Create a message instance, specifying topic, tag and message body.
			Message msg = new Message("topic-3" /* Topic */, "TagA" /* Tag */,
					("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
			);
			// Call send message to deliver message to one of brokers.
			producer.sendOneway(msg);

		}
		// Shut down once the producer instance is not longer in use.
		producer.shutdown();
	}
}

2.3 消费者

package org.equaker.cache;

import java.util.List;

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.common.message.MessageExt;
import org.apache.rocketmq.common.message.MessageQueue;

public class Consumer_RocketMQ {
	
	public static void main(String[] args) throws Exception{
		// Instantiate with specified consumer group name.
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consume1");
         
        // Specify name server addresses.
        consumer.setNamesrvAddr("外网ip:9876");
        //默认集群消费模式
        consumer.setMessageModel(MessageModel.CLUSTERING);
        // Subscribe one more more topics to consume.
        consumer.subscribe("topic-3", "*");
        // Register callback to execute on arrival of messages fetched from brokers.
        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);
            	MessageQueue messageQueue = context.getMessageQueue();
            	System.out.println("broker name: "+messageQueue.getBrokerName());
            	System.out.println("topic name: "+messageQueue.getTopic());
            	System.out.println("msgs length: "+msgs.size());
                for(MessageExt msg : msgs) {
                	System.out.println(new String(msg.getBody()));
                }
                System.out.println("*******************");
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        //Launch the consumer instance.
        consumer.start();
        System.out.printf("Consumer Started.%n");
	}
	

}

3.顺序消费

RocketMQ使用FIFO顺序提供有序消息。主要是在生产者端使用MessageQueueSelector实现。

package com.equaker.demo.test.mq;

import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
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.common.message.MessageQueue;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class Mq_Producer_Test {

    public static void main(String[] args) throws MQClientException, InterruptedException, UnsupportedEncodingException, RemotingException, MQBrokerException {
        //Async_Producer();
        //Sync_Producer();
        //OneWay_Producer();
        Order_Producer();
    }

public static void Order_Producer() throws MQClientException, UnsupportedEncodingException, RemotingException, InterruptedException, MQBrokerException {
        //声明并初始化一个producer
        //需要一个producer group名字作为构造方法的参数,这里为producer1
        DefaultMQProducer producer = new DefaultMQProducer("producer1");

        //设置NameServer地址,此处应改为实际NameServer地址,多个地址之间用;分隔
        //NameServer的地址必须有,但是也可以通过环境变量的方式设置,不一定非得写死在代码里
        producer.setNamesrvAddr("172.26.5.160:9876");
        producer.setSendMsgTimeout(6000);
        //调用start()方法启动一个producer实例
        producer.start();

        String[] tags = new String[] {"TagA", "TagB", "TagC", "TagD", "TagE"};
        for (int i = 0; i < 10; i++) {
            int orderId = i % 10;
            //Create a message instance, specifying topic, tag and message body.
            Message msg = new Message("TopicTest", tags[i % tags.length], "KEY" + i,
                    ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));
            SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
                @Override
                public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
                    Integer id = (Integer) arg;
                    int index = id % mqs.size();
                    return mqs.get(index);
                }
            }, orderId);

            System.out.printf("%s%n", sendResult);
        }
        //server shutdown
        producer.shutdown();
    }
}

4.广播消费

主要是在消费者端,设置为广播模式。默认为集群模式。

package com.equaker.demo.test.mq;

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 org.apache.rocketmq.common.protocol.heartbeat.MessageModel;

import java.util.List;

public class Mq_Consumer_Test {

    public static void main(String[] args) throws MQClientException {
        //声明并初始化一个consumer
        //需要一个consumer group名字作为构造方法的参数,这里为consumer1
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer1");

        //同样也要设置NameServer地址
        consumer.setNamesrvAddr("172.26.5.160:9876");

        //这里设置的是一个consumer的消费策略
        //CONSUME_FROM_LAST_OFFSET 默认策略,从该队列最尾开始消费,即跳过历史消息
        //CONSUME_FROM_FIRST_OFFSET 从队列最开始开始消费,即历史消息(还储存在broker的)全部消费一遍
        //CONSUME_FROM_TIMESTAMP 从某个时间点开始消费,和setConsumeTimestamp()配合使用,默认是半个小时以前
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        //设置为广播模式,默认集群消费模式
        consumer.setMessageModel(MessageModel.BROADCASTING);

        //设置consumer所订阅的Topic和Tag,*代表全部的Tag
        consumer.subscribe("TopicTest", "*");

        //设置一个Listener,主要进行消息的逻辑处理
        consumer.registerMessageListener(new MessageListenerConcurrently() {

            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                                                            ConsumeConcurrentlyContext context) {

                System.out.println(Thread.currentThread().getName() + " Receive New Messages: " + msgs);

                MessageExt ext = msgs.get(0);
                System.out.println(new String(ext.getBody()));
                //返回消费状态
                //CONSUME_SUCCESS 消费成功
                //RECONSUME_LATER 消费失败,需要稍后重新消费
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });

        //调用start()方法启动consumer
        consumer.start();

        System.out.println("Consumer Started.");
    }
}

 

5. 延迟消费

消息被消耗比存储时间晚。主要是在生产者方的消息体设置延迟信息。

messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h(我们使用第三级 即延迟10s)

package com.equaker.demo.test.mq;

import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
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.common.message.MessageQueue;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class Mq_Producer_Test {

    public static void main(String[] args) throws MQClientException, InterruptedException, UnsupportedEncodingException, RemotingException, MQBrokerException {
        //Async_Producer();
        //Sync_Producer();
        //OneWay_Producer();
        Order_Producer();
    }
public static void Schedule_Producer() throws Exception {

        //声明并初始化一个producer
        //需要一个producer group名字作为构造方法的参数,这里为producer1
        DefaultMQProducer producer = new DefaultMQProducer("producer1");

        //设置NameServer地址,此处应改为实际NameServer地址,多个地址之间用;分隔
        //NameServer的地址必须有,但是也可以通过环境变量的方式设置,不一定非得写死在代码里
        producer.setNamesrvAddr("172.26.5.160:9876");
        producer.setSendMsgTimeout(6000);
        //调用start()方法启动一个producer实例
        producer.start();

        Message message = new Message("TopicTest", ("Hello scheduled message " + 1).getBytes());
        // This message will be delivered to consumer 10 seconds later.

        message.setDelayTimeLevel(3);
        // Send the message
        producer.send(message);
        System.out.println("send...");

        producer.shutdown();
    }
}

 

6.批量生产

批量发送消息可提高传递小消息的性能。

同一批次的消息应具有:相同的主题,相同的waitStoreMsgOK,并且不支持计划。

此外,一批邮件的总大小不得超过1MiB。

package com.equaker.demo.test.mq;

import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
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.common.message.MessageQueue;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class Mq_Producer_Test {

    public static void main(String[] args) throws MQClientException, InterruptedException, UnsupportedEncodingException, RemotingException, MQBrokerException {
        //Async_Producer();
        //Sync_Producer();
        //OneWay_Producer();
        Order_Producer();
    }

public static void Batch_Producer() throws Exception {

        //声明并初始化一个producer
        //需要一个producer group名字作为构造方法的参数,这里为producer1
        DefaultMQProducer producer = new DefaultMQProducer("producer1");

        //设置NameServer地址,此处应改为实际NameServer地址,多个地址之间用;分隔
        //NameServer的地址必须有,但是也可以通过环境变量的方式设置,不一定非得写死在代码里
        producer.setNamesrvAddr("172.26.5.160:9876");
        producer.setSendMsgTimeout(6000);
        //调用start()方法启动一个producer实例
        producer.start();

        Message message1 = new Message("TopicTest", ("Hello scheduled message " + 1).getBytes());
        Message message2 = new Message("TopicTest", ("Hello scheduled message " + 2).getBytes());
        Message message3 = new Message("TopicTest", ("Hello scheduled message " + 3).getBytes());
        Message message4 = new Message("TopicTest", ("Hello scheduled message " + 4).getBytes());

        producer.send(Arrays.asList(message1, message2, message3, message4));
        producer.shutdown();
    }

}

 

7.过滤消费

通常在订阅通道的时候,我们可以指定tag,进行消息过滤。例如: consumer.subscribe("TopicTest", "tagA || tagB || tagC");

这里面的弊端是一个消息只有一个tag,如果我们想消费的消息来自不同的tag,就有点麻烦。这里我们使用RocketMq Sql。

7.1,过滤消费-生产者

生产者通过Message.putUserProperty设置变量信息。

package com.equaker.demo.test.mq;

import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
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.common.message.MessageQueue;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class Mq_Producer_Test {

    public static void main(String[] args) throws MQClientException, InterruptedException, UnsupportedEncodingException, RemotingException, MQBrokerException {
        //Async_Producer();
        //Sync_Producer();
        //OneWay_Producer();
        Filter_Producer();
    }

public static void Filter_Producer() throws Exception {

        //声明并初始化一个producer
        //需要一个producer group名字作为构造方法的参数,这里为producer1
        DefaultMQProducer producer = new DefaultMQProducer("producer1");

        //设置NameServer地址,此处应改为实际NameServer地址,多个地址之间用;分隔
        //NameServer的地址必须有,但是也可以通过环境变量的方式设置,不一定非得写死在代码里
        producer.setNamesrvAddr("172.26.5.160:9876");
        producer.setSendMsgTimeout(6000);
        //调用start()方法启动一个producer实例
        producer.start();

        Message message1 = new Message("TopicTest", ("Hello scheduled message " + 1).getBytes());
        message1.putUserProperty("a", "25");

        producer.send(message1);
        producer.shutdown();

    }

}

7.1,过滤消费-消费者

消费者通过MessageSelector.bySql 过滤。

package com.equaker.demo.test.mq;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.MessageSelector;
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 org.apache.rocketmq.common.protocol.heartbeat.MessageModel;

import java.util.List;

public class Mq_Consumer_Test {

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

        //Common_Consumer();
        Filter_Consumer();

    }
    public static void Filter_Consumer() throws MQClientException {
        //声明并初始化一个consumer
        //需要一个consumer group名字作为构造方法的参数,这里为consumer1
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer1");

        //同样也要设置NameServer地址
        consumer.setNamesrvAddr("172.26.5.160:9876");

        //这里设置的是一个consumer的消费策略
        //CONSUME_FROM_LAST_OFFSET 默认策略,从该队列最尾开始消费,即跳过历史消息
        //CONSUME_FROM_FIRST_OFFSET 从队列最开始开始消费,即历史消息(还储存在broker的)全部消费一遍
        //CONSUME_FROM_TIMESTAMP 从某个时间点开始消费,和setConsumeTimestamp()配合使用,默认是半个小时以前
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        //默认集群消费模式
        consumer.setMessageModel(MessageModel.CLUSTERING);

        //设置consumer所订阅的Topic和Tag,过滤a属性在20-30之间
       consumer.subscribe("TopicTest", MessageSelector.bySql("a between 20 and 30"));

        //设置一个Listener,主要进行消息的逻辑处理
        consumer.registerMessageListener(new MessageListenerConcurrently() {

            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                                                            ConsumeConcurrentlyContext context) {

                System.out.println(Thread.currentThread().getName() + " Receive New Messages: " + msgs);

                MessageExt ext = msgs.get(0);
                System.out.println(new String(ext.getBody()));
                //返回消费状态
                //CONSUME_SUCCESS 消费成功
                //RECONSUME_LATER 消费失败,需要稍后重新消费
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        //调用start()方法启动consumer
        consumer.start();

        System.out.println("Consumer Started.");
    }
}

8,事务消息

 

rocketMq的事务消息是一大特性,我们放在下一章《分布式事务与RocketMq 事务消息》和分布式事务一块说。

 

更多操作见:http://rocketmq.apache.org/docs/simple-example/

https://github.com/apache/rocketmq/tree/master/example

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值