私が直面している問題を説明し、いくつかのコード サンプルでバックアップします。次のように宣言された LinkedBlockingQueue を使用しています。
private BlockingQueue<OutgoingMessage> outgoingMessageQueue = new LinkedBlockingQueue<OutgoingMessage>();
OutgoingMessage は、顧客に送信されるテキスト メッセージを表します。それを準備する Web サービス呼び出しによってキューに入れられ、データベースに保存され、キューに入れられます。アプリケーションは tomcat にデプロイされているため、このスレッドは HTTP プールからのスレッドです。
キューを処理し、実際のメッセージ送信を行うために別のスレッドを作成しました。無期限に実行され、次のようにキューで take() メソッドを呼び出します。
public void processOutgoingMessageQueue() {
try {
OutgoingMessage outgoingMessage = outgoingMessageQueue.take();
logger.debug(MessageFormat.format("Took outgoing message with id = [{0}] from queue", outgoingMessage.getId()));
this.forwardToCommunicator(outgoingMessage);
}
catch (InterruptedException e) {
logger.fatal("Interupted while waiting to process outgoing messages ", e); }
catch (Exception e) {
exceptionHandler.handle(e);
}
}
メソッド processOutgoingMessageQueue() がスレッドから呼び出されます。
これは、メッセージがキューに入れられ、後で定期的に送信されるという点で機能しますが、クライアント側 (Web サービス メソッドを呼び出した側) は、送信メッセージがキューに入れられた直後ではなく、スレッドがキューから取得すると、処理が終了します。Tomcat の HTTP プールのスレッドが、他のスレッドがメッセージ処理を終了するのを待ってから、Web サービスの応答をクライアントに返しているようです。これにより、ユーザーは別のメッセージをキューに入れる前にプロセスが完了するまで待たなければならないため、ユーザー エクスペリエンスが低下します。
以下は、メッセージが正常にキューに入れられたことを示すログです。
[DEBUG] 2012-07-08 23:09:51,707 [http-8080-8] SimpleServiceCommunicatorImpl: Received sendMessage request from serviceId = [3], charginId = [3], text [some text]
[DEBUG] 2012-07-08 23:09:51,721 [http-8080-8] SimpleServiceCommunicatorImpl: Request verification succeeded, creating outgoing message.
[INFO ] 2012-07-08 23:09:51,738 [http-8080-8] SimpleMessageCreatorImpl: Created outgoing message with id = [1,366] and payment invoice with id = [1,323]
[INFO ] 2012-07-08 23:09:51,738 [http-8080-8] Core: Enqueued outgoing message with id = [1,366]
これは、メッセージ送信リクエストが実行されていることを示すクライアント側のログです。
DEBUG 2012-07-08 23:09:51,702 CoreAdapter: Sending message with serviceId = [3], chargingId = [3], text = [some text]
INFO 2012-07-08 23:10:06,477 SimpleMessageSenderImpl: Created answer with core id = [1,366]
INFO 2012-07-08 23:10:06,477 SMSChatServiceImpl: Response message with result = 1366 sent to the customer
送信メッセージから約 15 秒後にリクエストが返されたことを示していますが、スレッド HTTP 8080-8 が実行する作業はこれ以上ありませんでした。
アップデート
これは、送信メッセージをキューに入れるメソッドです。
public void enqueueOutgoingMessage(OutgoingMessage outgoingMessage) {
try {
outgoingMessageQueue.put(outgoingMessage);
logger.info(MessageFormat.format("Enqueued outgoing message with id = [{0}]", outgoingMessage.getId()));
}
catch (InterruptedException e) {
logger.fatal("Interupted while waiting to enqueue outgoing message. ", e);
}
}
そして、これはキューを処理するスレッドです:
// outgoing message queue
this.outgoingMessageQueueProcessingThread = new Thread(new Runnable() {
public void run() {
while (!stopQueueProcessing) {
Core.this.processOutgoingMessageQueue();
}
}
});
this.outgoingMessageQueueProcessingThread.start();
stopQueueProcessing は、アプリのシャットダウン時に false に設定されるフラグです。
これは既知の tomcat または LinkedBlockingQueue の問題でしょうか?
誰にもアイデアがありますか?詳細が必要な場合は、喜んで提供します。