RocketMQ和ActiveMQ



在windows中使用MQ

rocketmq启动命令

进入到bin目录

1. 启动nameserver

start runserver.cmd

2.启动broker

start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true

window版本安装参考

pom

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!--Spring cloud alibaba 2.1.1.RELEASE--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring.cloud.alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> </dependency>

 

 

配置文件

rocketmq:
  #服务地址
  name-server: 127.0.0.1:9876
  producer:
    group: test_group
    test-topic: test_topic
  consumer:
    # 官方建议:确保同一组中的每个消费者订阅相同的主题。
    group-name: test_consumer
    test-topic: test_topic
server:
  port: 8888

 

生产者

package com.weget.rocketmq.service.impl;

import com.alibaba.fastjson.JSON;
import com.weget.rocketmq.service.AsyncMessageService;
import com.weget.util.ServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @作者 ao.lou
 * @创建时间 2020/9/17 13:21
 * @版本 1.0
 * @描述 消费服务实现
 */
@Slf4j
@Service
public class AsyncMessageServiceImpl implements AsyncMessageService {
    @Autowired
    private RocketMQTemplate template;

    @Override
    public void sendMessage(String jsonMessage, String topic) {
        asyncSendMessage(jsonMessage, topic);
    }
    private void asyncSendMessage(String message, String topic) {
        template.asyncSend(topic, MessageBuilder.withPayload(message).build(), new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("消息发送成功,信息id为{}", sendResult.getMsgId());
            }
            @Override
            public void onException(Throwable throwable) {
                log.error("消息发送失败", throwable);
            }
        });
    }

    @Override
    public ResponseEntity sendMessage(HttpServletRequest request, String topic) {
        String requestIp = ServletUtil.getRequestIp(request);
        String headerParam = ServletUtil.getHeaderParam(request);
        String allRequestParam = ServletUtil.getAllRequestParam(request);
        if (StringUtils.isBlank(allRequestParam)) {
            log.info("请求体内容为空,不发送到MQ中");
            return new ResponseEntity<>("body is null", HttpStatus.BAD_REQUEST);
        }

        String messageContent = getMessageContent(headerParam, allRequestParam);
        log.info("请求IP:{},发送到MQ中的消息内容:{}", requestIp, messageContent);

        asyncSendMessage(messageContent, topic);
        return new ResponseEntity(HttpStatus.OK);
    }

    private String getMessageContent(String headerParam, String allRequestParam) {
        Map<String, Object> map = new HashMap<>();
        map.put("header", headerParam);
        map.put("body", allRequestParam);
        return JSON.toJSONString(map);
    }
}

 

消费者: 默认集群模式,只会被一个消费掉,将其设置为广播模式,凡订阅者皆可消费

public enum MessageModel {
    BROADCASTING("BROADCASTING"),
    CLUSTERING("CLUSTERING");

    private final String modeCN;

    private MessageModel(String modeCN) {
        this.modeCN = modeCN;
    }

    public String getModeCN() {
        return this.modeCN;
    }
}
@Slf4j
@Component
@RocketMQMessageListener(topic = "${rocketmq.consumer.test-topic}",messageModel = MessageModel.BROADCASTING,
        consumerGroup = "${rocketmq.consumer.group-name}")
public class TestListener implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        log.info("获取信息:{}", message);
    }
}

 

测试类:

package com.weget.rocketmq.controller;

import com.weget.rocketmq.service.AsyncMessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * @作者 ao.lou
 * @创建时间 2020/9/17 14:39
 * @版本 1.0
 * @描述 测试发送消息
 */
@RestController
public class TestController {

    @Autowired
    AsyncMessageService asyncMessageService;

    @Value("${rocketmq.producer.test-topic}")
    private String topic;

    @GetMapping("/test")
    public void test() {
        asyncMessageService.sendMessage("123", topic);
    }
    @PostMapping("/test")
    public ResponseEntity test(HttpServletRequest request) {
        return asyncMessageService.sendMessage(request, topic);
    }
}

请求

日志信息:

广播模式:

服务A订阅广播

服务B订阅广播

activemq 启动命令

进入bin目录

apache-activemq-5.13.3\bin>activemq start

