1.RocketMQ简单使用(一)

本次使用的是rocketmq4.3.0版本,

新建maven项目导入依赖

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

// 消息发送的状态
public enum SendStatus {
SEND_OK, // 发送成功
FLUSH_DISK_TIMEOUT, // 刷盘超时。当Broker设置的刷盘策略为同步刷盘时才可能出
现这种异常状态。异步刷盘不会出现
FLUSH_SLAVE_TIMEOUT, // Slave同步超时。当Broker集群设置的Master-Slave的复
制方式为同步复制时才可能出现这种异常状态。异步复制不会出现
SLAVE_NOT_AVAILABLE, 
// 没有可用的Slave。当Broker集群设置为Master-Slave的
复制方式为同步复制时才可能出现这种异常状态。异步复制不会出现
}

发送同步消息

同步发送消息是指,Producer发出⼀条消息后,会在收到MQ返回的ACK之后才发下⼀条消息。该方式的消息可靠性最高,但消息发送效率太低。

代码示例

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.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;

public class SyncProducer {

    public static void main(String[] args) throws MQClientException, MQBrokerException, RemotingException, InterruptedException {
        // 创建一个producer,参数为Producer Group名称
        DefaultMQProducer producer = new DefaultMQProducer("pg");
        // 指定nameServer地址
        producer.setNamesrvAddr("127.0.0.1:9876");
       // 设置当发送失败时重试发送的次数,默认为2次
        producer.setRetryTimesWhenSendFailed(3);
        // 设置发送超时时限为5s,默认3s
        producer.setSendMsgTimeout(5000);
        // 开启生产者
        producer.start();

        for (int i = 0; i < 10; i++) {
            byte[] body = ("Hi," + i).getBytes();
            Message message = new Message("someTopic", "someTag", body);
            // 为消息指定key
            message.setKeys("key-" + i);
            SendResult sendResult = producer.send(message);
            System.out.println(sendResult);
        }
        //关闭
        producer.shutdown();
    }

}

异步发送消息

异步发送消息是指,Producer发出消息后无需等待MQ返回ACK,直接发送下⼀条消息。该方式的消息可靠性可以得到保障,消息发送效率也可以。

import java.util.concurrent.TimeUnit;
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.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;

public class ASyncProducer {

    public static void main(String[] args) throws MQClientException, MQBrokerException, RemotingException, InterruptedException {
        // 创建一个producer,参数为Producer Group名称
        DefaultMQProducer producer = new DefaultMQProducer("myTopicA_pg");
        // 指定nameServer地址
        producer.setNamesrvAddr("127.0.0.1:9876");
       // 设置当发送失败时不进行重试。默认为2
        producer.setRetryTimesWhenSendAsyncFailed(0);

        // 指定新创建的Topic的Queue数量为2,默认为4
        producer.setDefaultTopicQueueNums(2);

        // 开启生产者
        producer.start();

        for (int i = 0; i < 10; i++) {
            byte[] body = ("Hi," + i).getBytes();
            Message message = new Message("myTopicA", "myTag", body);
            // 为消息指定key
            message.setKeys("key-" + i);
            //异步发送
             producer.send(message, new SendCallback() {
                 public void onSuccess(SendResult sendResult) {
                     System.out.println("发送成功:"+sendResult);
                 }

                 public void onException(Throwable e) {
                     e.printStackTrace();
                 }
             });
        }

        //休眠一会,让异步发送完成。
        TimeUnit.SECONDS.sleep(10);

        //关闭
        producer.shutdown();
    }

}

单向发送消息

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.exception.RemotingException;

public class OnewayProducer {

    public static void main(String[] args) throws MQClientException, RemotingException, InterruptedException {
        DefaultMQProducer producer = new DefaultMQProducer("myTopicB_pg");
        producer.setNamesrvAddr("127.0.0.1:9876");
        producer.start();

        for (int i = 0; i < 10; i++) {
            byte[] body = ("Hi," + i).getBytes();
            Message message = new Message("myTopicB", "myTag", body);
            producer.sendOneway(message);
        }

        producer.shutdown();
    }

}

发送顺序消息

全局有序需要设置Queue为1.,不为1,只能保证每个队列的有序

以下只能保证发送的顺序,消费的时候还应该使用顺序消费。不能多线程并发消费。

import java.util.List;
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.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageQueue;
import org.apache.rocketmq.remoting.exception.RemotingException;

