2010-03-16 5 views
1

시스템 설정은 두 개의 Weblogic 10.3 서버로 구성됩니다. 하나는 프리젠 테이션 계층을 호스팅하고 다른 하나는 EJB를 호스팅합니다.Weblogic EJB 호출은 OptionalDataException으로 보통로드에서 실패하기 시작합니다.

java.rmi.RemoteException: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.io.OptionalDataException 

스택 추적 :

시스템은 다음과 같은 오류와 함께 실패하는 EJB 방법은 EJB 서버 시작에 대한 프리젠 테이션 서버에서 호출 후 약간의 시간 (몇 일 한)에 대한 중간 부하에서 잘 실행
java.io.OptionalDataException 
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1349) 
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) 
    at weblogic.utils.io.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:197) 
    at weblogic.rjvm.MsgAbbrevInputStream.readObject(MsgAbbrevInputStream.java:564) 
    at weblogic.utils.io.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:193) 
    at weblogic.jndi.internal.RootNamingNode_WLSkel.invoke(Unknown Source) 
    at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:589) 
    at weblogic.rmi.cluster.ClusterableServerRef.invoke(ClusterableServerRef.java:230) 
    at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:477) 
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363) 
    at weblogic.security.service.SecurityManager.runAs(Unknown Source) 
    at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:473) 
    at weblogic.rmi.internal.wls.WLSExecuteRequest.run(WLSExecuteRequest.java:118) 

첫 번째 OptionalDataException이 발생하면 모든 후속 호출이 동일한 결과로 실패합니다. 일부 출처는 클러스터 멀티 캐스트 포트가 잘못 구성된 것과 관련 될 수 있다고 제안합니다. 그러나 이러한 서버는 클러스터에 속하지 않습니다.

EJB 서버를 부팅하면 항상 일시적으로 문제가 해결되지만 문제가 다시 발생하는 것으로 보입니다.

업데이트 : 문제가 (아래 내 자신의 대답을 참조) 결국 소켓 연결 수에 오버 플로우 관련 하지 것 같다. 네트워크 클래스 로딩을 허용하지 않으면 일주일 동안 꾸준히 실행되어 프리젠 테이션 서버에서 OptionalDataExceptions를 다시 받기 시작했습니다 (아래의 스택 추적). 시스템이 일주일 동안 잘 작동하고 실패하기 시작하는 것은 매우 이상합니다.

javax.naming.CommunicationException [Root exception is java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.io.OptionalDataException] 
    at weblogic.jndi.internal.ExceptionTranslator.toNamingException(ExceptionTranslator.java:74) 
    at weblogic.jndi.internal.WLContextImpl.translateException(WLContextImpl.java:439) 
    at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:395) 
    at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:380) 
    at javax.naming.InitialContext.lookup(InitialContext.java:392) 
    ... 
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 

    java.io.OptionalDataException 
    at weblogic.rjvm.ResponseImpl.unmarshalReturn(ResponseImpl.java:234) 
    at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:348) 
    at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:259) 
    at weblogic.jndi.internal.ServerNamingNode_1030_WLStub.lookup(Unknown Source) 
    at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:392) 
    ... 38 more 
Caused by: java.io.OptionalDataException 
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1349) 
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) 
    at  
    weblogic.utils.io.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:197) 
    at weblogic.rjvm.MsgAbbrevInputStream.readObject(MsgAbbrevInputStream.java:564) 
    at  
weblogic.utils.io.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:193) 
    at weblogic.jndi.internal.RootNamingNode_WLSkel.invoke(Unknown Source) 
    at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:589) 
    at weblogic.rmi.cluster.ClusterableServerRef.invoke(ClusterableServerRef.java:230) 
    at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:477) 
    at   
weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363) 
    at weblogic.security.service.SecurityManager.runAs(Unknown Source) 
    at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:473) 
    at weblogic.rmi.internal.wls.WLSExecuteRequest.run(WLSExecuteRequest.java:118) 
    ... 2 more 

우리는 초기 문맥에게 꽤 표준 방법을 구하십시오 어떤 얻은 참조 유사한로 OptionalDataException 실패에

Properties p = new Properties(); 
p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); 
p.put(Context.PROVIDER_URL, serverPath); 
Context context = new InitialContext(p); 

는 또한 호출합니다. 프리젠 테이션 서버 만 부팅하면 일시적으로 문제가 해결됩니다.

+0

