由于公司项目需要使用JMS来进行远程方法的调用,即使用了Spring提供的实现来完成。结果在并发到300左右时总是会出现“慢速消费者”的异常,查看Spring源代码实现看似每次访问都会新建一个会话。结果造成消费积压在JMS服务器上。只能自己动手,即然是消费者连接太多那就减少消费者吧。在客户端建立一个“响应消息池”来接收远程方法吃应消息,线程发送了调用方法消息之前先在此“响应消息池”注册一下表示需要接收消息然后发送调用的消息。
建立一个MessageConsumer实例,设定为用异步方式接收消费。在接收到消费后根据消息池中是否有注册来决定处理方式。同注后得到一个“消息探针”,里面用到了java.util.concurrent.CountDownLatch来帮助实现。
public class MessageProbe {    private Map<String, Serializable> returnValue;
    private CountDownLatch latch = new CountDownLatch(1);    public Map<String, Serializable> await() throws InterruptedException {
        latch.await();
        return returnValue;
    }    public Map<String, Serializable> await(long timeout)
            throws InterruptedException, TimeoutException {
        boolean noTimeout = false;
        noTimeout = latch.await(timeout, TimeUnit.MILLISECONDS);
        if (noTimeout) {
            return returnValue;
        } else {
            throw new TimeoutException("Response message timed out.");
        }
    }    public void obtainRetunValue(Map<String, Serializable> value) {
        returnValue = value;
        latch.countDown();
    }
}
客户端线程调用await方法,在远程方法没有返回调用结果之前阻塞。返回结果经由obtainRetunValue方法注入后即结束阻塞。各位看看,这样实现有没有什么问题。
我测试下来,并发到1700都正常。