品优购商城项目(五)消息中间件 ActiveMQ

消息中间件用于降低各个项目模块的耦合,适用于不需要等待返回消息才能进入下一个业务环节的模块,以及实时要求性不高的业务模块。

一、JMS

  JMS(Java Messaging Service)是Java平台上有关面向消息中间件的技术规范,它便于消息系统中的Java应用程序进行消息交换,并且通过提供标准的产生、发送、接收消息的接口简化企业应用的开发。

       JMS本身只定义了一系列的接口规范,是一种与厂商无关的 API,用来访问消息收发系统。它类似于 JDBC(java Database Connectivity):这里,JDBC 是可以用来访问许多不同关系数据库的 API,而 JMS 则提供同样与厂商无关的访问方法,以访问消息收发服务。许多厂商目前都支持 JMS,包括 IBM 的 MQSeries、BEA的 Weblogic JMS service和 Progress 的 SonicMQ,这只是几个例子。 JMS 使您能够通过消息收发服务(有时称为消息中介程序或路由器)从一个 JMS 客户机向另一个 JML 客户机发送消息。消息是 JMS 中的一种类型对象,由两部分组成:报头和消息主体。报头由路由信息以及有关该消息的元数据组成。消息主体则携带着应用程序的数据或有效负载。

JMS 定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据,提供现有消息格式的一些级别的兼容性。

· TextMessage--一个字符串对象

· MapMessage--一套名称-值对

· ObjectMessage--一个序列化的 Java 对象

· BytesMessage--一个字节的数据流

· StreamMessage -- Java 原始值的数据流

JMS消息传递类型

对于消息的传递有两种类型:

一种是点对点的,即一个生产者和一个消费者一一对应;其实是只能由一个消费者消费消息。

另一种是发布/ 订阅模式,即一个生产者产生消息并进行发送后,可以由多个消费者进行接收。由于采取订阅/广播的形式,错过了广播就会接受不到消息。

 

二、消息中间件

  消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。对于消息中间件,常见的角色大致也就有Producer(生产者)、Consumer(消费者)。

常见的消息中间件产品:

1ActiveMQ

ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现。我们在本次课程中介绍 ActiveMQ的使用。

(2)RabbitMQ

AMQP协议的领导实现,支持多种场景。淘宝的MySQL集群内部有使用它进行通讯,OpenStack开源云平台的通信组件,最先在金融行业得到运用。

(3)ZeroMQ

史上最快的消息队列系统

(4)Kafka

Apache下的一个子项目 。特点:高吞吐,在一台普通的服务器上既可以达到10W/s的吞吐速率;完全的分布式系统。适合处理海量数据。

 

三、ActiveMQ简介

官方网站下载:http://activemq.apache.org/

无论是windows还是linux都是下载解压即用的,类似与zookeeper,不同的是不需要什么配置。后台管理账户和密码默认都是admin

bin目录下 activemq.bat 或者 activemq.sh 启动即可。

 

四、spring整合JMS

  ①:点对点模式

  点对点的模式主要建立在一个队列上面,当连接一个列队的时候,发送端不需要知道接收端是否正在接收,可以直接向ActiveMQ发送消息,发送的消息,将会先进入队列中,如果有接收端在监听,则会发向接收端,如果没有接收端接收,则会保存在activemq服务器,直到接收端接收消息,点对点的消息模式可以有多个发送端,多个接收端,但是一条消息,只会被一个接收端给接收到,哪个接收端先连上ActiveMQ,则会先接收到,而后来的接收端则接收不到那条消息。

消息生产者

(1)创建工程,在POM文件中引入SpringJms 、activeMQ相关依赖

<dependency>
  <groupId>org.apache.activemq</groupId>
  <artifactId>activemq-client</artifactId>
  <version>5.13.4</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jms</artifactId>
  <version>4.2.4.RELEASE</version>
</dependency>

(2)在src/main/resources下创建spring配置文件applicationContext-jms-producer.xml

