RabbitMQ阻塞读取时数据时,关闭channel引起的问题和解决方案
项目场景:
最近在项目中使用了RabbitMq,其中有一个功能必须能随时切断RabbitMq的coumser。第一时间写出来的代码如下:
伪代码:
while(flag){
QueueingConsumer.Delivery delivery=consumer.nextDelivery();
String message = new String(delivery.getBody());
//doing someting strange
//......
}
//另外一个项目开始关闭
public void closeConsumer{
channel().close();
connection().close();
}
closeConsumer();
通过关闭channel,消费者自然会关闭。然而,项目开始报错:

channel关闭抛出ShutdownSignalException,抛出异常就表示这种关闭方式是不合理的。有必要去探索一下是否有更优雅的链接关闭方式。
先看consumer的源码:
public Delivery nextDelivery()throws InterruptedException, ShutdownSignalException, ConsumerCancelledException{
return handle(_queue.take());
}
而这里_queue其实是一个 LinkedBlockingQueue,LinkedBlockingQueue是一个单向链表实现的阻塞队列。nextDelivery()方法使用LinkedBlockingQueue的take方法实现了阻塞。这个地方感觉不好操作。但是QueueingConsumer还有另外一个读取数据的方法,源码如下:
public Delivery nextDelivery(long timeout)throws InterruptedException, ShutdownSignalException, ConsumerCancelledException{
return handle(_queue.poll(timeout, TimeUnit.MILLISECONDS));
}
这边设定了超时时间。虽然没想到优雅关闭消费者的方法,但是利用超时时间来修改一下读取数据的方法还是可以的。代码如下:
try{
while(flag){
QueueingConsumer.Delivery delivery = consumer.getDeliveryMessage(10000);
if(consumer.getState()==Consumer.Status.Stopped.getValue()){
break;
}
if(delivery==null){
continue;
}
String message = new String(delivery.getBody());
//....dosomething
}
}finally {
if(consumer!=null){
consumer.closeConnection();
}
}
public void closeConnection{
channel().close();
connection().close();
}
//另外一个线程关闭consumer
consumer.setStatus(Consumer.Status.Stopped);
总结:这种关闭方式可以让Mq关闭连接时不抛出异常,比之前的方式好一点。但可能并不是最好的方法。如果有更好的方案,请留言告诉我,谢谢
RabbitMQ阻塞读取时数据时,关闭channel引起的问题和解决方案的更多相关文章
- Hive读取外表数据时跳过文件行首和行尾
作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 有时候用hive读取外表数据时,比如csv这种类型的,需要跳过行首或者行尾一些和数据无关的或者自 ...
- wcf序列化大对象时报错:读取 XML 数据时,超出最大
错误为: 访问服务异常:格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出 错: request.InnerException 消息是“反序 ...
- InnerException 消息是“反序列化对象 属于类型 *** 时出现错误。读取 XML 数据时,超出最大字符串内容长度配额 (8192)。(注意细节)
WEB站点在调用我们WCF服务的时候,只要传入的参数过长,就报如下错误: 格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出错: formD ...
- python使用xlrd读取excel数据时,整数变小数的解决办法
python使用xlrd读取excel数据时,整数变小数: 解决方法: 1.有个比较简单的就是在数字和日期的单元格内容前加上一个英文的逗号即可.如果数据比较多,也可以批量加英文逗号的前缀(网上都有方法 ...
- Web Service 或 WCF调用时读取 XML 数据时,超出最大字符串内容长度配额(8192)解决方法
1.调用服务时服务 当我们使用 Web Service 或 WCF 服务时,常把读取的数据转化为string类型(xml格式),当数据量达到一 定数量时,会出现以下异常: 错误:格式化程序尝试对消息反 ...
- 读取 XML 数据时,超出最大字符串内容长度配额 (8192)
格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://www.thermo.com/informatics/xmlns/limswebservice 进行反序列化时出错: Process ...
- 格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出错: GetLzdtArticleResult。InnerException 消息是“反序列化对象 属于类型 lzdt.DTO.Dtolzdt[] 时出现错误。读取 XML 数据时,超出最大
当遇到这个错误的时候郁闷了好长时间报错是字符串长度过大可是修改了MaxStringContentLength”属性的值却不起作用最后才发现还是因为配置文件配置的问题在服务端 格式化程序尝试对消息反序列 ...
- oledbdataadapter 读取excel数据时,有的单元格内容不能读出
表现:excel中某列中,有的单元格左上角有绿色箭头标志,有的没有,c#编写读取程序,但是只能读取出带绿色箭头的单元格中的内容,其余不带的读取不到内容 原因:excel中单元格因为是文本格式而存储了数 ...
- pandas读取csv数据时设置index
比如读取数据时想把第一列设为index,那么只需要简单的 pd.read_csv("new_wordvecter.csv",index_col=[0]) 这里index_col可以 ...
随机推荐
- java面向对象整理
1.局部变量与全局变量的区别 区别一:定义的位置不同 定义在类中的变量是成员变量 定义在方法中或者{}语句里面的变量是局部变量定义 区别二:在内存中的位置不同 成员变量存储在对内存的对象中 局部变量存 ...
- Microsoft SQL Server 2008 R2数据库备份 - 人工备份
业务介绍 数据库人工备份是指由相关管理人员通过主动的手工方式备份数据库文件.在一些特殊的时间节点,如重要资料的录入完成.软硬件环境更新前等需要特别关注数据库安全的时候,一定要进行数据库的人工备份,以保 ...
- HTML5能否会成为Web技术的核心?
谁会成为HTML5后继者? 那么会有一个HTML6吗? Jaffe表示,网上支付可能会推动进行这样的全面修订,以期能为网上支付来提供一个统一方式.如果大家将之称为HTML 6,那么HTML 6是极有可 ...
- spring boot自定义log4j2日志文件
背景:因为从 spring boot 1.4开始的版本就要用log4j2 了,支持的格式有json和xml两种格式,此次实践主要使用的是xml的格式定义日志说明. spring boot 1.5.8. ...
- 学习MySQL(上)
具体实例 1.PHP 服务器组件 对于初学者建议使用集成的服务器组件,它已经包含了 PHP.Apache.Mysql 等服务,免去了开发人员将时间花费在繁琐的配置环境过程. Window 系统可以使用 ...
- C语言之最大公约数与最小公倍数
#include<stdio.h>int main(){ int num1, num2,temp; scanf("%d%d",&num1,&num2); ...
- 爬起点小说 day01
先介绍下我自己爬起点小说的思路: 1.爬取所有的类型列表 a.链接存redis中 类型表:novel_list 具体每一种类型:bnovel_all_list(把novel_list和bnovel_l ...
- pdo 封装增删改查类
<?php/** * Class model * @package Core\lib */class model{ protected $pdo = null; // 连接数据库 ...
- 智能合约语言Solidity教程系列2 - 地址类型介绍
智能合约语言Solidity教程系列第二篇 - Solidity地址类型介绍. 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你 ...
- UWP Listview 多选
最近在做一个项目的时候,用到了Listview,需要选择一个item,来进行删除. 但是当开启了 PullToRefreshListViewControl.IsMultiSelectCheckBoxE ...