JBoss运行期故障

  1. 平台:
    Tomcat 5.0.28+JBoss 4.2.0GA + JDK 5.0 + RedHat Enterprise Linux X64
  2. 症状:
    系统运行一段时间以后,会因为下面这个Exception而宕机。
    ERROR [org.jboss.remoting.transport.socket.ServerThread] Worker thread initialization failure
    java.io.EOFException
            at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:526)
            at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:369)
            at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:165)
  3. 解决:
    先采用Google和百度,搜索了很多帖子,但回答的很少。有的说是内存太少,有的说是64位,这些都是不太有力的解决方案,也无法解决问题。只好看源代码:

    在ServerThread.processInvocation(SocketWrapper socketWrapper)方法中有这样一段:
    InputStream inputStream = socketWrapper.getInputStream();
    if(performVersioning){
        version = readVersion(inputStream);
        if(version == -1)
            throw new EOFException();
    }
    
    这里就是扔出EOFException的元凶,当readVersion(inputStream) 返回-1的时候,就认为运行环境不对了。
    再看ServerThread.readVersion(InputStream inputStream)在做些啥子动作:
    private int readVersion(InputStream inputStream) throws IOException{
        if(trace)
            log.trace("blocking to read version from input stream");
        int version = inputStream.read();
        if(trace)
            log.trace("read version " + version + " from input stream");
        return version;
    }
    
    这里仅仅是一个简单的读操作,也就是从InputStream里面读不到流。而InputStream是从SocketWrapper  中直接通过SocketWrapper.getInputStream()来获取的。那这SocketWrapper又是如何创建的呢?
    在ServerThread.doRun()代码里面有如下动作:
    socketWrapper = createServerSocketWrapper(socket, timeout, invoker.getLocator().getParameters());
    ServerThread.createServerSocketWrapper(Socket socket, int timeout, Map metadata)代码段:
    if(serverSocketClass == null)
        serverSocketClass = ClassLoaderUtility.loadClass(serverSocketClassName, getClass());
    try{
        serverSocketConstructor = serverSocketClass.getConstructor(new Class[] {
        java.net.Socket.class, java.util.Map.class, java.lang.Integer.class
        });
    }catch(NoSuchMethodException e){
        serverSocketConstructor = serverSocketClass.getConstructor(new Class[] {
            java.net.Socket.class
        });
    }
    ServerSocketWrapper的这两个构造方法都定义在父类ClientSocketWrapper中:
    public ClientSocketWrapper(Socket socket) throws IOException{
        super(socket);
        createStreams(socket, null);
    }
    
    public ClientSocketWrapper(Socket socket, Map metadata, Integer timeout) throws Exception{
        super(socket, timeout);
        createStreams(socket, metadata);
    }
    这个InputStream就是从createStreams所创建的。
    ClientSocketWrapper.createStreams(Socket socket, Map metadata)方法中代码段:
    private InputStream in;
    
    in = createInputStream(serializationType, socket, unmarshaller);
    
    继续往下看ClientSocketWrapper.createInputStream(String serializationType, Socket socket, UnMarshaller unmarshaller):
    InputStream is = socket.getInputStream();
    
    if(unmarshaller instanceof PreferredStreamUnMarshaller){
        PreferredStreamUnMarshaller psum = (PreferredStreamUnMarshaller)unmarshaller;
        is = psum.getMarshallingStream(is);
    }
    
    return is;
    到这里大家应该都明白了这InputStream是如何创建的了,那么为啥这InputStream.read()返回-1呢,  这就  要 研究这个一直出现在代码中的Socket了,Socket是在ServerThread的构造方法中传递过来的, 实际上这个Socket就是JBoss到tomcat的一个连接。那么既然Socket初始化能成功,说明连接没有问题, 就只能从Socket返回的流上面来查找问题。那是否是Tomcat宕机了,从Socket无法返回流,而Socket连接却是正常的。打开Tomcat的 logs,确实,Tomcat宕机了,再对比Tomcat宕机时间和JBoss出现Exception的时间,前后一致,原来如此。只要Tomcat不宕机,JBoss就不会出这个Exception。
  4. 为什么Tomcat 5.0.28在JDK 5.0上面会出现PermGen错误,PermGen如何产生的,下回分解:
    http://www.thesorensens.org/2006/09/09/java-permgen-space-stringintern-xml-parsing/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值