RabbitMQ解决大量unacked问题

为了快速响应用户请求,我们需要消息异步处理机制,比较简单的做法是用redis的List结构,我们项目使用更专业的RabbitMQ。关于redis和RabbitMQ队列处理的性能比较可以查看这篇文章http://blog.csdn.net/educast/article/details/34521603

这里不扯RabbitMQ的一些定义了,我们遇到的问题是,入队并发和速度速度很快,但是消费端的处理速度慢得惊人。为了数据安全我们做了持久化而且消费端需要ack或者unack响应。从其提供的web控制台可以看到量大的时候产生大量的unacked消息,也就是说MQ把数据放到channel里,很长时间过去了channel没有给任何响应。我们创建了600个channel问题也依旧。查看了硬件没有瓶颈,网上有文章说是channel连接断了mq无法及时识别,还会往这些失效的channel里传递数据,误认子弟啊,拉出去枪毙了。Netstat一下,发现一共MQ服务器一共有4个外部连接连入了5672端口,两个productor两个consumer跟预想的一样。Jstack一下,发现pool-xxx线程远远没有预想的多,才50个,我们创建了600个channel啊。恍然大悟,尼玛的channel中文意思虽然是通道,但是MQ使用了线程池技术,它们是共享线程的,而不是一个通道一个线程,这个有点类似http请求和http服务器的关系。

把结构图给画出来先:

Java代码

  1.  
    Properties prop = new Properties();
  2.  
    InputStream inStream = this.getClass().getResourceAsStream("/config.properties");
  3.  
    prop.load(inStream);
  4.  
     
  5.  
    ConnectionFactory factory = new ConnectionFactory();
  6.  
    factory.setHost(prop.getProperty("RabbitMQHost"));
  7.  
    factory.setUsername(prop.getProperty("RabbitMQUserName"));
  8.  
    factory.setPassword(prop.getProperty("RabbitMQPassword"));
  9.  
     
  10.  
    // 关键所在,指定线程池
  11.  
    ExecutorService service = Executors.newFixedThreadPool(500);
  12.  
    factory.setSharedExecutor(service);
  13.  
     
  14.  
    factory.setAutomaticRecoveryEnabled(true);
  15.  
    factory.setConnectionTimeout(15000);// 15秒
  16.  
    factory.setRequestedHeartbeat(60);
  17.  
    Connection connection = factory.newConnection();

线程方面已经没有问题了,不存在什么失效连接无法及时识别这一说法,如果还慢,则jstack去跟踪这些线程池的线程,看看都在干啥,关于jstack抽空再写了,很强大的jdk工具。

---------------------

本文来自 weinianjie1 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/weinianjie1/article/details/50611379?utm_source=copy

RabbitMQ -- unacked的更多相关文章

  1. python开发笔记-连接rabbitmq异常问题unacked处理

    待补充 思路:捕获程序处理异常,异常情况下,也给队列生产者返回“确认”消息

  2. 消息队列——RabbitMQ学习笔记

    消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...

  3. 消费RabbitMQ时的注意事项,如何禁止大量的消息涌到Consumer

    按照官网提供的订阅型写法( Retrieving Messages By Subscription ("push API")) 我发现,RabbitMQ服务器会在短时间内发送大量的 ...

  4. RabbitMQ的几种典型使用场景

    RabbitMQ主页:https://www.rabbitmq.com/ AMQP AMQP协议是一个高级抽象层消息通信协议,RabbitMQ是AMQP协议的实现.它主要包括以下组件: 1.Serve ...

  5. 【RabbitMQ】 WorkQueues

    消息分发 在[RabbitMQ] HelloWorld中我们写了发送/接收消息的程序.这次我们将创建一个Work Queue用来在多个消费者之间分配耗时任务. Work Queues(又称为:Task ...

  6. RabbitMQ消息队列:ACK机制

    每个Consumer可能需要一段时间才能处理完收到的数据.如果在这个过程中,Consumer出错了,异常退出了,而数据还没有处理完成,那么 非常不幸,这段数据就丢失了. 因为我们采用no-ack的方式 ...

  7. (转)RabbitMQ消息队列(三):任务分发机制

    在上篇文章中,我们解决了从发送端(Producer)向接收端(Consumer)发送“Hello World”的问题.在实际的应用场景中,这是远远不够的.从本篇文章开始,我们将结合更加实际的应用场景来 ...

  8. RabbitMQ基础总结

    MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们.消 息传递指的是程序之 ...

  9. RabbitMQ 原文译02--工作队列

    工作队列: 在上一篇文章中我们我们创建程序发送和接受命名队列中的消息,在这篇文章我会创建一个工作队列,用来把耗时的操作分配给多个执行者. 工作队列(任务队列)的主要实现思想是避免马上执行资源密集型的任 ...

随机推荐

  1. 采用镜像的方法安装python第三方库

    转自:https://blog.csdn.net/s740556472/article/details/68557330 pip install --index https://pypi.mirror ...

  2. INTERVAL

    select sysdate - interval '10' day as "10天前",       sysdate - interval '10' hour as " ...

  3. Qt编写通用主界面V2019

    其实是2018年做出来的这个界面效果,用该界面做了三四个项目,今天抽空特意提取出来单独的demo,集成到了皮肤生成器中.

  4. 关于H5页面在iPhoneX适配(转)

    ​1.  iPhoneX的介绍 屏幕尺寸 我们熟知的iPhone系列开发尺寸概要如下: △ iPhone各机型的开发尺寸 转化成我们熟知的像素尺寸: △ 每个机型的多维度尺寸 倍图其实就是像素尺寸和开 ...

  5. MySQL 之 表操作

    一 什么是表 表(TABLE) 是一种结构化的文件,可用来存储某种特定类型的数据.表中的一条记录有对应的标题,标题 称之为 表的字段. 二 创建表 1 2 3 4 5 CREATE TABLE 表名( ...

  6. AngularJS基础02 神奇的数据绑定(Binding)

    作者:arccosxy  转载请注明出处:http://www.cnblogs.com/arccosxy/ 上一节,我们在JS中声明一个scope变量然后在HTML直接访问它,这非常的酷.但是Angu ...

  7. Maven Web项目部署到Tomcat下问题

    但是也遇到了很多问题,下面记录一下Web项目部署到Tomcat下的问题 1.普通的WEB项目,就是虽然是用maven搭建的,但是没有使用profiles.xml文件来配置参数.这样的项目可以通过以下的 ...

  8. Unable to cast object of type 'System.Int32' to type 'System.Array'.

    x 入职了新公司.最近比较忙...一看博客...更新频率明显少了...罪过罪过... 新公司用ASP.NET MVC 遇上一个错误: Unable to cast object of type 'Sy ...

  9. ubuntu16.04编译安装imu_tk

    imu_tk代码地址 https://bitbucket.org/alberto_pretto/imu_tk 安装依赖项 sudo apt-get install build-essential cm ...

  10. let 与 const 的用法

    let 与 const 的用法 let 用来声明变量,并且会在当前作用域形成 代码块 conts 用来声明常量,所谓常量就是物理指针不可以更改的变量. 所谓代码块,最简单的做法就是(这个 {} 就是一 ...