public class OrderProducer {

    public static void main(String[] args) throws MQClientException, MQBrokerException, RemotingException, InterruptedException {
        DefaultMQProducer producer = new DefaultMQProducer("myTopicOrderA_pg");
        producer.setNamesrvAddr("127.0.0.1:9876");
        
        //全局有序需要设置为1
        producer.setDefaultTopicQueueNums(1);
        producer.start();

        for (int i = 0; i < 10; i++) {
            Integer orderId = i;
            byte[] body = ("Hi," + i).getBytes();
            Message message = new Message("myTopicOrderA", "myTag", body);
            // 为消息指定key
            message.setKeys(i+"");

            //send()第三个参数值会传递给选择器的select()的第三个参数
            SendResult sendResult = producer.send(message, new MessageQueueSelector() {
                public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {

                    //用key作为参数选择队列,当前是int类型,
                    // 如果string类型可使用hash算法。
                    String keys = msg.getKeys();
                    int key = Integer.parseInt(keys);
                    int index = key % mqs.size();


                    //使用arg作为参数选择队列的算法。
//                    Integer id = (Integer) arg;
//                    int index = id % mqs.size();


                    return mqs.get(index);
                }
            }, orderId);
            System.out.println(sendResult);
        }

        producer.shutdown();
    }

}

发送延时消息

当消息写入到Broker后,在指定的时长后才可被消费处理的消息,称为延时消息。

采用RocketMQ的延时消息可以实现 定时任务 的功能,而无需使用定时器。

典型的应用场景是,电商交易中超时未支付关闭订单的场景,12306平台订票超时未支付取消订票的场景。

默认级别:从1开始 

private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";

可以在broker.conf 自定义级别

或者消费的时候再次发送延时队列,达到再次延时的目的。

import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;

public class DelayProducer {

    public static void main(String[] args) throws Exception {
        DefaultMQProducer producer = new DefaultMQProducer("myTopicD_pg");
        producer.setNamesrvAddr("127.0.0.1:9876");
        producer.start();

        for (int i = 0; i < 10; i++) {
            byte[] body = ("Hi," + i).getBytes();
            Message message = new Message("myTopicD", "myTag", body);
            // 指定消息延迟等级为6级,即延迟2min
            message.setDelayTimeLevel(6);
            SendResult sendResult = producer.send(message);
         // 输出消息被发送的时间
            System.out.print(new SimpleDateFormat("mm:ss").format(new Date()));
            System.out.println(", " + sendResult);
        }

        System.out.println("-----------------");
        producer.shutdown();

    }

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是使用RocketMQ实现一个简单的消息队列的步骤: 1. 下载RocketMQ 首先你需要从RocketMQ官网下载RocketMQ压缩包,并解压到你的本地目录。 2. 启动Name Server和Broker 在解压后的RocketMQ目录下,进入bin目录,执行以下命令启动Name Server和Broker: ``` sh mqnamesrv sh mqbroker -n localhost:9876 ``` 3. 创建Topic 在RocketMQ中,消息是发布到Topic中的,所以你需要先创建一个Topic。可以使用RocketMQ提供的命令行工具创建Topic: ``` sh bin/mqadmin updateTopic -n localhost:9876 -t testTopic ``` 4. 发送消息 使用Producer发送消息到Topic中,以下是Java代码示例: ```java import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.common.message.Message; public class Producer { public static void main(String[] args) throws Exception { DefaultMQProducer producer = new DefaultMQProducer("producer_group"); producer.setNamesrvAddr("localhost:9876"); producer.start(); Message msg = new Message("testTopic", "tagA", "Hello RocketMQ".getBytes()); producer.send(msg); producer.shutdown(); } } ``` 5. 消费消息 使用Consumer消费Topic中的消息,以下是Java代码示例: ```java import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; import org.apache.rocketmq.common.message.MessageExt; import java.util.List; public class Consumer { public static void main(String[] args) throws Exception { DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer_group"); consumer.setNamesrvAddr("localhost:9876"); consumer.subscribe("testTopic", "*"); consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { for (MessageExt msg : msgs) { System.out.println(new String(msg.getBody())); } return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); consumer.start(); System.out.println("Consumer started."); } } ``` 以上就是使用RocketMQ实现简单消息队列的步骤。当然,还有很多高级特性,比如延时消息、事务消息等,你可以自行了解和实践。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值