Java 对等方使用异步http客户端和netty重置连接

Java 对等方使用异步http客户端和netty重置连接,java,playframework-2.0,netty,asynchttpclient,Java,Playframework 2.0,Netty,Asynchttpclient,我在异步http客户端上遇到了一个奇怪的问题,netty作为http提供者,它是一个调用远程web服务的play应用程序,我们无法访问该服务。还需要注意的是,该服务位于SSL加密的域上,并且只向该域而不是IP进行响应。 堆栈跟踪: java.io.IOException: Connection reset by peer at sun.nio.ch.FileDispatcherImpl.read0(Native Method) ~[na:1.7.0_60] at sun.nio.ch.Socke

我在异步http客户端上遇到了一个奇怪的问题,netty作为http提供者,它是一个调用远程web服务的play应用程序,我们无法访问该服务。还需要注意的是,该服务位于SSL加密的域上,并且只向该域而不是IP进行响应。 堆栈跟踪:

java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcherImpl.read0(Native Method) ~[na:1.7.0_60]
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39) ~[na:1.7.0_60]
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) ~[na:1.7.0_60]
at sun.nio.ch.IOUtil.read(IOUtil.java:192) ~[na:1.7.0_60]
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:379) ~[na:1.7.0_60]
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:64) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:108) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:318) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89) ~[netty-3.9.2.Final.jar:na]
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178) ~[netty-3.9.2.Final.jar:na]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_60]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_60]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_60]
最奇怪的是,这种情况突然发生(这是一个客户使用的测试环境),这让我相信接收服务或网络出现了问题,但我无法找出问题所在,因为使用curl调用相同的url效果很好

我试图通过在本地使用异步http客户机(play使用它的WS接口)来隔离问题,并得到相同的错误,curl工作,使用javas URL api也工作。另外,当我使用JDKAsyncHttpProvider作为http提供程序时,它也可以很好地工作

   try {
        AsyncHttpClientConfig cf = new AsyncHttpClientConfig.Builder().build();
        // works if I use JDKAsyncHttpProvider..
        //AsyncHttpClient asyncHttpClient = new AsyncHttpClient(new JDKAsyncHttpProvider(cf));
        AsyncHttpClient asyncHttpClient = new AsyncHttpClient(cf);

        Future<Response> f = asyncHttpClient.prepareGet(nw).execute();
        Response r = f.get();

        System.out.println(r.getResponseBody());
    } catch(Exception e) {
        e.printStackTrace();
    }
TLS握手出现了问题,在不访问远程服务的情况下调试此问题时,我还能做些什么吗

再次更新,这次收到新的错误消息:

[write] MD5 and SHA1 hashes:  len = 149
0000: 01 00 00 91 03 01 53 AD   1C 54 D6 57 05 7A 89 E5  ......S..T.W.z..
0010: 55 60 01 2F 48 A5 BA EB   4C E6 96 68 E7 B8 2B 67  U`./H...L..h..+g
0020: A2 4C AF C8 9D 10 00 00   2A C0 09 C0 13 00 2F C0  .L......*...../.
0030: 04 C0 0E 00 33 00 32 C0   07 C0 11 00 05 C0 02 C0  ....3.2.........
0040: 0C C0 08 C0 12 00 0A C0   03 C0 0D 00 16 00 13 00  ................
0050: 04 00 FF 01 00 00 3E 00   0A 00 34 00 32 00 17 00  ......>...4.2...
0060: 01 00 03 00 13 00 15 00   06 00 07 00 09 00 0A 00  ................
0070: 18 00 0B 00 0C 00 19 00   0D 00 0E 00 0F 00 10 00  ................
0080: 11 00 02 00 12 00 04 00   05 00 14 00 08 00 16 00  ................
0090: 0B 00 02 01 00                                     .....
New I/O worker #2, WRITE: TLSv1 Handshake, length = 149
[Raw write]: length = 154
0000: 16 03 01 00 95 01 00 00   91 03 01 53 AD 1C 54 D6  ...........S..T.
0010: 57 05 7A 89 E5 55 60 01   2F 48 A5 BA EB 4C E6 96  W.z..U`./H...L..
0020: 68 E7 B8 2B 67 A2 4C AF   C8 9D 10 00 00 2A C0 09  h..+g.L......*..
0030: C0 13 00 2F C0 04 C0 0E   00 33 00 32 C0 07 C0 11  .../.....3.2....
0040: 00 05 C0 02 C0 0C C0 08   C0 12 00 0A C0 03 C0 0D  ................
0050: 00 16 00 13 00 04 00 FF   01 00 00 3E 00 0A 00 34  ...........>...4
0060: 00 32 00 17 00 01 00 03   00 13 00 15 00 06 00 07  .2..............
0070: 00 09 00 0A 00 18 00 0B   00 0C 00 19 00 0D 00 0E  ................
0080: 00 0F 00 10 00 11 00 02   00 12 00 04 00 05 00 14  ................
0090: 00 08 00 16 00 0B 00 02   01 00                    ..........
Hashed wheel timer #2, called closeOutbound()
Hashed wheel timer #2, closeOutboundInternal()
Hashed wheel timer #2, SEND TLSv1 ALERT:  warning, description = close_notify
Hashed wheel timer #2, WRITE: TLSv1 Alert, length = 2
Hashed wheel timer #2, called closeInbound()
Hashed wheel timer #2, fatal error: 80: Inbound closed before receiving peer's close_notify: possible truncation attack?
javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
Hashed wheel timer #2, SEND TLSv1 ALERT:  fatal, description = internal_error
Hashed wheel timer #2, Exception sending alert: java.io.IOException: writer side was already closed.
已更新、已解决:

