服务器消息消费不过来,RabbitMQ消息队列+spring监听mq服务器,接收消费mq消息_吴玄熙的博客-程序员宅基地

技术标签: 服务器消息消费不过来  

最近soa项目要和官网系统对接,实现mq信息监听,保存等一些列操做。项目用的是Maven+SSM框架。而后学习和开发用了两天时间,算是搞定,趁加班时间作个总结。

对于Maven工程的ssm框架,整合RabbitMq首先就是java

1.引入依赖:

org.springframework.amqp

spring-rabbit

1.3.5.RELEASE

依赖很少,就这一个就够用了。可是有个坑要注意,若是引入的位置不对,启动会出现莫名的启动报错,我试了好几回,最后放到全部引入依赖的最后面是没问题的~因此,明智的选择是引入成功后先启动项目看看会不会报错,这个时候才引入一个依赖,正常不会报错,若是报错,就是位置不对,及时调整吧。web

2.配置文件:context-rabbitMq.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd">

3.在web.xml中引入配置的文件context-rabbitMq.xml

contextConfigLocation

classpath:META-INF/app_config/context/context-*.xml

4.自定义监听类:RabbitMqConsumerListener

自定义的监听类必须实现接口:ChannelAwareMessageListener或者MessageListener.这里最好用Channel…这个。spring

两者的区别能够从他们的抽象类的入参来讲:一个是message(消息实体),一个是channel就是当前的通道。

ChannelAwareMessageListener的抽象类:

void onMessage(Message message,Channel channel) .

MessageListener接口的抽象类:

void onMessage(Message message).

多出的参数Channel能够很方便的提供监听以外的ack通知RabbitMq服务器功能。

因为MQ服务器对于消费端无反馈的,有重发机制,可能会有一条数据发送屡次,而且一致保存在服务器中,长此以往就会因为数据量过大形成内存溢出的危险,而ack机制就是经过消费端发出通知给mq服务器,告诉服务器那条mq已经处理完毕,能够剔除。对于处理异常的,则能够从新回到mq服务器的队列中。而实现手动实现这个ack的关键点就是实现接口:ChannelAwareMessageListener.api

如何实现手动ack?

手动ack就是在当前channel里面调用basic***的方法,并传入当前消息的tagId就能够了。服务器

这里的ack通知分为三种状况:app

a.消费端正常处理完成一条mq时,ack mq服务器能够移除此条mq的方法框架

//消息的标识,false只确认当前一个消息收到,true确认全部consumer得到的消息

channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

参数解释:

deliveryTag:该消息的index

multiple:是否批量.true:将一次性ack全部小于deliveryTag的消息。ide

b. 消费端处理完成一条mq时发生异常,ack 会将此条mq从新放到mq服务器队列queue中svg

//ack返回false,此条mq并从新回到队列

channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);

参数解释:

deliveryTag:该消息的index

multiple:是否批量.true:将一次性拒绝全部小于deliveryTag的消息。

requeue:被拒绝的是否从新入队列学习

c.就是消费端主动拒绝mq服务器发送mq过来。

//拒绝消息

channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);

参数解释:

deliveryTag:该消息的index

requeue:被拒绝的是否从新入队列

channel.basicNack 与 channel.basicReject

的区别在于basicNack能够拒绝多条消息,而basicReject一次只能拒绝一条消息

5.自定义类的具体实现:

import java.io.IOException

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.amqp.core.Message;

import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;

import com.rabbitmq.client.Channel;

import com.zlf.cn.action.IRabbitMqConsumerTaskAction;

