ActiveMQ

Mq的分类

  • kafka
  • RabbitMQ
  • RocketMQ
  • ActiveMQ

image-20200418154040737

为什么要使用MQ

现在让我们来假设一个场景

许多学生要向教师询问问题,学生们有问题了,就会排成队

MQ特性

解耦,异步,削峰

LInux安装软件

  1. windows下载安装包 tar,用ftp软件传到linux的opt上

  2. 在opt目录下解压

    tar -zxvf 文件名
    
  3. 在根目录下新建一个myactivemq目录

mkdir myactivemq
  1. 将解压后的文件复制到myactivemq中

    #是在opt目录下,即解压文件所在的目录下进行复制
    cp -r apache-activemq-5.15.12 /myactivemq/
    
  2. 进入到/myactivemq/apache-activemq-5.15.12 /bin,启动相应文件即可

    [root@iZm5edj71ir6mgk9ys4b4fZ bin]# pwd
    /myactivemq/apache-activemq-5.15.12/bin
    [root@iZm5edj71ir6mgk9ys4b4fZ bin]# ll
    total 144
    -rwxr-xr-x 1 root root 21535 Apr 18 16:44 activemq
    -rwxr-xr-x 1 root root  6189 Apr 18 16:44 activemq-diag
    -rw-r--r-- 1 root root 16405 Apr 18 16:44 activemq.jar
    -rw-r--r-- 1 root root  5607 Apr 18 16:44 env
    drwxr-xr-x 2 root root    78 Apr 18 16:44 linux-x86-32
    drwxr-xr-x 2 root root    78 Apr 18 16:44 linux-x86-64
    drwxr-xr-x 2 root root    82 Apr 18 16:44 macosx
    -rw-r--r-- 1 root root 83820 Apr 18 16:44 wrapper.jar
    [root@iZm5edj71ir6mgk9ys4b4fZ bin]# ./activemq start
    
  3. activemq的默认端口是61616,查询activemq是否启动

    #第一种查询方法
    [root@iZm5edj71ir6mgk9ys4b4fZ bin]# ps -ef|grep activemq|grep -v grep
    root     27892     1  1 16:47 pts/0    00:00:06 /usr/bin/java -Xms64M -Xmx1G -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=/myactivemq/apache-activemq-5.15.12//conf/login.config -Dcom.sun.management.jmxremote -Djava.awt.headless=true -Djava.io.tmpdir=/myactivemq/apache-activemq-5.15.12//tmp -Dactivemq.classpath=/myactivemq/apache-activemq-5.15.12//conf:/myactivemq/apache-activemq-5.15.12//../lib/: -Dactivemq.home=/myactivemq/apache-activemq-5.15.12/ -Dactivemq.base=/myactivemq/apache-activemq-5.15.12/ -Dactivemq.conf=/myactivemq/apache-activemq-5.15.12//conf -Dactivemq.data=/myactivemq/apache-activemq-5.15.12//data -jar /myactivemq/apache-activemq-5.15.12//bin/activemq.jar start
    #第二种查询方法
    [root@iZm5edj71ir6mgk9ys4b4fZ bin]#  netstat -anp|grep 61616
    tcp6       0      0 :::61616                :::*                    LISTEN      27892/java   
    #第三种查询方法
    [root@iZm5edj71ir6mgk9ys4b4fZ bin]# lsof -i:61616
    COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    java    27892 root  132u  IPv6 545080      0t0  TCP *:61616 (LISTEN)
    
  4. 带日志方式的启动

    [root@iZm5edj71ir6mgk9ys4b4fZ bin]# ./activemq start > /myactivemq/myrunmq.log
    

ActiveMQ

两大模式特性

队列和主题,统称为目的地

  • 在点对点对的消息传送域中,目的地被称为队列

    image-20200419100030385

  • 在发布订阅的消息传送域中,目的地被称为主题

    image-20200419100041443

队列

image-20200419095927210

主题

image-20200419100306788

主题和队列的区别

image-20200419101630425

连接到ActiveMQ的管理界面

注意:activemp的那个后台管理界面不是默认的服务端口61616,而是8161

  1. 首先启动activemq服务

    [root@iZm5edj71ir6mgk9ys4b4fZ bin]# ./activemq start
    #注意:在activemq的bin目录下启动
    
  2. 浏览器访问 Ip地址:8161

    我的是这样的

    http://47.104.109.159:8161/
    

    正确访问出现如下界面

    image-20200419090442832

  3. 点击以下内容,会提示输入账号和密码,默认账号密码都为admin

    image-20200419090628159

  4. 正确进入后

  5. image-20200419090702483