<context:component-scanbase-package="cn.itcast.demo"></context:component-scan>
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
    <beanid="targetConnectionFactory"class="org.apache.activemq.ActiveMQConnectionFactory">
    <propertyname="brokerURL"value="tcp://192.168.25.135:61616"/>
    </bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
    <beanid="connectionFactory"class="org.springframework.jms.connection.SingleConnectionFactory">
    <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
    <propertyname="targetConnectionFactory"ref="targetConnectionFactory"/>
    </bean>    
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
    <beanid="jmsTemplate"class="org.springframework.jms.core.JmsTemplate">
    <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
    <propertyname="connectionFactory"ref="connectionFactory"/>
    </bean>
<!--这个是队列目的地,点对点的  文本信息-->
    <beanid="queueTextDestination"class="org.apache.activemq.command.ActiveMQQueue">
    <constructor-argvalue="queue_text"/>
    </bean>

(3)在cn.itcast.demo包下创建消息生产者类

@Component
publicclass QueueProducer {
    
    @Autowired
    private JmsTemplate jmsTemplate;
    
    @Autowired
    private Destination queueTextDestination;
    
    /**
     * 发送文本消息
     * @param text
     */
    publicvoid sendTextMessage(final String text){
        jmsTemplate.send(queueTextDestination, new MessageCreator() {            
            public Message createMessage(Session session) throws JMSException {
                returnsession.createTextMessage(text);
            }
        });        
    }
}

4)单元测试 在src/test/java创建测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext-jms-producer.xml")
publicclass TestQueue {

    @Autowired
    private QueueProducer queueProducer;
    
    @Test
    publicvoid testSend(){
        queueProducer.sendTextMessage("SpringJms-点对点");
    }    
}

 

消息消费者

(1)创建工程springjms_consumer,在POM文件中引入依赖 (同上一个工程)

 

(2)创建配置文件 applicationContext-jms-consumer-queue.xml

<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
    <beanid="targetConnectionFactory"class="org.apache.activemq.ActiveMQConnectionFactory">
    <propertyname="brokerURL"value="tcp://192.168.25.135:61616"/>
    </bean>    
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
    <beanid="connectionFactory"class="org.springframework.jms.connection.SingleConnectionFactory">
    <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
    <propertyname="targetConnectionFactory"ref="targetConnectionFactory"/>
    </bean>    
<!--这个是队列目的地,点对点的  文本信息-->
    <beanid="queueTextDestination"class="org.apache.activemq.command.ActiveMQQueue">
    <constructor-argvalue="queue_text"/>
    </bean>
    <!-- 我的监听类 -->
    <beanid="myMessageListener"class="cn.itcast.demo.MyMessageListener"></bean>
    <!-- 消息监听容器 -->
    <beanclass="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <propertyname="connectionFactory"ref="connectionFactory"/>
        <propertyname="destination"ref="queueTextDestination"/>
        <propertyname="messageListener"ref="myMessageListener"/>
    </bean>    

(3)编写监听类

