posts - 42,comments - 83,trackbacks - 0
        1:在weblogic cluster环境中,配置一个Distributed Queue, 它的QueueMember分布于cluster中不同managed server上的JMS Server上。JMS采用filestore方式存储消息。如果运行过程中,某一个managed server发生宕机的话,它的JMS Server上的消息在重起前,能不能被客户端consume掉?

        要回答这个问题,首先我们先看一下Distributed Queue的概念。所谓distributed queue, 顾名思义,分布式队列。它实际上是个逻辑Queue, 管理着一堆物理Queue。这些物理Queue对于客户端是透明的,即客户端发送、接收消息的时候,他们无法辨别这个消息到底发到哪个物理Queue,消息从哪个物理Queue接收到的。客户端看到的只是一个DQ,对于客户端已经足够了,至于发到哪,从哪接收,这些由Weblogic帮你去做。好了,回到这个问题,客户做JMSServer配置的时候,filestore不能共享文件,即一个filestore对应一个物理文件(这些文件可以通过ScanStore查看),而且jms server关联的filestore只能和它自己部署在同一managed server上。filestore只能部署到某个managed server上,其实无论是filestore,还是jdbcstore,都不能部署到cluster上。由于store不能部署到cluster上,jms server于是不能共享store(共享store会涉及到IO同步问题、事务问题)。当运行过程中,某个managed server宕机的话,在它启动之前,它上面filestore是不可用的,即filestore中的message不可读,message当然也就不能被其他客户端消费了。

        题外话:测试中,我让两个JMSServer使用不同的jdbc store, 但这两个jdbc store指向同一数据源。虽然active changes的时候,console不会看到什么错误,当log文件中会记录store.open()相关的错误,原因就在于两个不同的jms server使用了同一张叫做WLStore的表。第一个store用了这个表,第二个就不能使用了。重起这两个managed server, 后启动的那个不会变成running mode, 它会一直处于admin状态(jms service无法启动)。

        2:message consume的时候,会不会做load balance?
        不会!客户端做message send的时候,weblogic server会根据DQ的load banlance policy做load balance,即每调用一次send,都会做一次load balance,这样消息会在物理Queue之间均分(至于哪些物理Queue会参与均分,这跟loadbalance、serverAffinity设定有关),另外,当所有QueueMember中,只有某个Queue有consumer的时候,那么所有消息都会发送到这个QueueMember,然后被消费。客户端consume的时候,consumer被创建的时候,weblogic会分配一个物理Queue给它,即该consumer只能从这个物理Queue上接受消息。当然consumer被重新创建的时候,它们会粘连到不同的物理Queue上。

        3:Consumer粘连的物理Queue所在的server宕机,不重起consumer的话,它能不能继续收到消息? 物理Queue所在server重启之后,它能不能接收?
        两种情况都不能!这种问题典型场景就是message listener或message driven bean,问题2中我们提到,consumer创建的时候,它会粘连到某个物理Queue上,如果物理Queue所在的managed server宕机了,Queue就不会有消息进来(内存中都不存在这个物理Queue),当然这个consumer就不会收到消息了。对于第二种情况,即managed server重起之后,这个consumer如果不重起(或重建consumer)的话,它依然不会收到消息。对于这个问题,我们首先了解一下listener的机制: listener是客户端通过setMessageListener设定到consumer中的,这个设定会驻留在服务器端,当服务器端发现对应Queue上有消息的时候,他们通过callback机制,把消息传递到客户端的listener,listener的onMessage()被触发,执行相应的逻辑。因为listener信息是保存在服务器端的,当managed server宕机并重起的时候,它不会recover listener信息,即即使consumer对应的物理Queue上有消息进来的时候,managed server上的jms server也不会通过listener callback把消息deliver给consumer,因为它根本不知道这个consumer的存在。

        对于第二中情况,我觉得这应该是weblogic设计的问题,它不能让客户端感知到managed server的crash,客户端如果不知道后端发生什么的话,只能傻傻的等着。其实weblogic应该可以通过peerGone event抛出exception,客户端可以去处理这个异常,重建consumer还是退出,由客户端自己处理。这样做感觉会更好些吧!

        更新!!!!!!!   
        对于最后关于异常处理的问题,实际上weblogic(也包含其他AppServer Vendor)提供了异常监听功能,这是JMS规范的要求。具体的API是connection.setExceptionListener(JMSException e), 对于这个API,客户端程序要做的就是,提供一个实现JMSExceptionListener的listener类,然后在connection创建完成后,将这个listener实例注入到这个新建的connection上,这样这个连接发生JMSException的时候,ExceptionListener的onException()会被触发,客户可以在onException()中定义异常处理逻辑。下面是个exception listener的例子,
 1 import javax.jms.ExceptionListener;
 2 import
 javax.jms.JMSException;
 3 

 4 public class TestExceptionListener implements ExceptionListener {
 5 
    
 6     public void
 onException(JMSException e){
 7         System.out.println("jms exception is encountered, and onException is triggered!"
);
 8 
        e.printStackTrace();
 9 
    }
10 

11 }
        对于这个listener,我们可以将底层的JMSException输出,如果runtime过程中,对端managed server发生crash,我们可以看到如下的exception,