java向activemq队列中写入数据

生产者

package com.sun.activemq;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class JmsProducer {
    public static final String ACTIVEMQ_URL="tcp://47.104.109.159:61616";
    public static final String QUEUE_NAME="queue";
    public static void main(String[] args) throws JMSException {

        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        //两个参数,第一个是事务,第二个是签收机制
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Queue queue = session.createQueue(QUEUE_NAME);

        MessageProducer producer = session.createProducer(queue);
        for (int i = 0; i < 3; i++) {
            TextMessage textMessage = session.createTextMessage("创建了第" + i++ + "个消息");
            producer.send(textMessage);
        }
        producer.close();
        session.close();
        connection.close();
        System.out.println("消息发送到MQ完成");
    }
}

消费者

package com.sun.activemq;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;
import java.io.IOException;

public class JmsConsumer {
    public static final String ACTIVEMQ_URL="tcp://47.104.109.159:61616";
    public static final String QUEUE_NAME="queue";
    public static void main(String[] args) throws JMSException, IOException {
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        //两个参数,第一个是事务,第二个是签收机制
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Queue queue = session.createQueue(QUEUE_NAME);
        //创建消费者
        MessageConsumer consumer = session.createConsumer(queue);
        //同步阻塞方法receive()
        //订阅者通过接口调用消费者的resive方法来接收消息,receive方法能够在接收到消息之前
        //(或超时之前)会一直阻塞
//        while (true)
//        {
//            //生成的数据类型要和接收的数据类型一致
//            TextMessage message = (TextMessage) consumer.receive(4000L);
//            if(message!=null)
//            {
//                System.out.println("消费者接收到消息"+message.getText());
//            }
//            else {
//                break;
//            }
//        }
//        consumer.close();
//        session.close();
//        connection.close();
        //第二种:通过消息监听的方式来消费消息
        //异步非阻塞监听
        //默认采用轮询分发的方式来消费消息
        //例如:当已经有两个消费者的时候,这时候生产六条消息,会被两个消费者平均消费掉
        //1号消费者消费代号为1,3,5消息,2号消费者消费代号为2,4,6的消息

        consumer.setMessageListener(new MessageListener()
        {
            @Override
            public void onMessage(Message message) {
                if(null!=message&&message instanceof TextMessage)
                {
                    TextMessage textMessage=(TextMessage)message;
                    try {
                        System.out.println("消费者接收到消息"+textMessage.getText());
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                }

            }
        });
        //保证控制台不消失
        System.in.read();
        consumer.close();
        session.close();
        connection.close();
    }
}

主题

注意:先订阅再发布才可以正常发送消息!先发布再订阅的话,消息是废消息,订阅者接收不到订阅时间之前发布的消息

生产者

package com.sun.activemq;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class JmsProducer_topic {
    public static final String ACTIVEMQ_URL="tcp://47.104.109.159:61616";
    public static final String TOPIC_NAME="topic";
    public static void main(String[] args) throws JMSException {

        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        //两个参数,第一个是事务,第二个是签收机制
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Topic topic = session.createTopic(TOPIC_NAME);

        MessageProducer producer = session.createProducer(topic);
        for (int i = 1; i <= 3; i++) {
            TextMessage textMessage = session.createTextMessage("创建了第" + i + "个Topic消息");
            producer.send(textMessage);
        }
        producer.close();
        session.close();
        connection.close();
        System.out.println("Topic消息发送到MQ完成");
    }
}

消费者

package com.sun.activemq;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;
import java.io.IOException;

public class JmsConsumer_topic {
    public static final String ACTIVEMQ_URL="tcp://47.104.109.159:61616";
    public static final String TOPIC_NAME="topic";
    public static void main(String[] args) throws JMSException, IOException {
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();
        //两个参数,第一个是事务,第二个是签收机制
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Topic topic = session.createTopic(TOPIC_NAME);
        //创建消费者
        MessageConsumer consumer = session.createConsumer(topic);
        //同步阻塞方法receive()
        //订阅者通过接口调用消费者的resive方法来接收消息,receive方法能够在接收到消息之前
        //(或超时之前)会一直阻塞
//        while (true)
//        {
//            //生成的数据类型要和接收的数据类型一致
//            TextMessage message = (TextMessage) consumer.receive(4000L);
//            if(message!=null)
//            {
//                System.out.println("消费者接收到消息"+message.getText());
//            }
//            else {
//                break;
//            }
//        }
//        consumer.close();
//        session.close();
//        connection.close();
        //第二种:通过消息监听的方式来消费消息
        //异步非阻塞监听
        //默认采用轮询分发的方式来消费消息
        //例如:当已经有两个消费者的时候,这时候生产六条消息,会被两个消费者平均消费掉
        //1号消费者消费代号为1,3,5消息,2号消费者消费代号为2,4,6的消息
        consumer.setMessageListener((message)->{
            if(null!=message&&message instanceof TextMessage)
            {
                TextMessage textMessage=(TextMessage)message;
                try {
                    System.out.println("消费者接收到消息"+textMessage.getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });
        //保证控制台不消失
        System.in.read();
        consumer.close();
        session.close();
        connection.close();
    }
}

spring整合ActiveMQ

1. 导入依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-all -->
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-all</artifactId>
        <version>5.15.12</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.xbean/xbean-spring -->
    <dependency>
        <groupId>org.apache.xbean</groupId>
        <artifactId>xbean-spring</artifactId>
        <version>4.16</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
        <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
        <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>2.0.0-alpha1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.10.3</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-jms -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-pool -->
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-pool</artifactId>
        <version>5.15.12</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/aspectj/aspectjrt -->
    <dependency>
        <groupId>aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.5.4</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.5</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/cglib/cglib -->
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.3.0</version>
    </dependency>
</dependencies>

2. 配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://camel.apache.org/schema/spring
       http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
    <!--设置扫描的包-->
    <context:component-scan base-package="com.sun.spring"/>
    <!--设置连接ActiveMQ的服务器的地址-->
    <bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
        <property name="connectionFactory">
            <bean class="org.apache.activemq.ActiveMQConnectionFactory">
                <property name="brokerURL" value="tcp://47.104.109.159:61616"/>
            </bean>
        </property>
        <property name="maxConnections" value="100"/>
    </bean>
    <!--设置连接ActiveMQ的连接模式为队列-->
    <bean id="destinationQueue" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg index="0" value="spring-active-queue"/>
    </bean>
    <!--设置连接ActiveMQ的连接模式为主题-->
    <bean id="destinationTopic" class="org.apache.activemq.command.ActiveMQTopic">
        <constructor-arg index="0" value="spring-active-topic"/>
    </bean>
    <!--spring提供的jms的工具类,它可以进行消息的发送、接收等-->
    <bean id="jmdTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="jmsFactory"/>
        <!--队列还是主题,只需要在这里设置接口 ref引用的那个id里面的类是对应的队列或者主题即可-->
        <property name="defaultDestination" ref="destinationTopic"/>
        <property name="messageConverter">
            <bean class="org.springframework.jms.support.converter.SimpleMessageConverter"/>
        </property>
    </bean>
</beans>

3. 生产者

注意:主题的话,先启动消费者,再启动生产者

package com.sun.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;

import javax.jms.*;

@Service
public class springMQ_producer {
    @Autowired
    private JmsTemplate jmsTemplate;

    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        springMQ_producer producer= (springMQ_producer) context.getBean("springMQ_producer");
        producer.jmsTemplate.send(new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                TextMessage textMessage = session.createTextMessage("spring-active");
                return textMessage;
            }
        });
        System.out.println("send over");
    }
}

4. 消费者

package com.sun.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;

@Service
public class springMQ_consumer {
    @Autowired
    private JmsTemplate jmsTemplate;
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        springMQ_consumer consumer= (springMQ_consumer) context.getBean("springMQ_consumer");
        String retValue = (String) consumer.jmsTemplate.receiveAndConvert();
        System.out.println("消费者收到的消息"+retValue);
    }
}

