Java 在RabbitMQ中使用单通道与单线程执行器进行通信可以吗?

Java 在RabbitMQ中使用单通道与单线程执行器进行通信可以吗?,java,multithreading,rabbitmq,threadpoolexecutor,Java,Multithreading,Rabbitmq,Threadpoolexecutor,我正在尝试使用RabbitMQ java客户端API与RabbitMQ服务器交互。 我从报纸上读到: 根据经验,应该避免在线程之间共享通道实例。应用程序应该更喜欢每个线程使用一个通道,而不是跨多个线程共享同一个通道 我正在尝试使用corePoolSize为1的ThreadPoolExecutor,并添加可运行任务以在RabbitMQ队列中保存消息。以下是我正在使用的代码: package common; import java.io.IOException; import java.io.In

我正在尝试使用RabbitMQ java客户端API与RabbitMQ服务器交互。 我从报纸上读到:

根据经验,应该避免在线程之间共享通道实例。应用程序应该更喜欢每个线程使用一个通道,而不是跨多个线程共享同一个通道

我正在尝试使用corePoolSize为1的ThreadPoolExecutor,并添加可运行任务以在RabbitMQ队列中保存消息。以下是我正在使用的代码:

package common;

import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonObject;
import com.rabbitmq.client.BlockedListener;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;
import com.rabbitmq.client.ShutdownListener;
import com.rabbitmq.client.ShutdownSignalException;

public class RabbitMQUtil {
    private static Logger log= LoggerFactory.getLogger("logger");
    private static RabbitMQUtil gmInstance;
    private ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(10000));
    private final String PROPERTIES_FILE_NAME = "config/rabbitmq.properties";
    private final Properties properties = new Properties();
    private String host = null;
    private int port = 0;
    private String username = null;
    private String password = null;
    private String useSSL = "false";
    private ConnectionFactory factory;
    private Connection connection;
    private Channel channel;

    private RabbitMQUtil() throws IOException, TimeoutException, Exception {
        try {
            InputStream stream = RabbitMQUtil.class.getClassLoader().getResourceAsStream(PROPERTIES_FILE_NAME);
            if(stream != null) {
                properties.load(stream);
            }
        } catch (Exception ex) {
            log.error("Exception while loading the rabbitmq properties file:", ex);
        }

        host = properties.getProperty("rabbitmq.host", "localhost");
        port = Integer.parseInt(properties.getProperty("rabbitmq.port", "5672"));
        username = properties.getProperty("rabbitmq.username", "guest");
        password = properties.getProperty("rabbitmq.password", "guest");
        useSSL = properties.getProperty("rabbitmq.usessl", "false");

        factory = new ConnectionFactory();
        factory.setHost(host);
        factory.setPort(port);
        factory.setUsername(username);
        factory.setPassword(password);
        if("true".equalsIgnoreCase(useSSL)) {
            try {
                factory.useSslProtocol();
            } catch (KeyManagementException | NoSuchAlgorithmException e) {
                log.error("Exception while applying the tls for rabbitmq:", e);
            }
        }
        connection = factory.newConnection();
        connection.addBlockedListener(new RabbitMQBlockedListener());
        connection.addShutdownListener(new RabbitMQShutDownListener());

        channel = connection.createChannel();
    }

    public static RabbitMQUtil getInstance() {
        if(gmInstance == null) {
            synchronized (RabbitMQUtil.class) {
                if(gmInstance == null) {
                    try {
                        gmInstance = new RabbitMQUtil();
                    } catch (IOException | TimeoutException e) {
                        log.error("Exception in getInstance:", e);
                    } catch (Exception e) {
                        log.error("Exception in getInstance:", e);
                    }
                }
            }
        }
        return gmInstance;
    }

    public static void saveErrorMessagesInLogs(JsonObject obj, String queueName) {
        log.info("data to be saved for :"+queueName+" is:"+obj.toString());
    }

    public void saveMsgInQueue(JsonObject gson, String queueName) {
        this.executor.execute(new RabbitMQData(gson, queueName));
    }

    private class RabbitMQBlockedListener implements BlockedListener {
        @Override
        public void handleBlocked(String arg0) throws IOException {
            log.warn("blocked listener called:", arg0);
        }

        @Override
        public void handleUnblocked() throws IOException {
            log.warn("unblocked listener called:");
        }
    }

    private class RabbitMQShutDownListener implements ShutdownListener {
        @Override
        public void shutdownCompleted(ShutdownSignalException cause) {
            log.error("Shutdown event listener called:", cause);
            log.error("shutdown event listener:"+cause.isHardError());
        }
    }

    private class RabbitMQData implements Runnable{
        JsonObject obj;
        String queueName;
        public RabbitMQData(JsonObject obj, String queueName) {
            Thread.currentThread().setName("RabbitMQ Thread:"+obj.get("userid")+" -->"+queueName);
            this.obj = obj;
            this.queueName = queueName;
        }

        @Override
        public void run() {
            try {
                channel.queueDeclare(this.queueName, true, false, false, null);
                channel.basicPublish("", this.queueName, MessageProperties.PERSISTENT_BASIC, this.obj.toString().getBytes());
            } catch (Exception e) {
                log.info("Error while running the scheduled rabbitmq task:", e);
                log.info("data to be saved for :"+this.queueName+" is:"+this.obj.toString());
            }
        }
    }

    public static void saveRabbitMQData(JsonObject obj, String queueName) {
        RabbitMQUtil util = RabbitMQUtil.getInstance();
        if(util != null) 
            util.saveMsgInQueue(obj, queueName);
        else
            RabbitMQUtil.saveErrorMessagesInLogs(obj, queueName);
    }
}
包通用;
导入java.io.IOException;
导入java.io.InputStream;
导入java.security.KeyManagementException;
导入java.security.NoSuchAlgorithmException;
导入java.util.Properties;
导入java.util.concurrent.LinkedBlockingQueue;
导入java.util.concurrent.ThreadPoolExecutor;
导入java.util.concurrent.TimeUnit;
导入java.util.concurrent.TimeoutException;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入com.google.gson.JsonObject;
导入com.rabbitmq.client.BlockedListener;
导入com.rabbitmq.client.Channel;
导入com.rabbitmq.client.Connection;
导入com.rabbitmq.client.ConnectionFactory;
导入com.rabbitmq.client.MessageProperties;
导入com.rabbitmq.client.ShutdownListener;
导入com.rabbitmq.client.ShutdownSignalException;
公共类RabbitMQUtil{
私有静态记录器log=LoggerFactory.getLogger(“记录器”);
私有静态RabbitMQUtil gmInstance;
private ThreadPoolExecutor executor=新的ThreadPoolExecutor(1,1,10,TimeUnit.SECONDS,新的LinkedBlockingQueue(10000));
私有最终字符串属性\u文件\u NAME=“config/rabbitmq.PROPERTIES”;
私有最终属性=新属性();
私有字符串主机=null;
专用int端口=0;
私有字符串username=null;
私有字符串密码=null;
私有字符串useSSL=“false”;
私人连接工厂;
专用连接;
专用信道;
私有RabbitMQUtil()引发IOException、TimeoutException、Exception{
试一试{
InputStream stream=RabbitMQUtil.class.getClassLoader().getResourceAsStream(属性\文件\名称);
if(流!=null){
属性。加载(流);
}
}捕获(例外情况除外){
log.error(“加载rabbitmq属性文件时出现异常:”,ex);
}
host=properties.getProperty(“rabbitmq.host”、“localhost”);
port=Integer.parseInt(properties.getProperty(“rabbitmq.port”,“5672”);
username=properties.getProperty(“rabbitmq.username”、“guest”);
password=properties.getProperty(“rabbitmq.password”、“guest”);
usesl=properties.getProperty(“rabbitmq.usesl”,“false”);
工厂=新连接工厂();
setHost(主机);
工厂设置端口(端口);
setUsername(用户名);
出厂设置密码(密码);
if(“true”.equalsIgnoreCase(useSSL)){
试一试{
factory.UseSLProtocol();
}catch(KeyManagementException | nosuchalgorithme异常){
log.error(“为rabbitmq应用tls时出现异常:”,e);
}
}
connection=factory.newConnection();
addBlockedListener(新的RabbitMQBlockedListener());
addShutdownListener(新的RabbitMQShutDownListener());
channel=connection.createChannel();
}
公共静态RabbitMQUtil getInstance(){
if(gmInstance==null){
已同步(RabbitMQUtil.class){
if(gmInstance==null){
试一试{
gmInstance=new RabbitMQUtil();
}捕获(IOException | TimeoutException e){
log.error(“getInstance中的异常:”,e);
}捕获(例外e){
log.error(“getInstance中的异常:”,e);
}
}
}
}
返回gm实例;
}
公共静态void saveErrorMessagesInLogs(JsonObject对象,字符串queueName){
log.info(“为:“+queueName+”保存的数据是:“+obj.toString()”);
}
public void saveMsgInQueue(JsonObject gson,字符串queueName){
execute(新的RabbitMQData(gson,queueName));
}
私有类RabbitMQBlockedListener实现BlockedListener{
@凌驾
公共无效句柄锁定(字符串arg0)引发IOException{
log.warn(“被调用的阻塞侦听器:”,arg0);
}
@凌驾
public void handleunblock()引发IOException{
log.warn(“调用的未阻止侦听器:”;
}
}
私有类RabbitMQShutDownListener实现ShutdownListener{
@凌驾
公共无效关闭已完成(关闭信号异常原因){
错误(“调用的关闭事件侦听器:”,原因);
错误(“关机事件侦听器:+cause.isHardError());
}
}
私有类RabbitMQData实现可运行{
JsonObject对象;
字符串队列名称;
公共RabbitMQData(JsonObject对象,字符串queueName){
Thread.currentThread().setName(“RabbitMQ线程:“+obj.get(“userid”)+”-->“+queueName”);
this.obj=obj;
this.queueName=队列名称;
}
@凌驾
公开募捐{
试一试{
channel.queueDeclare(this.queueName,true,false,false,null);
channel.basicPublish(“”,this.queueName,MessageProperties.PERSISTENT_BASIC,this.obj.toString().getBytes());
}捕获(例外e){
log.info(“运行计划rabbitmq任务时出错:”,e);
log.info(“为:+this.queueName+”保存的数据是:+this.obj.toString());
}
}
}
公共静态void saverabitmqdata(JsonObj
    channel.close();
    conn.close();