Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Netty HTTP2 Request is timeout #6165

Closed
zmyer opened this issue Dec 30, 2016 · 8 comments
Closed

Netty HTTP2 Request is timeout #6165

zmyer opened this issue Dec 30, 2016 · 8 comments
Assignees
Labels
Milestone

Comments

@zmyer
Copy link

zmyer commented Dec 30, 2016

Expected behavior

When I run Netty Http2 helloworld example, it happened timeout request, How to do that, the example all run in localhost, and timeout set 5 seconds. It seem Netty Http2 codec module not too stable.

Actual behavior

Message received for unknown stream id 864103
Exception in thread "main" java.lang.IllegalStateException: Timed out waiting for response on stream id 864103
at io.netty.example.http2.helloworld.client.HttpResponseHandler.awaitResponses(HttpResponseHandler.java:77)
at io.netty.example.http2.helloworld.client.Http2Client.main(Http2Client.java:126)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Steps to reproduce

Minimal yet complete reproducer code (or URL to code)

Netty version

4.1.6.Final

JVM version (e.g. java -version)

jdk1.8.0_91-b14

OS version (e.g. uname -a)

Mac OS X EI Capitan 10.11.1

@Scottmitch
Copy link
Member

@zmyer - Can you please list the steps to reproduce this issue? Are you running the http2-server and http2-client on the same host? If so how are you running them and with what arguments?

@zmyer
Copy link
Author

zmyer commented Jan 2, 2017

@Scottmitch, yes, in the same host and all in default. I run http2 example repeatedly. My IDE is IDEA 2016.

@Scottmitch
Copy link
Member

I am unable to reproduce this issue. Please explicitly list the steps required to reproduce this issue.

@Scottmitch Scottmitch self-assigned this Jan 3, 2017
@zmyer
Copy link
Author

zmyer commented Jan 4, 2017

en, Ok, now I show such example below, and you can run it much more time.
at such example, I run in local, exception still happen,
Message received for unknown stream id 1857213
Exception in thread "main" java.lang.IllegalStateException: Timed out waiting for response on stream id 1857213
at io.netty.example.http2.helloworld.client.HttpResponseHandler.awaitResponses(HttpResponseHandler.java:81)
at io.netty.example.http2.helloworld.client.Http2Client.main(Http2Client.java:126)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

public final class Http2Client {

    static final boolean SSL = System.getProperty("ssl") != null;
    static final String HOST = System.getProperty("host", "127.0.0.1");
    static final int PORT = Integer.parseInt(System.getProperty("port", SSL ? "8443" : "19991"));
    static final String URL = System.getProperty("url", "/whatever");
    static final String URL2 = System.getProperty("url2");
    static final String URL2DATA = System.getProperty("url2data", "test data!");