5. 消息模型

不管是使用队列还是主题,只需要在配置文件中改就可以了,生产者和消费者不需要要改变

6. 实现不启动消费者

不启动消费者,直接通过配置监听完成

1. 加入配置文件

    <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="jmsFactory"/>
        <!--与id为jmdTemplate中的name为defaultDestination的 ref一致即可-->
        <property name="destination" ref="destinationTopic"/>
        <property name="messageListener" ref="myMessageListener"/>
    </bean>

2. 加入一个类继承MessageListener接口

package com.sun.spring;

import org.springframework.stereotype.Component;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@Component
public class myMessageListener implements MessageListener {
    @Override
    public void onMessage(Message message) {
        if(null!=message&& message instanceof TextMessage)
        {
            TextMessage textMessage= (TextMessage) message;
            try {
                System.out.println(textMessage.getText());
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }
}

3. 直接启动生产者即可

MQ命令

./activemq start
./activemq restart
./activemq stop
#查询activemq是否启动的三种方式
lsof -i:61616
netstat -anp|grep 61616
ps -ef|grep activemq|grep -v grep
#关闭防火墙
service iptables status
service iptables start
service iptables stop

JMS

JMS开发步骤

image-20200419095617417

什么是javaEE

image-20200419102236196

什么是JMS

image-20200419102339521

jMS的组成和结构

  • 生产者
  • 消费者
  • 消息
  • mq

Message

消息头

常用的属性

JMSDestination

分为队列和属性

JMSDeliveryMode

image-20200419103727208

JMSException

image-20200419104133271

JMSPriority

image-20200419104221138

JMSMessageID

消息属性

消息属性是什么?

image-20200419105517282

如果需要去除消息头字段以外的值,可以使用消息属性

识别/去重/重点标注等操作非常有用的方法

消息体

消息体:封装具体的消息数据

注意:发送的消息和接收的消息,消息格式必须相同

五种消息格式

  • TestMessage
  • MapMessage
  • BytesMessage
  • StreamMessage
  • ObjectMessage

JMS的可靠性

持久性

默认是持久化

image-20200419110514337

队列的持久性

image-20200419111042054

主题的持久性

如果消费者已经订阅了,即使消费者宕机了,也会等消费者重新上线之后,将消息发送过去

生产者

package com.sun.activemq;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class JmsProducer_topic {
    public static final String ACTIVEMQ_URL="tcp://47.104.109.159:61616";
    public static final String TOPIC_NAME="topic";
    public static void main(String[] args) throws JMSException {

        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        Connection connection = activeMQConnectionFactory.createConnection();

        //两个参数,第一个是事务,第二个是签收机制
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Topic topic = session.createTopic(TOPIC_NAME);
        MessageProducer producer = session.createProducer(topic);
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        //改动的地方
        connection.start();
        for (int i = 1; i <= 3; i++) {
            TextMessage textMessage = session.createTextMessage("创建了第" + i + "个Topic消息");
            producer.send(textMessage);
        }
        producer.close();
        session.close();
        connection.close();
        System.out.println("Topic消息发送到MQ完成");
    }
}

事务transaction

事务偏生产者,签收偏消费者

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

生产者

  • false,直接用send提交即可
  • true,在send提交之后,要用session.commit提交才行

消费者

  • false,直接可以消费
  • true,必须用session.commit提交,否则会出现消息被重复消费的情况

签收

非事务情况下的签收

  • 自动签收(默认) AUTO_ACKNOWLEDGE
  • 手动签收
    • CLIENT_ACKNOWLEDGE
    • 客户端调用acknowledge方法手动签收
  • 允许重复消息 DUPS_OK_ACKNOWLEDGE

事务

  • 生产事务开启,只有commit后才能将全部消息变为已消费;否则消息会被重复消费
  • 消费生产者
  • 消费消费者

签收和事务的关系

  • 在事务性会话中,当一个事务被成功提交则消息被自动签收,如果事务回滚,则消息会被再次消费
  • 非事务性会话中,消息何时被确认取决于创建会话时的应答模式(acknowledge mode)

点对点总结

image-20200419191900727

发布订阅总结

image-20200419192013237

消息队列的比较

image-20200419102724487

发布订阅

Broker

是什么

相当于一个ActiveMQ的服务器实例

说白了,Broker其实就是用代码的形式启动ActiveMQ将MQ嵌入到java代码中,以便随时用随时启动,在用的时候再去启动这样能节省了资源,也保证了可靠性

配置多个实例

// activemq/conf目录下
[root@iZm5edj71ir6mgk9ys4b4fZ conf]# cp activemq.xml activemq02.xml
// activemq/bin目录下
./activemq start xbean:file:/myactivemq/apache-activemq-5.15.12/conf/activemq02.xml

代码实现

注意:需要到导入一个这样的包,否则可能会报错

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.3</version>
        </dependency>
public class EmbedBroker {
    public static void main(String[] args) throws Exception {
        BrokerService brokerService = new BrokerService();
        brokerService.setUseJmx(true);
        brokerService.addConnector("tcp://localhost:61616");
        brokerService.start();
    }
}

生产者和消费者正常实现,只需要访问地址改为

tcp://localhost:61616即可

posted @ 2020-10-27 21:46  shyshare  阅读(154)  评论(0)    收藏  举报