当前位置: 首页 > 知识库问答 >
问题:

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

牟嘉
2023-03-14

我在使用netty作为http提供者的异步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();
    }

因为我使用的是play framework,所以我不能更改提供程序。

我目前被卡住了,我正在询问问题的指针,或者我调试的下一步。

更新:在调试选项全部打开的情况下,我得到以下错误:

Extension ec_point_formats, formats: [uncompressed]
***
[write] MD5 and SHA1 hashes:  len = 149
0000: 01 00 00 91 03 01 53 AD   17 DD 91 78 24 7E 9A 58  ......S....x$..X
0010: 0E CA D9 ED 22 5A A9 DF   3F 4C DD 25 58 E1 E6 C1  ...."Z..?L.%X...
0020: 4C 63 3E 11 78 1E 00 00   2A C0 09 C0 13 00 2F C0  Lc>.x...*...../.
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 17 DD 91  ...........S....
0010: 78 24 7E 9A 58 0E CA D9   ED 22 5A A9 DF 3F 4C DD  x$..X...."Z..?L.
0020: 25 58 E1 E6 C1 4C 63 3E   11 78 1E 00 00 2A C0 09  %X...Lc>.x...*..
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                    ..........
09:06:05.883 [New I/O worker #2] DEBUG c.n.h.c.p.n.NettyAsyncHttpProvider - Unexpected I/O exception on channel [id: 0x9820cfc1, /192.168.101.123:41411 => domain/148.136.157.62:443]
java.io.IOException: Connection reset by peer

所以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-certificate配置为使用导致netty提供程序失败的服务器名称指示SNI。我猜netty提供者还不支持SNI。

共有2个答案

关冠宇
2023-03-14

我也有同样的问题。我通过从Java 6号切换到Java 7号来解决这个问题。这是服务器名称指示(SNI)在Java 6中不被支持的问题,但在Java 7中被支持。

岳景明
2023-03-14

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

如果是,您可以使用WS SSL中的调试功能:http://www.playframework.com/documentation/2.3.x/debuggingssl

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

此外,在application.conf中打开logger.play.api.libs.ws=debuglogger.org.asynchttpclient=debug以获得最大的详细度。

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

 类似资料:
  • 我试图理解netty http客户端连接池。如果是NIO和异步的,那么这个连接池的意义是什么? 例如:如果服务A调用服务B,并且服务A的客户端连接池计数设置为50,那么这是否意味着我们最多只能发出50个并行请求? 更新: 我在3.5秒内完成了所有通话。理想情况下,有一个连接,我应该在150秒内完成。

  • 我正在使用Android异步Http客户端。我的代码看起来像这样,并且运行良好。 我实现了一个静态HTTP客户端。我的服务器返回这个JSON数据。我不想将其视为字符串并将其转换回JSON。但是当我将其更改为eclipse告诉我 new AsyncHttpResponseHandler(){}类型的onSuccess(JSONObject)方法必须重写或实现超类型方法

  • 我正在构建一个tcp客户端来接收和发送消息。我按照Netty用户指南中的步骤编写了一个简单的tcp客户端,其中包含一个扩展的自定义处理程序。 在hander中,我存储了< code > ChannelHandlerContext : 然后我有一个发送方法,它使用发送消息: 我发现的另一个选项是在客户机类中使用

  • 异步Http客户端 Get方式 1.使用域名形式 use AsyncHttp; //直接使用域名, get方式 $http = new AsyncHttp('http://groupco.com'); //设置2s超时 $http->setTimeout(2); //$http->setCookies(['token' => 'xxxx']);

  • 在Netty中创建客户端连接时,我有一个问题。 这里,为什么我们没有一个bind方法,将通道绑定到发起客户端连接的端口(在客户端)?我们唯一需要提供的就是给出服务器地址和端口如下: 这是在客户端还是服务器端创建了一个新的通道?此通道绑定在客户端的哪个端口? 我们在执行服务器端引导时进行绑定,如下所示 我很困惑,不明白客户端从哪个端口向服务器发送数据,使用的是什么通道?

  • 我正在尝试将我的应用程序从apache http组件客户端切换到异步版本。目标是能够处理更多的出站连接(在不久的将来)。请求的负载非常小( 与同步版本的apache超文本传输协议客户端,通过把大约200请求/秒。平均响应时间约为100ms/请求。我在最大180ms后中止请求。 切换到异步后,响应时间增加了20ms/请求。吞吐量也降低到160/秒。中止的请求数量增加了一倍。 这是在对应用程序进行了很