项目场景:

  最近在项目中使用了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引起的问题和解决方案的更多相关文章

  1. Hive读取外表数据时跳过文件行首和行尾

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 有时候用hive读取外表数据时,比如csv这种类型的,需要跳过行首或者行尾一些和数据无关的或者自 ...

  2. wcf序列化大对象时报错:读取 XML 数据时,超出最大

    错误为: 访问服务异常:格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出 错: request.InnerException 消息是“反序 ...

  3. InnerException 消息是“反序列化对象 属于类型 *** 时出现错误。读取 XML 数据时,超出最大字符串内容长度配额 (8192)。(注意细节)

    WEB站点在调用我们WCF服务的时候,只要传入的参数过长,就报如下错误: 格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出错: formD ...

  4. python使用xlrd读取excel数据时,整数变小数的解决办法

    python使用xlrd读取excel数据时,整数变小数: 解决方法: 1.有个比较简单的就是在数字和日期的单元格内容前加上一个英文的逗号即可.如果数据比较多,也可以批量加英文逗号的前缀(网上都有方法 ...

  5. Web Service 或 WCF调用时读取 XML 数据时,超出最大字符串内容长度配额(8192)解决方法

    1.调用服务时服务 当我们使用 Web Service 或 WCF 服务时,常把读取的数据转化为string类型(xml格式),当数据量达到一 定数量时,会出现以下异常: 错误:格式化程序尝试对消息反 ...

  6. 读取 XML 数据时,超出最大字符串内容长度配额 (8192)

    格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://www.thermo.com/informatics/xmlns/limswebservice 进行反序列化时出错: Process ...

  7. 格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出错: GetLzdtArticleResult。InnerException 消息是“反序列化对象 属于类型 lzdt.DTO.Dtolzdt[] 时出现错误。读取 XML 数据时,超出最大

    当遇到这个错误的时候郁闷了好长时间报错是字符串长度过大可是修改了MaxStringContentLength”属性的值却不起作用最后才发现还是因为配置文件配置的问题在服务端 格式化程序尝试对消息反序列 ...

  8. oledbdataadapter 读取excel数据时,有的单元格内容不能读出

    表现:excel中某列中,有的单元格左上角有绿色箭头标志,有的没有,c#编写读取程序,但是只能读取出带绿色箭头的单元格中的内容,其余不带的读取不到内容 原因:excel中单元格因为是文本格式而存储了数 ...

  9. pandas读取csv数据时设置index

    比如读取数据时想把第一列设为index,那么只需要简单的 pd.read_csv("new_wordvecter.csv",index_col=[0]) 这里index_col可以 ...

随机推荐

  1. 使用Gulp构建前端自动化方案

    前言 在刚入门前端的时候,我们并不清楚前端有工具可以帮我们自动化打包压缩文件,当时只关注能实现功能就可以了,也不太在意前端性能优化的问题,随着项目功能的复杂,项目也变得越来越大,页面的执行速度也开始变 ...

  2. SaltStack 安装介绍 01

    一.入门指南 1.1 SALTSTACK是什么? The backbone of Salt is the remote execution engine, which creates a high-s ...

  3. iOS 中 .a 和 .framework 静态库的创建与 .bundle 资源包的使用

    iOS 中 .a 和 .framework 静态库的创建与 .bundle 资源包的使用 前言 开发中经常使用三方库去实现某特定功能,而这些三方库通常又分为开源库和闭源库.开源库可以直接拿到源码,和自 ...

  4. Numpy入门 - 行列式转置

    本章实例讲解如何将一个数组对象进行转置,我们可以使用.T将行列数据颠倒过来,看下面的代码: import numpy as np arr = np.array([[1, 2, 3], [4, 5, 6 ...

  5. SSM Spring+SpringMVC+mybatis+maven+mysql环境搭建

    SSM Spring+SpringMVC+mybatis+maven环境搭建 1.首先右键点击项目区空白处,选择new->other..在弹出框中输入maven,选择Maven Project. ...

  6. haproxy1.7编译安装配置

    #haproxy1.7编译安装配置#高可用.负载均衡 使用 #haproxy1.7编译安装配置 #centos7 x86_64 #高可用.负载均衡 使用 #下载 #http://www.haproxy ...

  7. 项目实战7—Mysql实现企业级数据库主从复制架构实战

    Mysql实现企业级数据库主从复制架构实战 环境背景:公司规模已经形成,用户数据已成为公司的核心命脉,一次老王一不小心把数据库文件删除,通过mysqldump备份策略恢复用了两个小时,在这两小时中,公 ...

  8. VMware中克隆虚拟机出现eth0改变为eth1情况

    解决如下: 查看复制虚拟机网卡信息如下: root@jcfx-2 ~]# ifconfig eth1 Link encap:Ethernet HWaddr 00:0C:29:CC:32:63 inet ...

  9. Echarts后台封装option对象

    该方法返回的keyword指向了前台负责图表显示的jsp页面 public String keyword() { if(this.dateNum == null || this.dateNum.equ ...

  10. Scala中的override

    Scala中的override override是覆盖的意思,在很多语言中都有,在scala中,override是非常常见的,在类继承方面,它和java不一样,不是可写可不写的了,而是必须写的.如果不 ...