티스토리 뷰

728x90
반응형

발생 환경

현재 프로젝트에서 Dropwizard를 적용하고 있는데, Mesos와 연계할 부분이 생겨서 Mesos Client를 구성하고 Ning을 사용해서 비동기 Http 클라이언트를 구성하였다. 그런데 디버그 모드일 때는 상관이 없지만 (아마도 처리가 되는 시간적인 부분이 있는 듯 하다) 실행에서 java.io.IOException: Unable to establish loopback connection 오류가 발생하는 것을 확인하였다.

오류 메시지

4047 ERROR 2015-02-26 14:01:13 [main] com.ning.http.client.AsyncHttpClient[loadDefaultProvider:561] -Unable to instantiate provider com.ning.http.client.providers.netty.NettyAsyncHttpProvider. Trying other providers.
4053 ERROR 2015-02-26 14:01:13 [main] com.ning.http.client.AsyncHttpClient[loadDefaultProvider:564] -org.jboss.netty.channel.ChannelException: Failed to create a selector.
org.jboss.netty.channel.ChannelException: Failed to create a selector.
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.openSelector(AbstractNioSelector.java:343) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.(AbstractNioSelector.java:100) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.(AbstractNioWorker.java:52) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioWorker.(NioWorker.java:45) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioWorkerPool.createWorker(NioWorkerPool.java:45) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioWorkerPool.createWorker(NioWorkerPool.java:28) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorkerPool.newWorker(AbstractNioWorkerPool.java:143) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorkerPool.init(AbstractNioWorkerPool.java:81) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioWorkerPool.(NioWorkerPool.java:39) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioWorkerPool.(NioWorkerPool.java:33) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory.(NioClientSocketChannelFactory.java:151) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory.(NioClientSocketChannelFactory.java:133) ~[netty-3.9.2.Final.jar:na]
at com.ning.http.client.providers.netty.NettyAsyncHttpProvider.(NettyAsyncHttpProvider.java:261) ~[async-http-client-1.8.12.jar:na]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.7.0_67]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) ~[na:1.7.0_67]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.7.0_67]
at java.lang.reflect.Constructor.newInstance(Constructor.java:526) ~[na:1.7.0_67]
at com.ning.http.client.AsyncHttpClient.loadDefaultProvider(AsyncHttpClient.java:554) [async-http-client-1.8.12.jar:na]
at com.ning.http.client.AsyncHttpClient.(AsyncHttpClient.java:187) [async-http-client-1.8.12.jar:na]
at com.msfl.framework.web.NingAsyncHttpClient.(NingAsyncHttpClient.java:71) [classes/:na]
at com.msfl.framework.web.NingHttpClient.(NingHttpClient.java:48) [classes/:na]
at com.msfl.platform.mesos.client.McpMesosClientModule.configure(McpMesosClientModule.java:67) [MesosClient-0.0.1-SNAPSHOT.jar:na]
at com.google.inject.AbstractModule.configure(AbstractModule.java:62) [guice-4.0-beta5.jar:na]
at com.google.inject.spi.ElementsRecordingBinder.install(Elements.java:253) [guice-4.0-beta5.jar:na]
at com.google.inject.spi.Elements.getElements(Elements.java:108) [guice-4.0-beta5.jar:na]
at com.google.inject.internal.InjectorShellInitializer.run(PipeImpl.java:125) ~[na:1.7.0_67]
at sun.nio.ch.PipeImplInitializer.run(PipeImpl.java:97) ~[na:1.7.0_67]
… 49 common frames omitted

원인 유추

문제는 모듈 초기화 시점 (Google Guice 사용)에 AsyncHttpClient 를 생성하는 시점과 실제 생성된 객체를 사용하는 시점이 다르다는 점이고, 오류는 초기화 시점에 발생한다. 물론 그 이후에 실제 사용할 때는 별다른 문제가 없다. (이런 증상 때문에 시간적인 문제라고 유추하고 있다. ㅠㅠ)

해결 방법

정확한 해결방법이라고 볼 수는 없지만 JVM이 시작할 때 IP version prefs를 처리할 때 IPv6를 사용하기 때문인 것으로 보인다. 즉 Loopback
연결을 처리하면서 IPv6를 먼저 처리하고 실패 후에 IPv4를 시도하는 것으로 보인다는 것이다. 따라서 이런 상황에서는 IPv4를 사용하도록 JVM 옵션을 설정하면 된다.

-Djava.net.perferIPv4Stack=true

위의 옵션을 주고 실행을 하면 위에서 발생했던 오류는 해결이 된다. 위에서 언급한 발생 상황뿐만 아니라 아래와 같이 유사한 오류 메시지들이 발생하는 경우라면 적용해 보는 것이 좋다.

  • java.net.ConnectionException: Connection refused: connect 오류
  • java.io.IOException: Unable to establish loopback connection 오류

상기와 같이 오류의 원인이 두 가지로 나온다면 적용해서 해결될 가능성이 높다. (단, 실제 다른 이유 떄문일 수 있기 때문에 오류 메시지를 면밀하게 검토해봐야 한다)

Written by Morris (MSFL)

728x90
반응형
댓글
댓글쓰기 폼