LinkedBlockingQueue与put操作有关

时间:2012-07-09 19:02:37

标签: java multithreading tomcat queue blocking

我将尝试描述我面临的问题并使用一些代码示例进行备份。 我正在使用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问题?

有没有人有想法?需要更多细节,我很乐意提供它。

0 个答案:

没有答案