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依赖注入的实现方法感兴趣 ...
随机推荐
- android 动画基础绘——view 动画(二)[补]
前言 这个是对view 动画的补充,是一些view 动画的特殊使用场景. 回顾第一篇关于view 动画的,我介绍到view的动画都是针对元素本身的. 当我们开发view动画的时候,我们看到几个元素在做 ...
- 12.Python的高级语法和用法
# from enum import Enum # 枚举 # class VIP(Enum): # YELLOW = # YELLOW_ALIAS = # 别名 # GREEN = # BLACK = ...
- 第三节MapStruct翻译--Defining a mapper
第三节MapStruct--Defining a mapper 在这一章节你将学到如何用mapstruct和它的一些必要的操作选项来定义一个bean mapper. 3.1 Basic mapping ...
- 前端基础之AJAX
AJAX 什么是AJAX,简单来说就是利用JavaScript天生异步的特性,使用异步请求后台数据,从而达到不刷新网页也能局部更新页面的效果. 原生AJAX JavaScript中的AJAX依赖于XM ...
- C++ 设置自动启动
WCHAR pFileName[MAX_PATH] = {}; //得到程序自身的全路径 DWORD dwRet = GetModuleFileName(NULL, pFileName, MAX_PA ...
- 洛谷 P1435 回文字串
题目传送门 解题思路: 就是求一个字符串的最长回文子序列的长度,然后用整个的长度减去最长回文子序列的长度 AC代码: #include<iostream> #include<cstd ...
- Codeforces 446C 线段树 递推Fibonacci公式
聪哥推荐的题目 区间修改和区间查询,但是此题新颖之处就在于他的区间修改不是个定值,而是从L 到 R 分别加 F1.F2....Fr-l+1 (F为斐波那契数列) 想了一下之后,觉得用fib的前缀和来解 ...
- Essay写作的六大黄金法则以及四大禁区
虽然Essay这么难写,但是,也有一些可以拿高分的准则,本文小编就为大家分享高分Essay写作必知黄金法则,希望对想要在Essay拿高分的留学生小伙伴们有些帮助. 黄金法则1.关注相关问题的重点词汇 ...
- 使用docker-sync解决docker for mac 启动的虚拟容器程序运行缓慢的问题
背景: 新入职的公司有个非常OG的大项目,为了避免新同学重复造轮子,有哥们已经把项目需要的所有打好了一个镜像供我们启动docker. 初次启动docker 使用的命令如下: docker run -i ...
- POJ1200 A - Crazy Search(哈希)
A - Crazy Search Many people like to solve hard puzzles some of which may lead them to madness. One ...