中间消息插件的介绍
消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。对于消息中间件,常见的角色大致也就有Producer(生产者)、Consumer(消费者)
常见的消息中间件产品:
(1)ActiveMQ
ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现。我们在本次课程中介绍 ActiveMQ的使用。
(2)RabbitMQ
AMQP协议的领导实现,支持多种场景。淘宝的MySQL集群内部有使用它进行通讯,OpenStack开源云平台的通信组件,最先在金融行业得到运用。
(3)ZeroMQ
史上最快的消息队列系统
(4)Kafka
Apache下的一个子项目 。特点:高吞吐,在一台普通的服务器上既可以达到10W/s的吞吐速率;完全的分布式系统。适合处理海量数据。
Linux安装MQ
ActiveMQ的Linux的安装
1.SecureCRT alt+p输入put e:/ActiveMQ的压缩包本地位置(目录不要带中文!!!)
2.解压缩tar zxvf apache-activemq-5.12.0-bin.tar.gz
3.对解压缩出来的文件夹,赋予权限chmod 777 apache-activemq-5.12.0
4.apache-activemq-5.12.0进入bin文件夹,继续赋予权限chmod 755 activemq目录
5.启动服务./activemq start
6.访问192.168.25.135:8161查看后台界面,用户名和密码都是admin
或者直接用FileZilla拖到root目录中,然后解压缩操作并对解压出的文件夹进行赋权操作
随记:如果是在图形化界面中,将压缩包复制到soft目录,解压。进入bin目录下,执行命令./activemq start,访问查看后台页面即可。
注意:192.168.25.135:8161是后台访问路径,在java类中调用时,使用的地址是tcp://192.168.25.128:61616(linux的路径加端口号61616)
创建SpringJmsDemo模块
1、新建Demo模块SpringJmsDemo(可以不使用骨架)
2、在pom文件中引入坐标
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.myApplication</groupId>
<artifactId>SpringJmsDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<spring.version>4.2.4.RELEASE</spring.version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.13.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
3、在resources中引入配置文件
附:
applicationContext-activemq-producer.xml全文如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd">
<context:component-scan base-package="cn.myApplication.demo"></context:component-scan>
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.25.128:61616"/> <!--这里的地址是安装上ActiveMQ的linux的ip地址-->
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean>
<!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
<!--这个是队列目的地,点对点的 文本信息-->
<bean id="queueTextDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="queue_text"/>
</bean>
<!--这个是订阅模式 文本信息-->
<bean id="topicTextDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="topic_text"/>
</bean>
</beans>
applicationContext-activemq-consumer.xml中的全文如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd">
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.25.128:61616"/>
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean>
<!--这个是队列目的地,点对点的 文本信息-->
<bean id="queueTextDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="queue_text"/>
</bean>
<!--这个是订阅模式 文本信息-->
<bean id="topicTextDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="topic_text"/>
</bean>
<!-- queue监听类 -->
<bean id="springQueueReceiver" class="cn.myApplication.demo.SpringQueueReceiver"></bean>
<!-- queue消息监听容器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />//连接信息
<property name="destination" ref="queueTextDestination" />//目标对象
<property name="messageListener" ref="springQueueReceiver" />//配置了监听类的实现类
</bean>
<!-- topic监听类 -->
<bean id="springTopicReceiver" class="cn.myApplication.demo.SpringTopicReceiver"></bean>
<!-- topic消息监听容器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="topicTextDestination" />
<property name="messageListener" ref="springTopicReceiver" />
</bean>
</beans>
SpringJMS发送Queue演示
1、创建SpringQueueSend类,用于发送消息
2、新建SpringQueueReceiver类,用于接收处理消息
3、创建一个SpringQueueSendTest类,用于发送消息
4、由于没有真正的使用spring容器,所以创建SpringQueueReceiverTest类,此处使用死循环的方式来加载配置文件
5、Queue方式,是多个消费者共同消费(处理)提供者的消息。如:提供者发送了10条消息,两个(或多个)消费者一共10条消息。
(例如:如果有两个消费者,消息一共处理的10次)
在这种方式中,可以先发消息(提供者),也可以先开监听器(消费者)。
SpringJMS发送Topic演示
1、创建一个SpringTopicSend类用来发送消息
2、新建SpringTopicReceiver类用来接收消息
3、新建SpringTopicSendTest类来调用SpringTopicSend类中的方法发送消息
4、新建SpringTopicReceiverTest类来实现消息的接收处理
5、Topic是订阅模式,在这种模式下,必须先开监听(消费者),再发送消息(提供者)。
同时发送10条消息,多个订阅者各自处理10条消息。每个消费者都要处理10条。
(例如:如果有两个消费者,消息就处理了20次)
静态页面在下架时删除(没有使用消息插件,单纯实现前天没有实现的功能)(shop-web模块)
1、在goodsController方法的updateStatus方法中的状态6的判断中,调用删除方法
2、在Page-interface模块中的接口ItemPageService中添加删除方法
3、在page-service实现类中实现删除方法
商家发送JMS消息设置
1、在shop-web模块中的resources引入配置文件
spring-activemq.xml中的全文如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd">
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.25.128:61616"/>
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
<!-- solr库添加内容的queue消息-->
<bean id="queueSolrCreateDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="solr_create"/>
</bean>
<!-- solr库删除内容的queue消息-->
<bean id="queueSolrDeleteDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="solr_delete"/>
</bean>
<!-- 生成页面的topic消息 -->
<bean id="topicPageCreateDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="page_create"/>
</bean>
<!-- 删除页面的topic消息 -->
<bean id="topicPageDeleteDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="page_delete"/>
</bean>
</beans>
2、使用中间消息插件,解耦合,删除shop-web引入的search_interface和page_interface依赖
3、在goodsController中引入JmsTemple和四个信息头配置
4、在goodsController类中的调用方法实现solr导入删除和模板的创建删除的位置改用使用功能jmsTemplate发送消息的方式。
注意:在开发中常用object。刚刚在demo中使用的是string和map。
page和search服务接收消息处理功能实现
searche服务接收消息(导入、删除solr库。只有一个solr库,所以使用queue即可)
1、在search-service模块中的resources中引入配置文件
applicationContext-activemq-consumer.xml的全文如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd">
<context:component-scan base-package="com.myApplication.search.service.impl"/>
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.25.135:61616"/>
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean>
<!-- solr库添加内容的queue消息-->
<bean id="queueSolrCreateDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="solr_create"/>
</bean>
<!-- solr库删除内容的queue消息-->
<bean id="queueSolrDeleteDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="solr_delete"/>
</bean>
<!-- 消息监听容器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="queueSolrCreateDestination" />
<property name="messageListener" ref="itemSearchCreateListener" />
</bean>
<!-- 消息监听容器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="queueSolrDeleteDestination" />
<property name="messageListener" ref="itemSearchDeleteListener" />
</bean>
</beans>
2、根据配置文件中的监听类的信息在search-service实现类中创建监听类
创建ItemSearchCreateListener监听类(需要是用Autowired调用自己的interface)
创建ItemSearchDeleteListener监听类(需要是用Autowired调用自己的interface)
page服务接收消息(创建、删除静态网页。分布式有多个服务器,所以需要使用Topic方式)
1、在page-service中引入配置文件applicationContext-activemq-consumer.xml
applicationContext-activemq-consumer.xml全文如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd">
<context:component-scan base-package="com.myApplication.page.service.impl"/>
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供-->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.25.128:61616"/>
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
</bean>
<!-- 生成页面的topic消息 -->
<bean id="topicPageCreateDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="page_create"/>
</bean>
<!-- 删除页面的topic消息 -->
<bean id="topicPageDeleteDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="page_delete"/>
</bean>
<!-- 消息监听容器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="topicPageCreateDestination" />
<property name="messageListener" ref="itemPageCreateListener" />
</bean>
<!-- 消息监听容器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="topicPageDeleteDestination" />
<property name="messageListener" ref="itemPageDeleteListener" />
</bean>
</beans>
2、在pageService实现类中根据配置文件中的信息创建监听类
创建ItemPageCreateListener监听类(需要是用Autowired调用自己的interface)
创建ItemPageDeleteListener监听类(需要是用Autowired调用自己的interface)