RabbitMQ解决大量unacked问题

在面临入队速度远超消费速度,导致RabbitMQ中出现大量unacked消息的问题时,通过分析发现,尽管创建了600个channel,但线程池并未按预期工作。实际上,RabbitMQ的channel是共享线程的,而非每个channel独占。调整线程配置后,解决了通道效率问题。使用jstack工具进行监控,确保线程正常运行。

RabbitMQ解决大量unacked问题

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

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

把结构图给画出来先:


Java代码

		Properties prop = new Properties();
		InputStream inStream = this.getClass().getResourceAsStream("/config.properties");
		prop.load(inStream);
		
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost(prop.getProperty("RabbitMQHost"));
		factory.setUsername(prop.getProperty("RabbitMQUserName"));
		factory.setPassword(prop.getProperty("RabbitMQPassword"));
		
		// 关键所在,指定线程池
		ExecutorService service = Executors.newFixedThreadPool(500);
		factory.setSharedExecutor(service);
		
		factory.setAutomaticRecoveryEnabled(true);
		factory.setConnectionTimeout(15000);// 15秒
		factory.setRequestedHeartbeat(60);
		Connection connection = factory.newConnection();

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


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值