publicclass MyMessageListener implements MessageListener {
    publicvoid onMessage(Message message) {
    TextMessage textMessage=(TextMessage)message;        
        try {
            System.out.println("接收到消息:"+textMessage.getText());
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

(4)创建测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext-jms-consumer-queue.xml")
publicclass TestQueue {
    @Test
    publicvoid testQueue(){
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }        
    }    
}

 

②:发布/订阅模式

消息生产者

(1)在工程springjms_producer的applicationContext-jms-producer.xml增加配置。同上需要引入ActiveMQ和JMS额依赖

<!--这个是订阅模式  文本信息-->
    <beanid="topicTextDestination"class="org.apache.activemq.command.ActiveMQTopic">
    <constructor-argvalue="topic_text"/>
    </bean>

(2)创建生产者类

@Component
publicclass TopicProducer {
    @Autowired
    private JmsTemplate jmsTemplate;
    
    @Autowired
    private Destination topicTextDestination;
    
    /**
     * 发送文本消息
     * @param text
     */
    publicvoid sendTextMessage(final String text){
        jmsTemplate.send(topicTextDestination, new MessageCreator() {            
            public Message createMessage(Session session) throws JMSException {
                returnsession.createTextMessage(text);
            }
        });        
    }
}

(3)编写测试类

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import cn.itcast.demo.TopicProducer;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext-activemq-producer.xml")
publicclass TestTopic {
    @Autowired
    private TopicProducer topicProducer;
    @Test
    publicvoid sendTextQueue(){        
        topicProducer.sendTextMessage();
    }    
}

  

消息消费者 

(1)在activemq-spring-consumer工程中创建配置文件applicationContext-jms-consumer-topic.xml。同上需要引入ActiveMQ和JMS额依赖

<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
    <beanid="targetConnectionFactory"class="org.apache.activemq.ActiveMQConnectionFactory">
    <propertyname="brokerURL"value="tcp://192.168.25.135:61616"/>
    </bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
    <beanid="connectionFactory"class="org.springframework.jms.connection.SingleConnectionFactory">
    <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
    <propertyname="targetConnectionFactory"ref="targetConnectionFactory"/>
    </bean>
<!--这个是队列目的地,点对点的  文本信息-->
    <bean id="topicTextDestination" class="org.apache.activemq.command.ActiveMQTopic">
    <constructor-arg value="topic_text"/>
    </bean>
    <!-- 我的监听类 -->
    <beanid="myMessageListener"class="cn.itcast.demo.MyMessageListener"></bean>
    <!-- 消息监听容器 -->
    <beanclass="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <propertyname="connectionFactory"ref="connectionFactory"/>
        <propertyname="destination"ref="topicTextDestination"/>
        <propertyname="messageListener"ref="myMessageListener"/>
    </bean>

(2)编写测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext-jms-consumer-topic.xml")
publicclass TestTopic {
    @Test
    publicvoidtestTopic(){
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }        
    }        
}

 

五、springboot整合JMS

1、使用内嵌服务

(1)在pom.xml中引入ActiveMQ起步依赖

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

(2)创建消息生产者

/**
 * 消息生产者
 * @author Administrator
 */
@RestController
publicclass QueueController {
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    @RequestMapping("/send")
    publicvoid send(String text){
        jmsMessagingTemplate.convertAndSend("itcast", text);
    }
}

(3)创建消息消费者

@Component
publicclass Consumer {
    @JmsListener(destination="itcast")
    publicvoid readMessage(String text){
        System.out.println("接收到消息:"+text);
    }    
}

测试:启动服务后,在浏览器执行

http://localhost:8080/send.do?text=aaaaa

即可看到控制台输出消息提示。Spring Boot内置了ActiveMQ的服务,所以我们不用单独启动也可以执行应用程序。

 

2、使用外部服务

在src/main/resources下的application.properties增加配置, 指定ActiveMQ的地址

spring.activemq.broker-url=tcp://192.168.25.135:61616

 

(1)修改QueueController.java,发送map消息

@RequestMapping("/sendmap")
    publicvoid sendMap(){
        Mapmap=new HashMap<>();
        map.put("mobile", "13900001111");
        map.put("content", "恭喜获得10元代金券");        
        jmsMessagingTemplate.convertAndSend("itcast_map",map);
    }

(2)修改Consumer.java

@JmsListener(destination="itcast_map")
    publicvoid readMap(Mapmap){
        System.out.println(map);        
    }

 

转载于:https://www.cnblogs.com/zeussbook/p/11492354.html

RocketMQ 是阿里巴巴在2012年开源的分布式消息中间件,目前已经捐赠给 Apache 软件基金会,并于2017年9月25日成为Apache 的顶级项目。作为经历过多次阿里巴巴双十一这种“超级工程”的洗礼并有稳定出色表现的国产中间件,以其高性能、低延时和高可靠等特性近年来已经也被越来越多的国内企业使用。其主要功能有1.灵活可扩展性、2.海量消息堆积能力、3.支持顺序消息、4.多种消息过滤方式、5.支持事务消息、6.回溯消费等常用功能。 RocketMQ 核心的四大组件:Name Server、Broker、Producer、Consumer ,每个组件都可以部署成集群进行水平扩展。 2、适应人群 有一定的Java基础,并且有分布式项目开发经验。 3、课程价值 可以让初学者对分布式系统解耦有一定认识,并且能够通过快速使用RocketMQ实现分布式服务的异步通信,同时本课程还会通过项目案例实战让学员对RocketMQ的应用场景有所体会,最后再通过源码角度让学员对RocketMQ的原理有所理解,不仅做到“知其然”,亦“知其所以然”。 4、课程收获 1. 理解消息中间件MQ的势和应用场景 2. 掌握RocketMQ的核心功能,以及各种消息发送案例 3. 通过电商项目深刻理解RocketMQ在使用项目中的落地应用 4. 通过RocketMQ高级功能和源码学习,对RocketMQ的技术细节和原理有更加透彻的理解 5、课程亮点 l  核心功能 n  MQ介绍 n  环境准备 n  RocketMQ高可用集群搭建 n  各种消息发送样例 l  综合练习 n  项目背景介绍 n  功能分析 n  项目环境搭建 n  下单功能,保证各服务的数据一致性 n  确认订单功能,通过消息进行数据分发 n  整体联调 l  高级功能 n  消息的存储和发送 n  消息存储结构 n  刷盘机制 n  消息的同步复制和异步复制 n  负载均衡 l  源码分析 n  路由中心NameServer n  消息生产者Producer n  消息存储 n  消息消费Consumer 6、主讲内容 章节一:核心功能 1.     快速入门 a)     MQ介绍 b)     作用 c)      注意事项 d)     各MQ产比较 2.     RocketMQ环境搭建 a)     环境准备 b)     安装RocketMQ c)      启动RocketMQ d)     测试RocketMQ e)     关闭RocketMQ 3.     RocketMQ高可用集群搭建 a)     集群各角色介绍 b)     集群搭建方式 c)      双主双从集群搭建 d)     集群监控平台 4.     各种消息发送样例 a)     同步消息 b)     异步消息 c)      单向消息 d)     顺序消息 e)     批量消息 f)      过滤消息 g)     事务消息 章节二:项目实战 1.    项目背景介绍 (1)    电商高可用MQ实战 2.    功能分析 (1)    下单功能 (2)    支付功能 3.    项目环境搭建 (1)    SpringBoot (2)    Dubbo (3)    Zookeeper (4)    RocketMQ (5)    Mysql 4.下单功能,保证各服务的数据一致性 5.确认订单功能,通过消息进行数据分发 章节三:高级功能 1. 消息的存储和发送 2. 消息存储结构 3. 刷盘机制 (1)    同步刷盘 (2)    异步刷盘 4. 消息的同步复制和异步复制 5. 负载均衡 (1)    Producer负载均衡 (2)    Consumer负载均衡 章节四:源码分析 1.     路由中心NameServer a)     NameServer架构设计 b)     NameServer启动流程 c)      NameServer路由注册和故障剔除 2.     消息生产者Producer a)     生产者启动流程 b)     生产者发送消息流程 c)      批量发送 3.     消息存储 a)     消息存储流程 b)     存储文件与内存映射 c)      存储文件 d)     实时更新消息消费队列和存储文件 e)     消息队列与索引文件恢复 f)      刷盘机制 4.     过期文件删除机制 a)     消息消费Consumer b)     消费者启动流程 c)      消息拉取 d)     消息队列负载均衡和重新分布机制 e)     消息消费过程 f)      定时消息机制 g)     顺序消息
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符 “速评一下”
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页