Spring使用Rabbitmq (简单使用)
1、pom.xml jar包引用
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.amqp/spring-amqp -->
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-amqp</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client -->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.6.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
</dependency>
</dependencies>
2、resouces 下面的log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info" monitorInterval="30">
<!--先定义所有的appender -->
<appenders>
<!--这个输出控制台的配置 -->
<Console name="Console" target="SYSTEM_OUT">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" />
<!--这个都知道是输出日志的格式 -->
<PatternLayout pattern="[%-5p] %d{yyyy-MM-dd HH:mm:ss} method:%l%n%m%n"/>
</Console>
</appenders>
<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效 -->
<loggers>
<!--建立一个默认的root的logger -->
<root level="info">
<appender-ref ref="Console" />
</root>
</loggers>
</Configuration>
3、resouces 下面的spring/rabbitmq-context.xml
<?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:rabbit="http://www.springframework.org/schema/rabbit"
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://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.tandaima.rabbitmq.spring"/>
<!--引用属性文件-->
<context:property-placeholder file-encoding="utf-8" location="classpath:rabbitmq.properties"/>
<bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
<property name="host" value="${mq.host}" />
<property name="port" value="${mq.port}" />
<property name="username" value="${mq.username}" />
<property name="password" value="${mq.password}" />
<property name="virtualHost" value="${mq.virtual-host}" />
<!-- 缓存模式 CONNECTION CHANNEL,默认的缓存模式是CHANNEL。
当缓存模式是 CONNECTION时, 队列的自动声明等等 (参考 the section called “Automatic Declaration of Exchanges, Queues and Bindings”) 将不再支持。
在框架(如. RabbitTemplate) 中使用的通道将会可靠地返回到缓存中.如果在框架外创建了通道 (如.直接访问connection(s)并调用 createChannel() ),
你必须可靠地返回它们(通过关闭),也许需要在 finally 块中以防止耗尽通道.
-->
<property name="cacheMode" value="CHANNEL"/>
<!-- 默认通道缓存25,多线程环境中,较小的缓存意味着通道的创建和关闭将以很高的速率运行.加大默认缓存大小可避免这种开销
如果达到了限制,调用线程将会阻塞,直到某个通道可用或者超时, 在后者的情况中,将抛出 AmqpTimeoutException异常.-->
<property name="channelCacheSize" value="10"/>
<!-- channelCheckoutTimeout属性. 当此属性的值大于0时, channelCacheSize会变成连接上创建通道数目的限制. -->
<!--毫秒为单位-->
<property name="channelCheckoutTimeout" value="200"/>
<!-- 发布确认必须配置在CachingConnectionFactory上 -->
<property name="publisherConfirms" value="true"/>
</bean>
<!-- 同步访问rabbitmq-->
<bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate">
<constructor-arg name="connectionFactory" ref="connectionFactory"/>
<!--消息确认回调 -->
<property name="confirmCallback" ref="confirmCallback"/>
<!--消息回滚回调 -->
<property name="returnCallback" ref="returnCallback"/>
</bean>
<!--通过指定下面的admin信息,当前producer中的exchange和queue会在rabbitmq服务器上自动生成 -->
<rabbit:admin id="connectAdmin" connection-factory="connectionFactory" /> <!--confirmCallback回调-->
<bean id="confirmCallback" class="com.tandaima.rabbitmq.spring.service.ConfirmCallBackListener"/>
<!--returnCallback回调-->
<bean id="returnCallback" class="com.tandaima.rabbitmq.spring.service.ReturnCallBackListener"/>
<!-- 队列声明 :
durable:true、false true:在服务器重启时,能够存活
exclusive :当连接关闭后是否自动删除队列;是否私有队列,如果私有,其他通道不能访问当前队列
autodelete:当没有任何消费者使用时,自动删除该队列 --> <!--定义交易记录队列 -->
<bean id="transactionRecordMessage" class="com.tandaima.rabbitmq.spring.receive.TransactionRecordMessage"/>
<rabbit:queue name="transaction.record.queue" durable="true" exclusive="false" auto-delete="false"/>
<!-- 定义direct exchange,绑定spring.queue -->
<rabbit:direct-exchange name="${mq.exchange-transaction}" declared-by="connectAdmin" durable="true">
<rabbit:bindings>
<rabbit:binding queue="transaction.record.queue" key="${mq.routing-key-transaction-record}"/>
</rabbit:bindings>
</rabbit:direct-exchange>
<!-- 队列 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象 -->
<!--acknowledge 消费者手工确认消息-->
<rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual">
<rabbit:listener queues="transaction.record.queue" ref="transactionRecordMessage" />
</rabbit:listener-container> <!--定义交易K线相关队列 -->
<bean id="transactionKlineMessage" class="com.tandaima.rabbitmq.spring.receive.TransactionKlineMessage"/>
<rabbit:queue name="transaction.kline.queue" durable="true" exclusive="false" auto-delete="false"/>
<rabbit:direct-exchange name="${mq.exchange-transaction}" declared-by="connectAdmin" durable="true">
<rabbit:bindings>
<rabbit:binding queue="transaction.kline.queue" key="${mq.routing-key-transaction-kline}"/>
</rabbit:bindings>
</rabbit:direct-exchange>
<rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual">
<rabbit:listener queues="transaction.kline.queue" ref="transactionKlineMessage" />
</rabbit:listener-container>
</beans>
4、resouces 下面的rabbitmq.properties
mq.host=127.0.0.1
mq.username=lpz
mq.password=lpz
mq.port=5672
mq.virtual-host=/
#交易记录队列key
mq.routing-key-transaction-record=transaction.record.queue.key
#交易K线队列key
mq.routing-key-transaction-kline=transaction.kline.queue.key
#交易相关交换机
mq.exchange-transaction=transaction.exchange
5、定义消息发送类MessageProducer
package com.tandaima.rabbitmq.spring.service; import org.apache.log4j.Logger;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; @Service
public class MessageProducer { private Logger logger= Logger.getLogger(MessageProducer.class); @Autowired
private AmqpTemplate amqpTemplate; /**
* 发送消息到队列
* @param exchange 通道名称
* @param queueKey 队列key
* @param content 内容
*/
public void sendMessage(String exchange,String queueKey,Object content){
try {
amqpTemplate.convertAndSend(exchange,queueKey, content);
}catch (Exception e){
logger.error("RabbitMQ发送消息异常==>"+e.getMessage());
}
}
}
6、消息发送成功回调类ConfirmCallBackListener
package com.tandaima.rabbitmq.spring.service;
import org.apache.log4j.Logger;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Configuration; @Configuration
public class ConfirmCallBackListener implements RabbitTemplate.ConfirmCallback{
private Logger logger=Logger.getLogger(ConfirmCallBackListener.class);
/**
* CorrelationData 是在发送消息时传入回调方法的参数,可以用于区分消息对象。 CorrelationData对象中只有一个属性 String id。
* 通过这个参数,我们可以区分当前是发送哪一条消息时的回调,并通过ack参数来进行失败重发功能
*
* @param correlationData 回调的相关数据.
* @param ack true for ack, false for nack
* @param cause 专门给NACK准备的一个可选的原因,其他情况为null。
*/
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
logger.info("exchange确认"+ack);
}
}
7、消息发送失败回调类ReturnCallBackListener
package com.tandaima.rabbitmq.spring.service; import org.apache.log4j.Logger;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Configuration; @Configuration
public class ReturnCallBackListener implements RabbitTemplate.ReturnCallback{
private Logger logger=Logger.getLogger(ReturnCallBackListener.class);
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
logger.error("失败确认:"+message+" | "+replyCode+" | "+replyText+" | "+exchange+" | "+routingKey);
}
}
8、定义TransactionKlineMessage
package com.tandaima.rabbitmq.spring.receive; import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import org.apache.log4j.Logger;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.context.annotation.Configuration; @Configuration
public class TransactionKlineMessage implements ChannelAwareMessageListener {
private Logger logger=Logger.getLogger(TransactionKlineMessage.class);
@Override
public void onMessage(Message message, Channel channel) throws Exception {
try{
String str = new String(message.getBody());
logger.info("接收到交易K线信息==>:" + str);
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}catch(Exception e){
logger.error("接收到交易K线信息异常回滚消息到队列中==>"+e.getMessage());
//消息回滚通道
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,true);
}
} @Override
public void onMessage(Message message) {
logger.info("消息==>"+JSON.toJSONString(message));
}
}
9、定义TransactionRecordMessage
package com.tandaima.rabbitmq.spring.receive; import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import org.apache.log4j.Logger;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.context.annotation.Configuration; @Configuration
public class TransactionRecordMessage implements ChannelAwareMessageListener {
private Logger logger=Logger.getLogger(TransactionRecordMessage.class);
@Override
public void onMessage(Message message, Channel channel) throws Exception {
try{
String str = new String(message.getBody());
logger.info("接收到交易记录信息==>:" + str);
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}catch(Exception e){
logger.error("接收到交易记录信息异常回滚消息到队列中==>"+e.getMessage());
//消息回滚通道
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,true);
}
} @Override
public void onMessage(Message message) {
logger.info("消息==>"+JSON.toJSONString(message));
}
}
10、测试类RabbitmqMessageTest
package com.tandaima.rabbitmq.spring; import com.tandaima.rabbitmq.spring.service.MessageProducer;
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.SpringRunner; import java.util.Date; @RunWith(SpringRunner.class)
@ContextConfiguration(locations = {"classpath:spring/rabbitmq-context.xml"})
public class RabbitmqMessageTest {
@Autowired
private MessageProducer messageProducer; private String exchange="transaction.exchange"; @Test
public void senTransactionRecordMsg(){
for(int i=1;i<=5;i++){
String routingKeyTransactionRecord = "transaction.record.queue.key";
messageProducer.sendMessage(
exchange,
routingKeyTransactionRecord,
"我是内容"+ i);
}
} /**
* 10w条数据 发送38秒496毫秒
*/
@Test
public void senTransactionKlineMsg(){
Date begin=new Date(); //开始时间
for(int i=1;i<=10;i++){
String routingKeyTransactionKlin = "transaction.kline.queue.key";
messageProducer.sendMessage(
exchange,
routingKeyTransactionKlin,
"我是内容"+ i);
}
System.out.println(getString(begin,new Date()));
}
private String getString(Date begin,Date end){
long between = end.getTime() - begin.getTime();// 得到两者的毫秒数
long day = between / (24 * 60 * 60 * 1000);
long hour = (between / (60 * 60 * 1000) - day * 24);
long min = ((between / (60 * 1000)) - day * 24 * 60 - hour * 60);
long s = (between / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
long ms = (between - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - s * 1000);
return (day + "天" + hour + "小时" + min + "分" + s + "秒" + ms + "毫秒");
}
}
测试效果
我这里用的是路由模式交换机、两个队列使用一个交换机
Spring使用Rabbitmq (简单使用)的更多相关文章
- 五.Spring与RabbitMQ集成--HelloWorld
spring对RabbitMQ做了很好的集成,我们称之为spring AMQP,其官方文档写得十分详尽,文档地址:https://docs.spring.io/spring-amqp/referenc ...
- 六.Spring与RabbitMQ集成--HelloWorld
spring对RabbitMQ做了很好的集成,我们称之为spring AMQP,其官方文档写得十分详尽,文档地址:https://docs.spring.io/spring-amqp/referenc ...
- Spring boot+RabbitMQ环境
Spring boot+RabbitMQ环境 消息队列在目前分布式系统下具备非常重要的地位,如下的场景是比较适合消息队列的: 跨系统的调用,异步性质的调用最佳. 高并发问题,利用队列串行特点. 订阅模 ...
- RabbitMQ入门到进阶(Spring整合RabbitMQ&SpringBoot整合RabbitMQ)
1.MQ简介 MQ 全称为 Message Queue,是在消息的传输过程中保存消息的容器.多用于分布式系统 之间进行通信. 2.为什么要用 MQ 1.流量消峰 没使用MQ 使用了MQ 2.应用解耦 ...
- Spring Security4.X 简单实例介绍
简介 本例子采用的是SpringMVC.SpringSecurity和Spring整合的简单使用 使用gradle搭建的项目(gradle比maven更加便捷),可以自行了解 web.xml配置 &l ...
- rabbitMQ第五篇:Spring集成RabbitMQ
前面几篇讲解了如何使用rabbitMq,这一篇主要讲解spring集成rabbitmq. 首先引入配置文件org.springframework.amqp,如下 <dependency> ...
- 使用Spring缓存的简单Demo
使用Spring缓存的简单Demo 1. 首先创建Maven工程,在Pom中配置 <dependency> <groupId>org.springframework</g ...
- spring amqp rabbitmq fanout配置
基于spring amqp rabbitmq fanout配置如下: 发布端 <rabbit:connection-factory id="rabbitConnectionFactor ...
- Spring依赖注入 --- 简单使用说明
Spring依赖注入 --- 简单使用说明 本文将对spring依赖注入的使用做简单的说明,enjoy your time! 1.使用Spring提供的依赖注入 对spring依赖注入的实现方法感兴趣 ...
随机推荐
- excel处理经纬度
=LEFT(A1,FIND("°",A1)-1)*1+MID(A1,FIND("°",A1)+1,2)/60+MID(A1,FIND("′" ...
- Spring 框架介绍
Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of Control – I ...
- springMvc接收json和返回json对象
导入三个包 页面: function sendJson(){ //请求json响应json $.ajax({ type:"post", url: "${pageConte ...
- B. The Number of Products(Codeforces Round #585 (Div. 2))
本题地址: https://codeforces.com/contest/1215/problem/B 本场比赛A题题解:https://www.cnblogs.com/liyexin/p/11535 ...
- 【LeetCode】子集
[问题]给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集).说明:解集不能包含重复的子集. 示例: 输入: nums = [,,] 输出: [ [], [], [], [,,] ...
- C++编程学习(二) 数据
博主已经有一些基础了,所以写的东西可能是容易错的,或者以前没记住的,或者是对理解知识点有帮助的.因此如果有纯小白看到了这篇博文,不懂的地方请自行百度啦~ 另外,本系列所有内容的图片均来自于西北工业大学 ...
- LIS是什么?【标本分拣】
接之前[LIS是什么?]中,提到几点需要补充描述的部分. Ⅰ.标本分管处理 标本的分管处理,在医院和第三方实验室有多种叫法,例如:分拣.合管等等.这里我称之为分拣,分拣实际上分为两个部分:系统中标本分 ...
- POJ 1149:PIGS 网络流经典题
PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18345 Accepted: 8354 Description ...
- 18 11 24 简单的http服务器
---恢复内容开始--- import socket def service_client(new_socket): """为这个客户端返回数据""& ...
- css 的基础样式--border--padding--margin
border 边框复合写法 border:border-width border-style border-color; border-width 边框宽度 border-style 边框样式:sol ...