/**

*使用监听器接收消息

*@author itw_zhanglf02

/

public class RabbitMqConsumerListener implents ChannelAwareMessageListener{

private Logger logger=loggerFactory.getLogger(RabbitMqConsumerListener.class);

@Resource(name=IRabbitMqConsumerTaskAction.ACTION_ID)

private IRabbitMqConsumerTaskAction rabbitMqConsumerTaskAction;

@Override

public void onMessage(Message arg0,Channel channel){

//业务处理,放到action层,并返回处理成功仍是异常的flag

boolean mqFlag=rabbitMaConsumerTaskAction.saveMq(arg0);

//还有一个点就是如何获取mq消息的报文部分message?

//String message=new String(arg0.getBody(),"UTF-8");

if(mqFlag){

basicACK(arg0,channle);//处理正常--ack

}else{

basicNACK(arg0,channle);//处理异常--nack

}

}

//正常消费掉后通知mq服务器移除此条mq

private void basicACK(Message message,Channel channel){

try{ channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);

}catch(IOException e){

logger.error("通知服务器移除mq时异常,异常信息:"+e);

}

}

//处理异常,mq重回队列

private void basicNACK(Message message,Channel channel){

try{

channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);

}catch(IOExeption e){

logger.error("mq从新进入服务器时出现异常,异常信息:"+e);

}

}

}

这样就能够了。启动项目,有时候在项目启动完毕,监听程序开始的时候报错,报错信息大体:

org.springframework.amqpAmqpIOException:java.io.IOException....

Case by:com.rabbitmq.client.ShutdownSignalException:channel error;protocol method:#method(reply-code=403,reply-text=ACCESS_REFUSED - access to queue 'ZL.SALETRACE' in vhost 'tele-onlineYA' refused for user 'tel-online',class-id=50,method-id=10)......

这种状况网上给的大都是因为在配置对应权限上有问题,但我这里报的一样的错误,并非他们说的那种状况,而是因为咱们这里作的监听mq服务器名为’ZL.SALETRACE’的queue,若是服务器端如今没有mq,就会报这个错,估计是没有mq,服务器暂时没有分配队列,队列就没有生成,但这个不是啥配置问题,是初始化问题。若是如今服务器端发送mq,仍是能迅速的接收到发送的mq的,而后一切就正常了。

因此这个问题归结于服务端没有mq,若是有mq,仍是能够正常接收,没啥问题的。这种报错能够忽略。

好了,这就是本次迭代的总结。~

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_42113380/article/details/119290819

智能推荐

此时墨迹在计算机上不起作用,win7系统自带截图工具不见了怎么找回_叶子虫的博客-程序员宅基地

win7系统自带截图工具不见了怎么找回答案:2信息版本:手机版解决时间 2019-10-04 23:07已解决2019-10-04 18:12win7系统自带截图工具不见了怎么找回最佳答案2019-10-04 18:26win7 系统自带的截图工具损坏修复方法:一、便笺修复方法:1、先看便笺的损坏情况,无法打开。2、打开资源管理器,在C盘中搜索到InkObj.dll。3、在其中选一个右击,选择...

安装mysql是按开发者还是full_安装mysql 选developer default和sever only的区别_weixin_39846289的博客-程序员宅基地

展开全部1、Developer Default 为默认安装类型,开发者机器。2、Server only 仅作为服务器。3、Developer Machine:代表典型个人用桌面工作站。62616964757a686964616fe78988e69d8331333365643662假定机器上运行着多个桌面应用程序。将MySQL服务器配置成使用最少的系统资源。4、Server Machine:代表服务...

Android 启动系统相机,相册,裁剪图片及6,h5移动端开发工具_普通网友的博客-程序员宅基地

两种方法的区别第一种方法获取的bitmap是被缩放的bitmap,第二种方法获取的bitmap是完整的bitmap,实际使用中根据需求情况决定使用哪一种方法。官网参考地址怎样启动相册获取我们想要的图片第一步,通过 Intent.ACTION_GET_CONTENT 这个Intent,并设置相应的type,启动相册。Intent i = new Intent(Intent.ACTION_GET_CONTENT, null);i.setDataAndType(MediaStore.Images.

在京东如何查找计算机的销量,京东商品真实销量数据怎么看?教你一键查询_寂寞孩纸的博客-程序员宅基地

原标题:京东商品真实销量数据怎么看?教你一键查询京东平台关于销量的展示和其他平台是不一样的,买家在京东商品展示页面中是无法看到真实的销售数据,京东这个做法既有好处也有坏处。好处就是对于商家来说,不显示销量就避开了商品销量低或者是新品的尴尬处境,即便是0销量的商品都可以和销量高的同款商品在消费者选择中具有公平性;坏处就是一些质量有问题的商品或者销量确实不高的商品消费者无法通过真实的数据做出对比,要知...

python定位相邻节点_Python selenium ---父子,兄弟,相邻节点定位方式详解_weixin_39779467的博客-程序员宅基地

selenium中根据父子、兄弟、相邻节点定位的方法,很多人在实际应用中会遇到想定位的节点无法直接定位,需要通过附近节点来相对定位的问题,但从父节点定位子节点容易,从子节点定位父节点、定位一个节点的哥哥节点就一筹莫展了,接下做出详尽的解析。1. 由父节点定位子节点最简单的肯定就是由父节点定位子节点了,我们有很多方法可以定位,下面上个例子:对以下代码:parent to child想要根据 B节点 ...

心淡淡的幸福[lyb521569]_weixin_33697898的博客-程序员宅基地

心淡淡的幸福!活着是一种心态! ----lyb521569 转载于:https://blog.51cto.com/462966779/1592127

随便推点

学C++的时候,这几个输入函数弄的有点迷糊;这里做个小结,为了自己复习,也希望对后来者能有所帮助,如果有差错的地方还请各位多多指教(本文所有程序均通过VC 6.0运行)_若水菱花的博客-程序员宅基地

1、cin2、cin.get()3、cin.getline()4、getline()5、gets()6、getchar()附:cin.ignore();cin.get()//跳过一个字符,例如不想要的回车,空格等字符1、cin>>用法1:最基本,也是最常用的用法,输入一个数字:#include <iostream>using namespace std;main (){int a,b;cin>>a&...

(19)使用RPA机器人保障敏感数据安全.docx_rpazj_Rayen的博客-程序员宅基地

大家好,我是徐老师,之前我们聊过打破数据孤岛的话题,那是解决多个系统之间的数据屏障,让数据能在多个系统之间流转起来。而这次我们主要讲的是,如何保障敏感数据的安全,让敏感数据不会被暴漏或泄露。在公司的运营和业务中,经常会涉及到一些敏感信息。这些信息因为需要被处理,只能赤裸裸的展现在处理人员眼中。虽然,我们会要求员工签署保密协议之类的,但是我们依旧对此保持担忧,并且会因此产生额外费用。很多流程可以抽象为:IPO也就是输入、处理、输出。输入和输出的渠道可能有很多,但是处理会有一个单独的个体或者组织去承担,那么这个

怎样实现随机抽题php,ppt VBA 实现随机抽题_十日君的博客-程序员宅基地

目标/最终效果目标具体描述:制作一个ppt,实现随机抽题。第一页幻灯片中:点击开始按钮后,右边的文本框快速滚动显示随机数字,点击停止按钮后,滚动停止,抽取到的题号会显示到第二个文本框中,并append到第三个文本框的内容中,然后点击跳转按钮,会跳转至相应幻灯片。跳转题目页面后,点击返回键,可返回到第一页幻灯片继续抽题。第一页幻灯片中,重置按钮将清除所有文本框的内容。PS:本文适合具有一定编程基础的...

要看计算机的cpu型号和内存大小,怎样查看电脑的CPU型号和存储空间_兔希求职咖青的博客-程序员宅基地

这个主板支持intel775针的处理器主要有:处理器型号 架构 高速缓存 时钟速度 前端总线E8600 45 纳米 6MB 二级缓存 3.33 GHz 1333 MHzE8500 45 纳米 6MB 二级缓存 3.16 GHz 1333 MHzE8400 45 纳米 6MB 二级缓存 3 GHz 1333 MHzE8300 45 纳米 6MB 二级缓存 2.83 GHz 1333 MHzE8200...

删掉word最后一页空白_shuaiba123的博客-程序员宅基地

这里写自定义目录标题删掉由于前面表格引起的word最后一页空白删掉由于前面表格引起的word最后一页空白Ctrl+backspace或者Alt+backspace

python用json转csv_Soyoger的博客-程序员宅基地

# -*- coding: utf-8 -*-"""Created on Wed May 31 14:07:54 [email protected]: ESRI"""import json  import sysif __name__ == "__main__":    reload(sys)    sys.setdefaultencoding( "ut

推荐文章

热门文章

相关标签