13、SpringBoot整合ActiveMQ

参考

博客:https://zhuanlan.zhihu.com/p/21649950

视频:https://www.bilibili.com/video/BV164411G7aB?p=1

消息队列

       假设我们现在需要做一个分布式电商系统,我们有用户服务、商品信息服务、订单服务、积分统计服务。服务之间相互调用,相互依赖。例如订单创建完成后,可能会做一下后续的操作:发送积分、短信通知等。创建订单可能很容易,也很快,但是发送积分、短信通知可更依赖网络环境,比较费时。双十一要来了,

      订单服务的压力越来越大,这个时候就需要将订单服务和一些后续的服务拆分下来。订单服务只管处理订货,后续的任务就和他无关了,他无需等待缓慢的积分服务、短信服务。
      消息队列就可以很好的充当这一媒介,或者说是一个缓冲。订单服务产生的订单信息发送到消息队列中即可,积分服务、短信服务可以不慌不忙地处理消息队列中待处理的订单,这就是一个解耦的过程。

      通过耗费两次RPC的时间的代价(不考虑一致性的话),来缓解了上游服务(订单)的压力,达到了解耦、削峰的目的。

      ActiveMQ有两种模式:队列模式、topic订阅模式。队列模式,如果多个人订阅,生产出来的消息只会被一个人消费。订阅模式,订阅的所有人都会收到生产者发出来的消息。

安装

官网:http://activemq.apache.org/components/classic/download/

下载linux版本,上传到服务器上,放在/usr/lcoal  或者/opt目录都可以。

解压 tar -zxvf 文件名

进入bin目录

 ./activemq start

 

需要提前装好jdk,配好环境变量,不然启动的时候会报错:

ERROR: Configuration variable JAVA_HOME or JAVACMD is not defined correctly.
       (JAVA_HOME='', JAVACMD='java')

启动完成后,可以查看61616端口的占用情况

 netstat -anp|grep 61616
 
 #或者
 
 lsof -i:61616

访问地址

http://ip:8161/admin/

初始密码

admin

admin

常用命令

启动

./activemq start

重启

./activemq restart

停止

./activemq stop

指定日志输出路径

./activemq start > /opt/activeMQ/activeMQ.log

远程访问

默认只能本机访问,如果是远程访问需要改配置文件。

host改成0.0.0.0表示允许所有ip访问。(如果在一个网段,也可以改成你自己电脑的ip)

    <bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
             <!-- the default port number for the web console -->
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8161"/>
    </bean>

整合SpringBoot

队列

生产者

依赖

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

配置文件

spring:
  activemq:
    broker-url: tcp://ip:61616
    user: admin
    password: admin
  jms:
    pub-sub-domain: false #false=队列(默认值),true=订阅

queueName: dayrain-queue

配置类

config目录下

@Component
@EnableJms
public class ConfigBean {

    @Value("${queueName}")
    private String queueName;

    @Bean
    public Queue queue() {
        return new ActiveMQQueue(queueName);
    }

}

 produce

@Component
public class QueueProduce {

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Autowired
    private Queue queue;

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");

    @Scheduled(fixedDelay = 3000)
    public void produceMessage() {
        jmsMessagingTemplate.convertAndSend(queue, "发送了一条消息 at: " + simpleDateFormat.format(new Date()));
    }
}

启动类

@SpringBootApplication
@EnableScheduling
public class ActivemqBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(ActivemqBootApplication.class, args);
    }

}

 

测试类

@SpringBootTest
@EnableScheduling
public class TestActiveMQ {

    @Resource
    private QueueProduce queueProduce;

    @Test
    public void send() {
        queueProduce.produceMessage();
    }
}

消费者

与生产者基本一致,部分配置要改下

spring:
  activemq:
    broker-url: tcp://175.24.15.179:61616
    user: admin
    password: admin
  jms:
    pub-sub-domain: false #false=队列(默认值),true=订阅

queueName: dayrain-queue

消息处理类

@Component
public class QueueConsumer {

    @JmsListener(destination = "${queueName}")
    public void receive(TextMessage textMessage) throws JMSException {
        System.out.println("消费者收到消息:" + textMessage.getText());
    }
}

topic订阅

生产者

依赖同上

配置文件

spring:
  activemq:
    broker-url: tcp://175.24.15.179:61616
    user: admin
    password: admin
  jms:
    pub-sub-domain: true #false=队列(默认值),true=订阅

topicName: dayrain-topic

配置类

@Component
@EnableJms
public class ConfigBean {

    @Value("${topicName}")
    private String topicName;

    @Bean
    public Topic topic() {
        return new ActiveMQTopic(topicName);
    }

}

produce

@Component
public class TopicProduce {

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Autowired
    private Topic topic;

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");

    @Scheduled(fixedDelay = 3000)
    public void produceMessage() {
        jmsMessagingTemplate.convertAndSend(topic, "发送了一条topic消息 at: " + simpleDateFormat.format(new Date()));
    }
}

启动类

@SpringBootApplication
@EnableScheduling
public class ActivemqBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(ActivemqBootApplication.class, args);
    }

}

 

测试类(运行的时候启动测试类)

@SpringBootTest
@EnableScheduling
public class TestActiveMQ {

    @Resource
    private TopicProduce topicProduce;

    @Test
    public void send() {
        topicProduce.produceMessage();
    }
}

消费者

配置文件

server:
  port: 8081
spring:
  activemq:
    broker-url: tcp://175.24.15.179:61616
    user: admin
    password: admin
  jms:
    pub-sub-domain: true #false=队列(默认值),true=订阅

topicName: dayrain-topic

消息处理类

@Component
public class TopicConsumer {

    @JmsListener(destination = "${topicName}")
    public void receive(TextMessage textMessage) throws JMSException {
        System.out.println("消费者收到消息:" + textMessage.getText());
    }
}

运行启动springboot即可。

目录结构

生产者

消费者

 

posted @ 2020-11-05 22:09  小楼夜听雨QAQ  阅读(351)  评论(0)    收藏  举报