RabbitMQ にメッセージを送信するための REST API を作成しており、チャネルを作成/閉じるためのベスト プラクティスを理解しようとしていました。RabbitMQ Java クライアント API を使用しています。
RabbitMQPublisherConnection
現在、 RabbitMQ 接続をスプリング注入するクラスがあります。このクラスは、別のクラスにスプリング注入されRabbitMQPublisherChannel
ます。このクラスには、チャネルを作成する次の関数があります。
public class RabbitMQPublisherChannel { public Channel createChannel(String amqpExchange, String exchangeType, String queue, String routingKey, boolean durableExchange, boolean durableQueue, boolean autoDelete, com.rabbitmq.client.Connection connection) throws IOException { Channel channel = null; channel = connection.createChannel(); if ((amqpExchange != null) && !"".equals(amqpExchange.trim())) { if (log.isLoggable(Level.FINEST)) { log.finest("exchange:" + amqpExchange + ", type: " + exchangeType + ", durableExchange: " + durableExchange); } channel.exchangeDeclare(amqpExchange, exchangeType, durableExchange); channel.queueDeclare(queue, durableQueue, false, autoDelete, null); channel.queueBind(queue, amqpExchange, routingKey); } return channel; } }
RabbitMQPublisher
これで、 Spring Injectクラスの 3 番目のクラスが作成されましたRabbitMQPublisherChannel
。私のアプリケーション コンテキストは次のようになります。
<bean id="rabbitMQPublisher" class="com.rabbitmq.RabbitMQPublisher">
<property name="publisherChannel" ref="rabbitMQPublisherChannel"/>
</bean>
<bean id="rabbitMQPublisherChannel" class="com.rabbitmq.RabbitMQPublisherChannel">
<property name="publisherConnection" ref="rabbitMQPublisherConnection"/>
</bean>
<bean id="rabbitMQPublisherConnection" class="com.rabbitmq.RabbitMQPublisherConnection">
<property name="rabbitMQConnectionSettingMap">
.. connection ..
</property>
</bean>
このクラスRabbitMQPublisher
には、RabbitMQ にメッセージを発行する機能があります。
public boolean publishMessage(String message, String queueName){
try {
// Validate queue name
com.rabbitmq.client.Channel channel = publisherChannel.getRabbitMQChannel(queueName);
RabbitMQConnection settings = publisherChannel.getPublisherConnection().getRabbitMQConnectionSettingMap().get(queueName);
if (channel != null) {
channel.basicPublish(settings.getAmqpExchange(), settings.getAmqpRoutingKey(), null, message.getBytes());
publisherChannel.closeChannel(channel);
}
} catch (AlreadyClosedException e) {
return FAILURE_RESPONSE;
} catch (IOException e) {
return FAILURE_RESPONSE;
}
return SUCCESS_RESPONSE;
}
このアプリケーションは tomcat を介して実行されますが、AppDynamics でチャネルを閉じるのに、メッセージの発行にかかる合計時間の 47% がかかることに気付きました。チャネルを閉じる呼び出しを削除すると、この 47% の時間を 32 ミリ秒節約できますが、RabbitMQ 管理コンソールで、その接続のチャネル数が増加していることに気付きます。
だから私の質問は -
- tomcat が 1 秒あたり複数のリクエストを受け取ると仮定して、パブリッシュのたびにチャンネルを開閉するのは良い方法ですか?
- これは複数のスレッド間でチャネル プールを共有することをお勧めしますか ( RabbitMQ はこれを推奨していますが、次のようにも述べています
Even so, applications should prefer using a Channel per thread instead of sharing the same Channel across multiple threads.
)。これは、スレッドごとに新しいチャネルを作成することを意味しますか? - チャネルを閉じず、アイドル状態の RabbitMQ http api クリーンアップ チャネルを使用することをお勧めします。(これをお勧めしないでください)?
- 32ミリ秒節約する価値はありますか?
ありがとう