EJB 서버도 EOFException과 같은 예외를 동시에 throw합니까? EJB Remote가 서버에서 전혀 호출되지 않았는지 아니면 실패했는지에 대해 드릴 다운하려고합니다. – JoseK

+0

아주 좋은 지적입니다. 100 % 확실하지는 않지만 요청이 EJB 서버에 도착하기 전에 실패했다고 생각합니다. 적어도 EJB 서버 로그에는 아무것도 없습니다. 로깅 수준이 이후로 증가 했으므로이 문제가 다시 발생하면 확실하게 알 수 있습니다. 문제가 발생하는 동안 서버가 실행 중이며 내부 예약 된 작업을 처리 했으므로 적어도 서버가 데이터베이스에 연결할 수 있음을 알 수 있습니다. – MarkoU

+0

그리고이 오류가 일반적으로 발생하는 클러스터링과 관련하여 두 서버가 모든 클러스터의 일부가 아니거나 SAME 클러스터의 일부가 아닙니다. 많은 URL이이 오류에 대한 클러스터 멀티 캐스트 간섭을 제안합니다. – JoseK

답변

1

마지막으로 OptionalDataExceptions는 기록입니다. 간단히 말해 애플리케이션 코드에서 복잡한 값 객체 (원격 메소드 호출에 대한 반환 값으로 사용됨)는 내부 필드로 HashMap 데이터 구조를가집니다. 이 필드의 유형을 SynchronizedMap으로 변경 한 후 OptionalDataExceptions이 중지되었습니다. 레거시 코드 어딘가에이 맵이 스레드로부터 안전하지 않은 방식으로 처리되는 것 같습니다.

이상한 점은 WLS 8.1에서 아무런 문제도 발생하지 않았지만 WLS 10에서 모든 후속 원격 메소드 호출 (JNDI 조회 포함)이 실패하기 시작한 상태가 된 것입니다.

1

마지막으로 우리는이 문제에 대한 해결책을 찾았습니다. (편집 : 나중에 이것이 문제의 근본 원인이 아니라 별도의 심각한 문제임을 알았습니다. 최종 해결책은 아래 답변을 참조하십시오.) 우리는 다음과 같은 예외가 발생하기 시작하면 우리는 원인의 트랙에 도착 : 우리는 옵션을했다 EJB 서버와 다른 호스트에서 실행되는 프리젠 테이션 서버에

<BEA-000403> <IOException occurred on socket: Socket[addr=/x.x.x.x,port=3266,localport=7001] 
java.net.SocketException: Connection refused. 
java.net.SocketException: Connection refused 
at java.net.SocketInputStream.socketRead0(Native Method) 
at java.net.SocketInputStream.read(SocketInputStream.java:129) 
at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:887) 
at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:859) 
at weblogic.socket.DevPollSocketMuxer.processSockets(DevPollSocketMuxer.java:120) 
at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:29) 
at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:42) 
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:145) 
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:117) 

-Dweblogic.NetworkClassLoadingEnabled=true 

을 사용하면 EJB 서버에서 클래스 로딩을 가능하게 할 수 있습니다. 우리가 알지 못하는 것은이 옵션을 사용하면 엄청난 수의 네트워크 소켓이 열릴 수 있다는 것입니다. netstat을 사용하여 수천 개의 소켓이 CLOSE_WAIT 또는 FIN_WAIT_2 상태에 있음을 알 수있었습니다. 프리젠 테이션 서버의 war 파일에이 모든 것이 포함되어 있음에도 불구하고 웹 UI의 모든 요소가 클래스 외에도 EJB 서버에서로드 된 것으로 보입니다. Weblogic이 시작 스크립트의 파일에 대한 ulimit을 제거하기 때문에 많은 양의 소켓이 "너무 많은 파일"오류 메시지를 발생시키지 않았습니다. 테스트 서버를 사용하여 사용자가 웹 UI를 한 번 클릭하면 두 서버 사이에 약 30 개의 소켓이 열렸습니다.

이 옵션을 제거하고 필요한 모든 클래스를 포함하도록 프리젠 테이션 서버에 전쟁을 다시 패키징하여 네트워크 클래스 로딩을 제거했습니다. 이로 인해 두 서버 간의 소켓 연결 수가 1000에서 1로 줄어 들었습니다.

요약하면 가능한 경우 Weblogic에서 네트워크 클래스 로딩을 피하십시오.