前言
项目中需要对用户上传的文件进行转换(WORD/EXCEL 转 PDF),但用户上传的文件可能很大,不能及时响应,这里想着把MQ集成到项目中,用队列的方式在服务器端完成文件转换,使提交报告的请求迅速响应
这里做个笔记,方便以后copy直接使用
消息中间件应用场景
- 服务的异步处理
- 应用的解耦
- 流量的削峰
集成到Sping
截至目前(2019-11-12)activeMQ最新版是5.15.10,下载后发现需要spring版本4.3
结合项目当前4.2.9的Spring版本,选择了ActiveMQ 5.11.1,这样就不需要做项目的版本升级了,上代码了:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd
">
<!-- 1、实例化Mq链接工厂 -->
<amq:connectionFactory brokerURL="tcp://192.168.2.4:61616"
userName="admin" password="admin" id="amqConnectionFactory"></amq:connectionFactory>
<!-- 2、实例化Mq的连接池 -->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="connectionFactory" ref="amqConnectionFactory"></property>
<property name="maxConnections" value="10"></property>
</bean>
<!-- 3、实例化spring提供的链接,将mq提供的原始的链接进行封装 -->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="sessionCacheSize" value="10"></property>
<!-- 异常后重置连接 -->
<property name="reconnectOnException" value="true"/>
<property name="targetConnectionFactory" ref="amqConnectionFactory"></property>
</bean>
<!-- 4、实例化jmsTemplate对象 -->
<bean id="jsmTemplate" class="org.springframework.jms.core.JmsTemplate">
<!-- 注入Spring提供的链接工厂对象 -->
<property name="connectionFactory" ref="connectionFactory"></property>
<!-- 指定默认队列的名称 -->
<property name="defaultDestinationName" value="fileConvert2Pdf"></property>
</bean>
<!-- 这里使用点对点模式(仅针对文件转换的队列消息做处理)
注册监听器容器
acknowledge : 消息确认机制
container-type : 容器类型 default|simple
simple : SimpleMessageListenerContainer最简单的消息监听器容器,
只能处理固定数量的JMS会话,且不支持事务。
default : DefaultMessageListenerContainer是一个用于异步消息监听器容器 ,
且支持事务
destination-type : 目的地类型, 使用队列作为目的地.
connection-factory :
连接工厂, spring-jms使用的连接工厂,必须是spring自主创建的
不能使用三方工具创建的工厂. 如: ActiveMQConnectionFactory.
-->
<jms:listener-container acknowledge="auto" destination-type="queue" container-type="default" connection-factory="connectionFactory">
<!-- 在监听器容器中注册某监听器对象.destination 设置目的地命名 ref 指定监听器对象 -->
<jms:listener destination="fileConvert2Pdf" ref="mqHelper" />
</jms:listener-container>
</beans>
这里定义的 mqHelper 需要实现 javax.jms.MessageListener 接口进行监听,做消息处理
完成此配置后可直接通过引用jmsTemplate进行消息发送
jmsTemplate.send(new MessageCreator() {});
注意:
- 发布订阅模式,必须先启动订阅者,再启动发布者,否则会收不到消息
- 使用监听进行消费,不能关闭资源连接
- 发送对象消息,对象必须实现序列化接口
数据持久化
这里需要修改activemq.xml的两个地方:
<!-- MySQLDataSource -->
<bean id="mysqlDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/ilis?relaxAutoCommit=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<persistenceAdapter>
<!-- <kahaDB directory="${activemq.data}/kahadb"/> -->
<jdbcPersistenceAdapter dataSource="#mysqlDataSource" createTablesOnStartup="true" useDatabaseLock="true" />
</persistenceAdapter>
将相关jar包拷贝到mq的lib目录下:
commons-dbcp-1.4
mysql-connector-java-8.0.9
commons-pool-1.6
至此数据持久化配置完毕,启动MQ后数据库会生成3个active打头的表