springboot-14-springboot整合rocketmq

1. 添加rocketmq依赖

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>4.1.0-incubating</version>
</dependency>
<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-common</artifactId>
    <version>4.1.0-incubating</version>
</dependency>

2. rocketmq配置

#消费者的组名
apache.rocketmq.consumer.PushConsumer=orderConsumer
#生产者的组名
apache.rocketmq.producer.producerGroup=Producer
#nameserver地址,虚拟机的地址加 rocketmq端口号,需要linux开放该端口号
apache.rocketmq.namesrvAddr=192.168.0.126:9876
# 修改端口号,rocketmq 可视化控制台端口默认为8080
server.port=8081 

3.生产者代码

package com.example.springbootdemo5.rocketmq;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * rocketmq 消息生产者
 */
@Component
public class MsgProducer {
    
    

    /**
     * 生产者组名
     */
    @Value("${apache.rocketmq.producer.producerGroup}")
    private String producerGroup;

    /**
     * nameserver地址
     */
    @Value("${apache.rocketmq.namesrvAddr}")
    private  String namesrvAddr;

    /**
     * 发送消息使用
     */
    private DefaultMQProducer producer;

    public DefaultMQProducer getProducer(){
    
    
        return this.producer;
    }

    /**
     * 使用@PostConstruct注解进行初始化,当一个类加载进service容器之前,会调用标记了@PostConstruct注解的方法进行一些资源的初始化操作; 一般应该放在servletContext容器初始化时调用该方法,可以放在自定义监听器里面实现
     */
    @PostConstruct
    public void init(){
    
    
        producer=new DefaultMQProducer(producerGroup);
        // 指定nameserve,多个地址以分号隔开
        producer.setNamesrvAddr(namesrvAddr);
        //
        producer.setVipChannelEnabled(false);

        try {
    
    
            //Producer使用前必须初始化,且只能初始化一次
            producer.start();
        } catch (Exception e){
    
    
            e.printStackTrace();
        }
//        producer.shutdown();
    }
}

Controller代码:

package com.example.springbootdemo5.rocketmq.controller;

import com.example.springbootdemo5.rocketmq.MsgProducer;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;

@RestController
@RequestMapping("/api/v1")
public class RocketMQController {
    
    

    @Autowired
    private MsgProducer producer;

    /**
     * 模拟微信支付成功后回调/order接口,order接口将消息内容发送到rocketmq中,由消费者慢慢去消费,提高并发支付能力!
     * @param msg 要发送的消息,如支付信息
     * @param tag 消息二级分类
     * @return
     * @throws UnsupportedEncodingException
     * @throws InterruptedException
     * @throws RemotingException
     * @throws MQClientException
     * @throws MQBrokerException
     */
    @RequestMapping("/orders")
    public Object order(String msg,String tag) throws UnsupportedEncodingException, InterruptedException, RemotingException, MQClientException, MQBrokerException {
    
    

        Message message = new Message("testTopic", tag, msg.getBytes(RemotingHelper.DEFAULT_CHARSET));
        SendResult result = producer.getProducer().send(message);
        System.out.println("发送响应:MsgId:" + result.getMsgId() + ",发送状态:" + result.getSendStatus());
        return "success";
    }
}

消费者代码:

package com.example.springbootdemo5.rocketmq;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
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.remoting.common.RemotingHelper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.UnsupportedEncodingException;

@Component
public class MsgConsumer {
    
    

    @Value("${apache.rocketmq.consumer.PushConsumer}")
    private String comsumerGroup;

    @Value("${apache.rocketmq.namesrvAddr}")
    private String namesrvAddr;

    /**
     * 初始化消费者
     */
    @PostConstruct
    public void inintConsumer() {
    
    
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(comsumerGroup);

        consumer.setNamesrvAddr(namesrvAddr);
        try {
    
    
            // 设置consumer所订阅的topic和tag, *表示订阅所有tag
            consumer.subscribe("testTopic", "*");
            // 默认策略,从该队列最尾开始消费,跳过历史消息
            consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
            consumer.registerMessageListener((MessageListenerConcurrently) (list, context) -> {
    
    
                for (MessageExt messageExt : list) {
    
    
                    try {
    
    
                        // 输出消息内容
                        System.out.println("messageExt:" + messageExt);
                        String messageBody = new String(messageExt.getBody(), RemotingHelper.DEFAULT_CHARSET);
                        System.out.println("消费响应:" + messageExt.getMsgId() + ",messageBody:" + messageBody);
                    } catch (UnsupportedEncodingException e) {
    
    
                        e.printStackTrace();
                        // 消费消息失败,稍后重试
                        return ConsumeConcurrentlyStatus.RECONSUME_LATER;
                    }
                }
                // 告诉topic消息消费成功,topic会将消息移除
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            });
            consumer.start();
        } catch (MQClientException e) {
    
    
            e.printStackTrace();
        }
    }

}

启动虚拟机上的rocketmq:
(1)启动nameserver

[itcast@lch bin]$ pwd
/usr/local/messageQueue/rocketmq/bin
[itcast@lch bin]$ nohup sh mqnamesrv &
[1] 3403
[itcast@lch bin]$ nohup: ignoring input and appending output to `nohup.out'
^C
[itcast@lch bin]$ cat nohup.out

在这里插入图片描述
(2) 启动broker

[itcast@lch bin]$ nohup sh mqbroker -n 127.0.0.1:9876 &

启动rocketmq控制台:找到 rocketmq-console-ng-1.0.1.jar ,使用java -jar 命令启动

D:\CodeFromGit\rocketmq-externals-master\rocketmq-externals-master\rocketmq-console\target>java -jar rocketmq-console-ng-1.0.1.jar

linux防火墙开放9876端口:

[root@lch bin]# /sbin/iptables -I INPUT -p tcp --dport 9876 -j ACCEPT
[root@lch bin]# /etc/init.d/iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]
[root@lch bin]#

启动访问http://localhost:8081/api/v1/orders?msg=testrocketmq&tag=pay,报错,原因如下:
https://bbs.csdn.net/topics/392168188 需要同时开放端口9876 10911 10909 10912才可以连接
在这里插入图片描述
在这里插入图片描述
开放10911 10909 10912 端口后继续访问:
http://localhost:8081/api/v1/orders?msg=testrocketmq&tag=pay
在rocketmq控制台,可以看到有一条消息了:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
idea控制台打印:

发送响应:MsgId:C0A8008057A818B4AAC21E8288390000,发送状态:SEND_OK
messageExt:MessageExt [queueId=2, storeSize=173, queueOffset=0, sysFlag=0, bornTimestamp=1599401471034, bornHost=/192.168.0.128:60992, storeTimestamp=1599401471568, storeHost=/192.168.0.126:10911, msgId=C0A8007E00002A9F0000000000000000, commitLogOffset=0, bodyCRC=376694888, reconsumeTimes=0, preparedTransactionOffset=0, toString()=Message [topic=testTopic, flag=0, properties={
    
    MIN_OFFSET=0, MAX_OFFSET=1, CONSUME_START_TIME=1599401476086, UNIQ_KEY=C0A8008057A818B4AAC21E8288390000, WAIT=true, TAGS=pay}, body=12]]
消费响应:C0A8008057A818B4AAC21E8288390000,messageBody:testrocketmq

猜你喜欢

转载自blog.csdn.net/weixin_41300437/article/details/108017796