pom 关键依赖

 <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-activemq</artifactId>
		</dependency>

        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-core</artifactId>
            <version>5.7.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-pool</artifactId>
        </dependency>

 

springboot 配置文件

spring:
  activemq:
    broker-url : tcp://localhost:61616
    in-memory: true
    pool:
      #如果此处设置为true,需要加如下的依赖包,否则会自动配置失败,报JmsMessagingTemplate注入失败
      enabled: false


  jms:
    template:
      default-destination: custom-destination
    #点对点/订阅模式
    pub-sub-domain: true

 

配置类:设置改属性后,点对点/订阅模式将以myJmsListenerContainerFactory的pubSubDomain属性为准,不是必须的

@Configuration
public class MqConfig {

    /**
     * @param connectionFactory
     * @return
     */
    @Bean
    JmsListenerContainerFactory<?> myJmsListenerContainerFactory(ConnectionFactory connectionFactory) {
        SimpleJmsListenerContainerFactory simpleJmsListenerContainerFactory = new SimpleJmsListenerContainerFactory();
        simpleJmsListenerContainerFactory.setConnectionFactory(connectionFactory);
        //默认false ,单个消息被某消费者消费后其他不再消费,true订阅广播模式
        simpleJmsListenerContainerFactory.setPubSubDomain(true);

        return simpleJmsListenerContainerFactory;
    }
}

 

生产者:

package com.jms.service.impl;
import com.jms.service.ProducerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;
import javax.jms.Destination;
/***
 * 生产者
 */
@Service
public class ProducerServiceImpl implements ProducerService {
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;
    @Override
    public void sendMessage(Destination destination, final String message) {
        jmsMessagingTemplate.convertAndSend(destination, message);
    }
}

 

消费者: 可以复制多个消费者,用来测试点对点/订阅模式

package com.jms.consumer;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Component
public class Consumer {
    /**
     * 使用JmsListener配置消费者监听的队列,其中text是接收到的消息
     * ,containerFactory = "myJmsListenerContainerFactory"
      */
    @JmsListener(destination = "mytest.queue")
    public void receiveQueue(String text) {
        System.out.println("Consumer收到的报文为:" + text);
    }
}

测试类:使用时需要注意发送点对点ActiveMQQueue和发布订阅ActiveMQTopic的Destination不一样,且注意配置文件中

  jms:
    template:
      default-destination: custom-destination
    #点对点/订阅模式
    pub-sub-domain: true
pub-sub-domain的属性设置
package com.jms;

import javax.jms.Destination;

import com.jms.service.ProducerService;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MQApplication.class)
public class SpringbootJmsApplicationTest {

    @Autowired
    private ProducerService producer;

    /**
     * queue
     *
     * @throws InterruptedException
     */
    @Test
    public void test() throws InterruptedException {

        /*注意:订阅发布模式要配置
         *#   点对点/订阅模式
         *    pub-sub-domain: false
         */
        Destination destination = new ActiveMQQueue("mytest.queue");
        for (int i = 0; i < 10; i++) {
            producer.sendMessage(destination, "hello !!!" + i);
        }
    }
    /**
     * topic
     *
     * @throws InterruptedException
     */
    @Test
    public void testTopic() throws InterruptedException {
        /*注意: 订阅发布模式要配置
         *#     点对点/订阅模式
         *    pub-sub-domain: true
         */
        Destination destination = new ActiveMQTopic("mytest.queue");
        for (int i = 0; i < 10; i++) {
            producer.sendMessage(destination, "hello !!!" + i);
        }
    }
}

点对点 测试结果

Consumer收到的报文为:hello !!!0

ConsumerTopic收到:hello !!!1

Consumer收到的报文为:hello !!!2

ConsumerTopic收到:hello !!!3

Consumer收到的报文为:hello !!!4

 

订阅模式 测试结果

Consumer收到的报文为:hello !!!0

ConsumerTopic收到:hello !!!0

ConsumerTopic收到:hello !!!1

Consumer收到的报文为:hello !!!1

Consumer收到的报文为:hello !!!2

ConsumerTopic收到:hello !!!2

ConsumerTopic收到:hello !!!3

Consumer收到的报文为:hello !!!3

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值