zoukankan      html  css  js  c++  java
  • 单例模式解决RabbitMQ超出最大连接问题

    今天在项目稳定性测试过程中遇到一个情景:通过工具jMeter一直请求消息转发服务器,消息转发服务器再向rabbitMQ发送数据,在这期间出现了问题、MQ意外宕机。

    1. 查看rabbitMQ管理界面。如下图、rabbitMQ连接数不断往上涨。

    2.初步定为为代码问题、通过分析工具代码发现:

    public class MQSender extends BaseEndPoint {
        public MQSender(String endPointName) throws IOException{
            super(endPointName);
        }
    
        public void sendMessage(Serializable object) throws IOException {
            if (channel != null) {
                channel.basicPublish("", endPointName, MessageProperties.PERSISTENT_TEXT_PLAIN, SerializationUtils.serialize(object));
            }
        }
    }
    

     项目中每次在调用时:

     MQSender mqSender = new MQSender(EnvConstant.NODE_PASS_QUEUE_NAME);
    

     通过代码不难发现mq的连接会最终撑爆,再通过linux命令nohup确定jar包错误:

    java.util.concurrent.TimeoutException
    	at com.rabbitmq.utility.BlockingCell.get(BlockingCell.java:77)
    	at com.rabbitmq.utility.BlockingCell.uninterruptibleGet(BlockingCell.java:111)
    	at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:37)
    	at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:367)
    	at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:293)
    	at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:678)
    	at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:722
    

    3.解决:通过单例模式改造

     用“双重检查加锁”改造后的工具类:

    /**
     * 用“双重检查加锁”,getMqSender()中减少使用同步
     * 利用双重检查加锁,首先检查是否实例已经创建,如果没有才同步。
     * 这样只有第一次才会同步。
     * @author monkjavaer
     * @date 2018/08/27 22:28
     */
    public class MQSender extends BaseEndPoint {
        private volatile static MQSender mqSender;
    
        public static MQSender getMqSender(String endPointName) throws IOException {
            //如果实例不存在,进入同步区
            if (mqSender == null){
                //只有第一次才执行
                synchronized (MQSender.class){
                    //进入区块再检查一次
                    if (mqSender == null){
                        mqSender =new MQSender(endPointName);
                    }
                }
            }
            return mqSender;
        }
        private MQSender(String endPointName) throws IOException{
            super(endPointName);
        }
        public void sendMessage(Serializable object) throws IOException {
            if (channel != null) {
                channel.basicPublish("", endPointName, MessageProperties.PERSISTENT_TEXT_PLAIN, SerializationUtils.serialize(object));
            }
        }
    }
    通过改写后mq正常使用。
  • 相关阅读:
    C#调试信息打印到输出窗口
    C#拼接SQL中in条件
    从图像到知识:深度神经网络实现图像理解的原理解析
    Cocoa Touch(六):App运行机制 NSRunLoop, KVC, KVO, Notification, ARC
    Cocoa Touch(五):网络请求 NSURLSession/AFNetworking, GCD, NSURLResquest
    JQuery:选择器、动画、AJAX请求
    Cocoa Touch(四): 多线程GCD, NSObject, NSThread, NSOperationQueue
    Socket、RPC通信实例,简单版本,仅供查阅
    Cocoa Touch(三):图形界面UIKit、Core Animation、Core Graphics
    Cocoa Touch(二):数据存储CoreData, NSKeyArchiver, NSOutputStream, NSUserDefaults
  • 原文地址:https://www.cnblogs.com/monkjavaer/p/9610712.html
Copyright © 2011-2022 走看看