weblogic.jms.common.LostServerException: java.lang.Exception: weblogic.rjvm.PeerGoneException: ;
 nested exception is: 
        weblogic.utils.net.SocketResetException
        at weblogic.jms.client.JMSConnection.dispatcherPeerGone(JMSConnection.java:1348)
        at weblogic.messaging.dispatcher.DispatcherWrapperState.run(DispatcherWrapperState.java:571)
        at weblogic.messaging.dispatcher.DispatcherWrapperState.timerExpired(DispatcherWrapperState.java:496)
        at weblogic.timers.internal.TimerImpl.run(TimerImpl.java:265)
        at weblogic.work.ExecuteRequestAdapter.execute(ExecuteRequestAdapter.java:21)
        at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:145)
        at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:117)
Caused by: java.lang.Exception: weblogic.rjvm.PeerGoneException: ; nested except
ion is:
        weblogic.utils.net.SocketResetException
        at weblogic.messaging.dispatcher.DispatcherWrapperState.onDisconnect(DispatcherWrapperState.java:276)
        at weblogic.rjvm.RJVMImpl$DisconnectEventDeliverer.run(RJVMImpl.java:1603)
        ... 3 more
Caused by: weblogic.rjvm.PeerGoneException: ; nested exception is:
        weblogic.utils.net.SocketResetException
        at weblogic.rjvm.RJVMImpl.gotExceptionReceiving(RJVMImpl.java:941)
        at weblogic.rjvm.ConnectionManager.gotExceptionReceiving(ConnectionManager.java:1025)
        at weblogic.rjvm.MsgAbbrevJVMConnection.gotExceptionReceiving(MsgAbbrevJVMConnection.java:452)
        at weblogic.rjvm.t3.MuxableSocketT3.hasException(MuxableSocketT3.java:373)
        at weblogic.socket.SocketMuxer.deliverExceptionAndCleanup(SocketMuxer.java:739)
        at weblogic.socket.SocketMuxer.deliverHasException(SocketMuxer.java:692)

        at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:875)

        at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:792)
        at weblogic.socket.JavaSocketMuxer.processSockets(JavaSocketMuxer.java:283)
        at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:29)
        ... 3 more
Caused by: weblogic.utils.net.SocketResetException
        at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:863)

        ... 6 more




posted on 2009-04-22 09:35 走走停停又三年 阅读(4117) 评论(3)  编辑  收藏 所属分类: Weblogic

FeedBack:
# re: 和JMS Message Cosumer相关的几个问题
2009-06-16 20:58 | sunnycare
很好,解惑。  回复  更多评论
  
# re: 和JMS Message Cosumer相关的几个问题
2011-01-28 11:41 | fsfdsafd
fdsafdsafds  回复  更多评论
  
# re: 和JMS Message Cosumer相关的几个问题[未登录]
2013-11-28 10:13 | daniel
想请问您,出现了:PeerGoneException、SocketResetException
这样的异常,该如何处理呢?

希望能联系我:cacsgr@sina.com 谢谢!

我在用的过程中,报错,并且服务就停了:

Setup of JMS message listener invoker failed for destination 'SystemModule-0!Queue-2' - trying to recover. Cause: Could not roll back JMS transaction; nested exception is weblogic.jms.common.JMSException: weblogic.messaging.dispatcher.DispatcherException: java.rmi.RemoteException: Could not establish a connection with -169094487187672541S:127.0.0.1:[7002,7002,-1,-1,-1,-1,-1]:base_domain:Server-0, java.rmi.ConnectException: Destination unreachable; nested exception is:
java.net.ConnectException: Connection refused; No available router to destination; nested exception is:
java.rmi.ConnectException: Destination unreachable; nested exception is:
java.net.ConnectException: Connection refused; No available router to destination; nested exception is:
java.rmi.ConnectException: Could not establish a connection with -169094487187672541S:127.0.0.1:[7002,7002,-1,-1,-1,-1,-1]:base_domain:Server-0, java.rmi.ConnectException: Destination unreachable; nested exception is:
java.net.ConnectException: Connection refused; No available router to destination; nested exception is:
java.rmi.ConnectException: Destination unreachable; nested exception is:
java.net.ConnectException: Connection refused; No available router to destination  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: