我将尝试描述我面临的问题并使用一些代码示例进行备份。 我正在使用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
它显示在传出消息的aprox 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是一个在app shutdown时设置为false的标志。
这可能是已知的tomcat还是LinkedBlockingQueue问题?
有没有人有想法?需要更多细节,我很乐意提供它。