본문 바로가기
Programming/JAVA

[JAVA] Netty 클라이언트 재접속 연결 오류 (BlockingOperationException)

by Pendine 2021. 6. 21.
728x90

Exception log : io.netty.util.concurrent.BlockingOperationException: DefaultChannelPromise@45bfd093(incomplete)
at io.netty.util.concurrent.DefaultPromise.checkDeadLock(DefaultPromise.java:395)
at io.netty.channel.DefaultChannelPromise.checkDeadLock(DefaultChannelPromise.java:159)
at io.netty.util.concurrent.DefaultPromise.await(DefaultPromise.java:225)
at io.netty.channel.DefaultChannelPromise.await(DefaultChannelPromise.java:131)
at io.netty.channel.DefaultChannelPromise.await(DefaultChannelPromise.java:30)
at io.netty.util.concurrent.DefaultPromise.sync(DefaultPromise.java:337)
at io.netty.channel.DefaultChannelPromise.sync(DefaultChannelPromise.java:119)
at io.netty.channel.DefaultChannelPromise.sync(DefaultChannelPromise.java:30)

~~

 

 

log : 

| channel is Active : false 
| channel is Open : true 
| channel is Writable : true 
| channel is Registered : true 
| 채널 열림 

 

채널 연결상태 계속 확인하는 뽑아내면서

연결 종료시나 연결 시도 중

1. 망이 끊겨있거나,

2. 서버에서 접속을 거부하거나

3. 서버에 대한 접속정보가 없거나

4. 서버에 대한 접속 연결 시간 초과

에 대한 예외사항이 발생했을때 재접속 시도를 하는걸 확인하고,

테스트환경에서 잘되는걸 확인하고 프로그램을 배포했는데

계속 특정 장소에서 연결이 종료되어 있는걸 확인했다.

 

어떤문제인지 감도 못잡고있었는데

데드락 발생으로 인해서 생긴 예외가 존재한다는걸 알게 되었다.

 

BlockingOperationException

-> channelFuture.channel().eventLoop().schedule( Client,  ReconnectTime, TimeUnit.SECONDS);

 

리스너 클래스를 이용하여 이벤트 루프를 통해 재접속시도를 하게끔 해놨는데

이벤트 루프가 사용중인 상태에서 닫히지 않고 새로 재접속 시도를 할 경우 발생 할 수 있는 예외 라고한다.

 

따라서 channelFuture의 상태 중 연결 종료를 확인 할 수 있는 isDone() 메소르를 통해

채널 상태를 확인하고, 종료를 맡는 리스너 클래스에서 isDone()의 반환이 참(ture)이 아닐때,

연결대기시간만큼 대기 후 (Thread.Sleep(ReconnectTime)) 재확인하고,

닫혔을때 재접속 하도록 바꿨음.

 

 

----- 첫번째변경 시도 -----

접속할때 리스너 클래스들을 .addListener( 리스너 클래스 ).sync(). 를 이용해서 등록해줬는데 이때 sync() 메소드를 이용하면 데드락이 발생할 수 있기 때문에 스택오버플로에서 확인한 답변을 따라

sync()를 제거하고 사용해봤는데, 접속을 할 서버에서 응답이 없는경우 접속시도하는 연결이 증가함.

------------------------------

 

 

----- 두번째 변경시도 -----

연결이 폭증함을 확인하고 sync() 메소드는 유지.

접속할때 사용하는 리스너 클래스에서 ChannelFuture, channel의 상태를 확인하고 연결 종료 후 재접속을 시도하는 부분에서 연결이 제대로 종료됐는지 ChannelFuture클래스의 isDone() 메소드로 확인하는 부분을 로그로 남김.

<-- 변경했고 지켜보면서 확인 필요함. (테스트 할 때 어떻게해야 동일한 증상을 구현하는지 모르겠음...)

이 글에 대해서 딱히 추가적인 수정이 없으면 여기서 해결 완료로 끝낼 수 있음.

-------------------------------

 

해결안됐다.

구동중인 리눅스 서버 실행할때 스크립트를

#!/bin/bash

nohup java -jar 파일명.jar 1> /dev/null 2>&1 &

 

이렇게 짜서 실행도 시켜봤는데

재접속 시도를 잘하다가 중간이 어느순간부터 동작을 안함.

 

서버에 1분이상 응답이 없으면 연결을 끊고 재접속을 하도록 실행시켜놨음.

자체적으로 테스트할때는 아무이상 없는데

실제 환경에서는 어쩔대는 응답없을때 알아서 잘 끊고 재접속을 시도하는데

어쩔때는 그냥 연결이 유지되어있음.

 

전혀 이해가 안됨.

 

--- 해결

https://pendine.tistory.com/71

 

[JAVA / Netty] 클라이언트 재접속 오류 해결

https://pendine.tistory.com/42 [JAVA / Netty] 클라이언트 오류 해결 뭔가 찜찜하긴한데 해결된것같음 기존 소스코드에서 바꾼건 하나도 없음 일주일 이상을 테스트했고 어떤 상황에서도 문제없이 돌아갔

pendine.tistory.com

 

728x90

댓글