    public static void main(String[] args) throws Exception {
        // Configure SSL.
        final SslContext sslCtx;
        if (SSL) {
            SslProvider provider = OpenSsl.isAlpnSupported() ? SslProvider.OPENSSL : SslProvider.JDK;
            sslCtx = SslContextBuilder.forClient()
                    .sslProvider(provider)
                /* NOTE: the cipher filter may not include all ciphers required by the HTTP/2 specification.
                 * Please refer to the HTTP/2 specification for cipher requirements. */
                    .ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
                    .trustManager(InsecureTrustManagerFactory.INSTANCE)
                    .applicationProtocolConfig(new ApplicationProtocolConfig(
                            Protocol.ALPN,
                            // NO_ADVERTISE is currently the only mode supported by both OpenSsl and JDK providers.
                            SelectorFailureBehavior.NO_ADVERTISE,
                            // ACCEPT is currently the only mode supported by both OpenSsl and JDK providers.
                            SelectedListenerFailureBehavior.ACCEPT,
                            ApplicationProtocolNames.HTTP_2,
                            ApplicationProtocolNames.HTTP_1_1))
                    .build();
        } else {
            sslCtx = null;
        }

        EventLoopGroup workerGroup = new NioEventLoopGroup();
        Http2ClientInitializer initializer = new Http2ClientInitializer(sslCtx, Integer.MAX_VALUE);

        try {
            // Configure the client.
            Bootstrap b = new Bootstrap();
            b.group(workerGroup);
            b.channel(NioSocketChannel.class);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.remoteAddress(HOST, PORT);
            b.handler(initializer);

            // Start the client.
            Channel channel = b.connect().syncUninterruptibly().channel();
            System.out.println("Connected to [" + HOST + ':' + PORT + ']');

            // Wait for the HTTP/2 upgrade to occur.
            Http2SettingsHandler http2SettingsHandler = initializer.settingsHandler();
            http2SettingsHandler.awaitSettings(5, TimeUnit.SECONDS);

            HttpResponseHandler responseHandler = initializer.responseHandler();
            int streamId = 3;
            HttpScheme scheme = SSL ? HttpScheme.HTTPS : HttpScheme.HTTP;
            AsciiString hostName = new AsciiString(HOST + ':' + PORT);
            System.err.println("Sending request(s)...");
            for (int index = 0; index < 100000000; index++) {
                if (URL != null) {
                    // Create a simple GET request.
                    FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, URL);
                    request.headers().add(HttpHeaderNames.HOST, hostName);
                    request.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), scheme.name());
                    request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP);
                    request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.DEFLATE);
                    responseHandler.put(streamId, channel.writeAndFlush(request), channel.newPromise());
                    streamId += 2;
                }
                if (URL2 != null) {
                    // Create a simple POST request with a body.
                    FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, POST, URL2,
                            Unpooled.copiedBuffer(URL2DATA.getBytes(CharsetUtil.UTF_8)));
                    request.headers().add(HttpHeaderNames.HOST, hostName);
                    request.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), scheme.name());
                    request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP);
                    request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.DEFLATE);
                    responseHandler.put(streamId, channel.writeAndFlush(request), channel.newPromise());
                    streamId += 2;
                }
                responseHandler.awaitResponses(5, TimeUnit.SECONDS);
            }
            System.out.println("Finished HTTP/2 request(s)");
            // Wait until the connection is closed.
            channel.close().syncUninterruptibly();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }
}

@Scottmitch
Copy link
Member

Scottmitch commented Jan 4, 2017

I was able to reproduce with 4.1.6.Final (on stream id 697) but I made it past stream id 5,000,000 with HEAD on the 4.1 branch and was unable to reproduce. Can you reproduce with HEAD on the 4.1 branch?

@zmyer
Copy link
Author

zmyer commented Jan 4, 2017

@Scottmitch , yes, When I change with HEAD on the 4.1 branch, it still happen.

@vongosling
Copy link

I've had a similar problem :-)

@Scottmitch Scottmitch added this to the 4.1.7.Final milestone Jan 7, 2017
@Scottmitch
Copy link
Member

I found some issues in the client example ... standby for a PR.

Scottmitch added a commit to Scottmitch/netty that referenced this issue Jan 10, 2017
Motivation:
The HTTP/2 helloworld client example has 2 bugs:
1. HttpResponseHandler has a map which is accessed from multiple threads, but the map is not thread safe.
2. Requests are flushed and maybe completely written and the responses may be received/processed by Netty before an element is inserted into the HttpResponseHandler map. This may result in an 'unexpected message' error even though the message has actually been sent.

Modifications:
- HttpResponseHandler should use a thread safe map
- Http2Client shouldn't flush until entries are added to the HttpResponseHandler map

Result:
Fixes netty#6165.
liuzhengyang pushed a commit to liuzhengyang/netty that referenced this issue Sep 10, 2017
Motivation:
The HTTP/2 helloworld client example has 2 bugs:
1. HttpResponseHandler has a map which is accessed from multiple threads, but the map is not thread safe.
2. Requests are flushed and maybe completely written and the responses may be received/processed by Netty before an element is inserted into the HttpResponseHandler map. This may result in an 'unexpected message' error even though the message has actually been sent.

Modifications:
- HttpResponseHandler should use a thread safe map
- Http2Client shouldn't flush until entries are added to the HttpResponseHandler map

Result:
Fixes netty#6165.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants