问题
I have a Spring 3 application that receives messages via a non-RabbitMQ receiver, processes them and forwards via RabbitMQ. Each time a message is to be sent a new RabbitMQ connection is built. This seems a bit wasteful. I am just wondering if this is really necessary or if there is a reason why the connection cannot be held in a Singleton and only built once (for multiple sends). This is the sending method:
private void send(String routingKey, String message) throws Exception {
String exchange = applicationConfiguration.getAMQPExchange();
String ipAddress = applicationConfiguration.getAMQPHost();
String exchangeType = applicationConfiguration.getAMQPExchangeType();
String password = applicationConfiguration.getAMQPUser();
String user = applicationConfiguration.getAMQPPassword();
String virtualHost = applicationConfiguration.getAMQPVirtualHost();
String port = applicationConfiguration.getAMQPPort();
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername(user);
factory.setPassword(password);
factory.setVirtualHost(virtualHost);
factory.setPort(Integer.parseInt(port));
factory.setHost(ipAddress);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare(exchange, exchangeType);
channel.basicPublish(exchange, routingKey, null, message.getBytes());
log.debug(" [AMQP] Sent message with key {} : {}",routingKey, message);
connection.close();
}
or a possible singleton:
public class MyConnection {
private static MyConnection singleton = new MyConnection();
private static Connection connection;
private MyConnection() {
ConnectionFactory factory = new ConnectionFactory();
String exchange = applicationConfiguration.getAMQPExchange();
String ipAddress = applicationConfiguration.getAMQPHost();
String exchangeType = applicationConfiguration.getAMQPExchangeType();
String password = applicationConfiguration.getAMQPUser();
String user = applicationConfiguration.getAMQPPassword();
String virtualHost = applicationConfiguration.getAMQPVirtualHost();
String port = applicationConfiguration.getAMQPPort();
try {
factory.setUsername(user);
factory.setPassword(password);
factory.setVirtualHost(virtualHost);
factory.setPort(Integer.parseInt(port));
factory.setHost(ipAddress);
connection = factory.newConnection();
}
catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getInstance( ) {
return connection;
}
}
回答1:
The connection could be a singleton, and you can share it for multiple send. The channel should be one for thread.
you code could be:
private void send(String routingKey, String message) throws Exception {
Connection connection = MyConnection().getInstance();
Channel channel = connection.createChannel();
channel.exchangeDeclare(exchange, exchangeType);
channel.basicPublish(exchange, routingKey, null, message.getBytes());
log.debug(" [AMQP] Sent message with key {} : {}",routingKey, message);
channel.close();
}
You can decide to create and destroy a channel for each publish, or create it for your thread and reuse always the same channel.
EDIT** In order to create a sigleton read here: http://javarevisited.blogspot.it/2012/12/how-to-create-thread-safe-singleton-in-java-example.html
public class MySingletonConnection{
private static final MySingletonConnection INSTANCE = new MySingletonConnection();
private Connection myConnection;
private Singleton(){
// here you can init your connection parameter
}
public static MySingletonConnection getInstance(){
return INSTANCE;
}
public Connection getConnection( ) {
return connection;
}
}
This is one way to create a Singleton
private void send(String routingKey, String message) throws Exception {
Connection connection = MySingletonConnection().getInstance().getConnection();
来源:https://stackoverflow.com/questions/24910502/is-it-necessary-to-rebuild-rabbitmq-connection-each-time-a-message-is-to-be-sent