中都

风习袅袅,盈水展千华,飞檐亭角清铃响。犹记当初,你回眸莞尔,一笑倾城百日香。

博客园 首页 新随笔 联系 订阅 管理

安装流程--略;RocketMQ安装启动

启动流程:
到对应路径bin下面打开cmd输入:mqnamesrv
image

启动BROKER:start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true
image
image
启动不起来得话:把c:/user/你的用户名/里面的store里面的所有文件全部删除,再启动,成功

broker应该算是RocketMQ中比较重要的一个环节,负责消息的接收、存储、发送,搭建方式支持主从。实现高性能、高吞吐量。简言之,生产者发送的消息全部到了这里;

注意:我前面一直启动不成功,使用了很多方法都不行,最后偶然发现原因是JDK版本是32位的(也就是默认jdk在C:\Program Files (x86)),和MQ不对应造成的,重新装了64的就好了;

启动可视化程序:
image

image

demo

添加依赖:

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

代码如下:

/**
 * @ClassName: MQConfig
 * @Author: 中都
 * @Date: 2022/1/1 16:53
 * @Description: 连接RocketMQ服务器配置类,这里为了方便直接写成常量。
 */
public class MQConfig {
    /**
     *  Name Server 地址,因为是集群部署 所以有多个用 分号 隔开
     */
    public static final String NAME_SERVER = "192.168.0.196:9876";

    /**
     * 主题名称 主题一般是服务器设置好 而不能在代码里去新建topic
     * ( 如果没有创建好,生产者往该主题发送消息 会报找不到topic错误)
     * mqadmin updateTopic -c DefaultCluster -n 127.0.0.1:9876 -t topic_test
     */
    public static final String TOPIC = "topic_test";
}

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
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;
import org.springframework.stereotype.Component;

/**
 * @ClassName: Producer
 * @Author: 中都
 * @Date: 2022/1/1 17:12
 * @Description: 生产者
 */
@Slf4j
@Component
public class Producer {
    private String producerGroup = "test_producer";

    private DefaultMQProducer producer;

    public Producer() {
        start();
    }

    /**
     * 对象在使用之前必须要调用一次,只能初始化一次
     */
    public void start() {
        // 示例生产者
        producer = new DefaultMQProducer(producerGroup);
        // 不开启vip通道 开通口端口会减2
        producer.setVipChannelEnabled(false);
        // 绑定name server
        producer.setNamesrvAddr(MQConfig.NAME_SERVER);
        // 设置超过多大进行compress压缩
        producer.setCompressMsgBodyOverHowmuch(1024 * 10);
        // 设置发送失败的尝试次数。
        producer.setRetryTimesWhenSendFailed(3);
        // 设置如果返回值不是send_ok,是否要重新发送
        producer.setRetryAnotherBrokerWhenNotStoreOK(false);
        // 设置限制最大的文件大小
        producer.setMaxMessageSize(1024*50);
        // 设置默认主题对应的队列数
        producer.setDefaultTopicQueueNums(4);
        // 设置发送超时时间 ms(这个时间给长一点,不然报错sendDefaultImpl call timeout)
        producer.setSendMsgTimeout(60000);
        try {
            this.producer.start();
        } catch (MQClientException e) {
            log.info(ExceptionUtils.getStackTrace(e));
        }
    }

    /**
     * 生产者生产方法
     * @param topic 主题
     * @param tags 标签,用来给消费者进行过滤的
     * @param keys 作为key
     * @param body 发送的内容
     */
    @SneakyThrows
    public SendResult producerSendMes(String topic, String tags, String keys, String body) {
        Message message = new Message(topic, tags, keys, body.getBytes(RemotingHelper.DEFAULT_CHARSET));
        // 发送
        SendResult sendResult = this.producer.send(message);
        return sendResult;
    }


    /**
     * 生产者生产方法
     * @param topic 主题
     * @param tags 标签,用来给消费者进行过滤的
     * @param body 发送的内容
     */
    @SneakyThrows
    public SendResult producerSendMes(String topic, String tags, String body) {
        Message message = new Message(topic, tags, body.getBytes(RemotingHelper.DEFAULT_CHARSET));
        // 发送
        SendResult sendResult = this.producer.send(message);
        return sendResult;
    }

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

    /**
     * 一般在应用上下文,使用上下文监听器,进行关闭
     */
    public void shutdown() {
        this.producer.shutdown();
    }
}

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
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.Message;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;

/**
 * @ClassName: Producer
 * @Author: 中都
 * @Date: 2022/1/1 16:55
 * @Description:  消费者--一般情況下需要程序启动就开始初始化
 */
@Slf4j
@Component
public class Consumer {
    /**
     * 消费者实体对象
     */
    private DefaultMQPushConsumer consumer;

    /**
     * 消费者组
     */
    public static final String CONSUMER_GROUP = "test_consumer";

    /**
     * 通过构造函数 实例化对象
     * @throws MQClientException
     */
    public Consumer() throws MQClientException {
        consumer = new DefaultMQPushConsumer(CONSUMER_GROUP);
        consumer.setNamesrvAddr(MQConfig.NAME_SERVER);
        // 消费模式:一个新的订阅组第一次启动从队列的最后位置开始消费 后续再启动接着上次消费的进度开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        // 订阅主题和 标签( * 代表所有标签)下信息
        consumer.subscribe(MQConfig.TOPIC,"*");
        // 注册消费的监听 并在此监听中消费信息,并返回消费的状态信息
        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
            /**
             * msgs中只收集同一个topic,同一个tag,并且key相同的message
             * 会把不同的消息分别放置到不同的队列中
             */
            try {
                for(Message msg : msgs) {
                    // 消费者获取消息 这里只输出 不做后面逻辑处理
                    String body = new String(msg.getBody(), "utf-8");
                    log.info("Consumer-获取消息-主题topic为={}, 消费消息为={}", msg.getTopic(), body);
                }
            }catch (UnsupportedEncodingException e) {
                log.error("rocketMq error:{}", ExceptionUtils.getStackTrace(e));
                // 异常重试
                return ConsumeConcurrentlyStatus.RECONSUME_LATER;
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });
        consumer.start();
        log.info("消费者 启动成功=======");
    }
}

import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName: RocketMqController
 * @Author: 中都
 * @Date: 2022/1/1 17:17
 * @Description: RocketMQ测试
 */
@Slf4j
@RestController
@RequestMapping(value = "/mq")
public class RocketMqController {
    @Autowired
    private Producer producer;

    private List<String> list;

    /**
     * 初始化消息
     */
    public RocketMqController() {
        list = new ArrayList<>();
        list.add("小小");
        list.add("爸爸");
        list.add("妈妈");
        list.add("爷爷");
        list.add("奶奶");
        list.add("外公");
        list.add("外婆");
    }

    @RequestMapping("/test")
    public Object callback() throws Exception {
        // 总共发送五次消息
        for (String s : list) {
            // 创建生产信息
            SendResult sendResult = producer.producerSendMes(MQConfig.TOPIC, "testtag", ("小小一家人的称谓:" + s));
            log.info("输出生产者信息={}",sendResult);
        }
        return "成功";
    }

}

启动程序,访问得到的日志:
image

对应的可视化程序:
image

在可视化应用在添加几个消息,后台显示:
image

image

posted on 2022-01-01 17:31  中都  阅读(96)  评论(0)    收藏  举报
Live2D