远程主机将https证书配置为使用服务器名称指示SNI,这导致netty提供程序失败。我猜netty提供商还不支持SNI。

当你说“SSL加密域”时,你是说HTTPS

如果是,您可以使用WS-SSL中的调试功能:

或者直接使用
-Djavax.net.debug=all
设置JSSE的调试标志

另外,在application.conf中启用
logger.play.api.libs.ws=DEBUG
logger.org.asynchttpclient=DEBUG
,以获得最大的详细性


如果您愿意直接使用AsyncHttpClient,也可以直接更改提供程序,而无需通过WS。这意味着您可能不得不在onSuccess()回调中胡乱处理一个承诺,但是您创建了一个有限的类WS接口,如果这是一个问题,它将在将来返回给您。

我也遇到了同样的问题。我可以通过从Java6切换到Java7来解决这个问题。服务器名称指示(SNI)在Java 6中不受支持,但在Java 7中受支持,这是一个问题。

“通过对等方重置连接”表示连接的远程端将其关闭。你需要找出为什么远程软件会断开连接。我已经知道了,但是为什么我只有在使用Netty提供程序时才会出错,而不是在终端中使用curl时,或者在我的JDKAsyncHttpProvider示例中,我不知道,但是,找出远程软件为何会中断连接将是一条重要线索。远程服务由另一家公司拥有,我从他们那里得到的唯一信息是没有任何日志记录(我认为他们正在使用IIS和.Net webAPI)。我想我要问的是,我是否可以确保这不是我这边的错误。谢谢,我得到了一些更有趣的调试输出。我更新了问题。
[write] MD5 and SHA1 hashes:  len = 149
0000: 01 00 00 91 03 01 53 AD   1C 54 D6 57 05 7A 89 E5  ......S..T.W.z..
0010: 55 60 01 2F 48 A5 BA EB   4C E6 96 68 E7 B8 2B 67  U`./H...L..h..+g
0020: A2 4C AF C8 9D 10 00 00   2A C0 09 C0 13 00 2F C0  .L......*...../.
0030: 04 C0 0E 00 33 00 32 C0   07 C0 11 00 05 C0 02 C0  ....3.2.........
0040: 0C C0 08 C0 12 00 0A C0   03 C0 0D 00 16 00 13 00  ................
0050: 04 00 FF 01 00 00 3E 00   0A 00 34 00 32 00 17 00  ......>...4.2...
0060: 01 00 03 00 13 00 15 00   06 00 07 00 09 00 0A 00  ................
0070: 18 00 0B 00 0C 00 19 00   0D 00 0E 00 0F 00 10 00  ................
0080: 11 00 02 00 12 00 04 00   05 00 14 00 08 00 16 00  ................
0090: 0B 00 02 01 00                                     .....
New I/O worker #2, WRITE: TLSv1 Handshake, length = 149
[Raw write]: length = 154
0000: 16 03 01 00 95 01 00 00   91 03 01 53 AD 1C 54 D6  ...........S..T.
0010: 57 05 7A 89 E5 55 60 01   2F 48 A5 BA EB 4C E6 96  W.z..U`./H...L..
0020: 68 E7 B8 2B 67 A2 4C AF   C8 9D 10 00 00 2A C0 09  h..+g.L......*..
0030: C0 13 00 2F C0 04 C0 0E   00 33 00 32 C0 07 C0 11  .../.....3.2....
0040: 00 05 C0 02 C0 0C C0 08   C0 12 00 0A C0 03 C0 0D  ................
0050: 00 16 00 13 00 04 00 FF   01 00 00 3E 00 0A 00 34  ...........>...4
0060: 00 32 00 17 00 01 00 03   00 13 00 15 00 06 00 07  .2..............
0070: 00 09 00 0A 00 18 00 0B   00 0C 00 19 00 0D 00 0E  ................
0080: 00 0F 00 10 00 11 00 02   00 12 00 04 00 05 00 14  ................
0090: 00 08 00 16 00 0B 00 02   01 00                    ..........
Hashed wheel timer #2, called closeOutbound()
Hashed wheel timer #2, closeOutboundInternal()
Hashed wheel timer #2, SEND TLSv1 ALERT:  warning, description = close_notify
Hashed wheel timer #2, WRITE: TLSv1 Alert, length = 2
Hashed wheel timer #2, called closeInbound()
Hashed wheel timer #2, fatal error: 80: Inbound closed before receiving peer's close_notify: possible truncation attack?
javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
Hashed wheel timer #2, SEND TLSv1 ALERT:  fatal, description = internal_error
Hashed wheel timer #2, Exception sending alert: java.io.IOException: writer side was already closed.