[undertow-dev] Using UndertowClient from one server to call another server

Stuart Douglas sdouglas at redhat.com
Tue Aug 29 20:01:14 EDT 2017


It should be ok, just make sure you have set the max concurrent
streams high enough, with that said though you will probably get
better performance with a connection pool. If you have a single
connection that will be serviced by a single IO thread, and will be
limited by the speed that it can send over the TCP connection.

I am not sure how much difference it will make in your environment,
but in some situations it can make a huge difference.

Stuart

On Wed, Aug 30, 2017 at 9:53 AM, Steve Hu <stevehu at gmail.com> wrote:
> I've been using https all the time. Let me add a debug statement to check
> the response protocol to ensure that http2 is used all the time. Thanks for
> pointing to the right direction.
>
> Although HTTP2.0 supports multiplex, do you think it would be problem if too
> many concurrent requests go through the same connection? Should I create a
> connection poll to split the load to multiple connections like HTTP 1.1?
>
>
> On Tue, Aug 29, 2017 at 7:37 PM, Stuart Douglas <sdouglas at redhat.com> wrote:
>>
>> The issue is that you are attempting to use prior knowledge to connect
>> to a https endpoint. HTTPS endpoints must use ALPN instead.
>>
>> I did not notice you were attempting to use HTTPS in the original
>> issue. The code should not attempt an upgrade in this case. Is it
>> possible that ALPN is failing so normal HTTP/1 is used instead, then
>> the server closes the connection so your request fails due to the
>> connection being closed?
>>
>> Stuart
>>
>> On Wed, Aug 30, 2017 at 9:24 AM, Steve Hu <stevehu at gmail.com> wrote:
>> > Hi Stuart,
>> >
>> > I have created two servers with one calls another with h2c-prior to
>> > reproduce the issue. There is a README.md in the root folder with
>> > instructions.
>> >
>> > https://github.com/stevehu/server2server
>> >
>> > Thanks,
>> >
>> > Steve
>> >
>> > On Mon, Aug 28, 2017 at 11:01 PM, Stuart Douglas <sdouglas at redhat.com>
>> > wrote:
>> >>
>> >> That would be great. This is tested in the test suite so I am not sure
>> >> why
>> >> it is not working for you.
>> >>
>> >> Stuart
>> >>
>> >> On 29 Aug. 2017 12:59 pm, "Steve Hu" <stevehu at gmail.com> wrote:
>> >>
>> >> Yes. It is another Undertow server with HTTP 2.0 enabled. I can build a
>> >> repo with two servers to reproduce the issue if it is necessary.
>> >>
>> >> Thanks,
>> >>
>> >> Steve
>> >>
>> >> On Mon, Aug 28, 2017 at 10:43 PM, Stuart Douglas <sdouglas at redhat.com>
>> >> wrote:
>> >>>
>> >>> What is the endpoint that you are trying to connect to? Is it another
>> >>> Undertow server?
>> >>>
>> >>> Stuart
>> >>>
>> >>> On Tue, Aug 29, 2017 at 12:17 PM, Steve Hu <stevehu at gmail.com> wrote:
>> >>> > Hi Stuart,
>> >>> >
>> >>> > Thanks for the quick reply. I have opened an issue
>> >>> > https://issues.jboss.org/browse/UNDERTOW-1170
>> >>> >
>> >>> > Also, I have tried your workaround with h2c-prior:// but got the
>> >>> > following
>> >>> > error in the callback.
>> >>> >
>> >>> > java.nio.channels.ClosedChannelException
>> >>> > at
>> >>> >
>> >>> >
>> >>> > io.undertow.protocols.http2.Http2Channel.createStream(Http2Channel.java:827)
>> >>> > at
>> >>> >
>> >>> >
>> >>> > io.undertow.client.http2.Http2ClientConnection.sendRequest(Http2ClientConnection.java:195)
>> >>> > at
>> >>> >
>> >>> >
>> >>> > com.networknt.apic.handler.DataGetHandler.handleRequest(DataGetHandler.java:57)
>> >>> >
>> >>> >
>> >>> > On Mon, Aug 28, 2017 at 9:50 PM, Stuart Douglas
>> >>> > <sdouglas at redhat.com>
>> >>> > wrote:
>> >>> >>
>> >>> >> This looks like a bug in the client with regards to how it handles
>> >>> >> HTTP upgrade. If the second request is added before the initial
>> >>> >> upgrade request is fully processed you can get this error.
>> >>> >>
>> >>> >> If you file a JIRA I will look into it. For now a possible
>> >>> >> workaround
>> >>> >> would be to use prior knowledge rather than upgrade (by using a URL
>> >>> >> of
>> >>> >> the form h2c-prior://target:p8080/whatever).
>> >>> >>
>> >>> >> Stuart
>> >>> >>
>> >>> >> On Tue, Aug 29, 2017 at 11:25 AM, Steve Hu <stevehu at gmail.com>
>> >>> >> wrote:
>> >>> >> > Hi,
>> >>> >> >
>> >>> >> > I am trying to use UndertowClient to call another service in the
>> >>> >> > current
>> >>> >> > service handleRequest using HTTP 2.0. If I have concurrent
>> >>> >> > requests
>> >>> >> > to
>> >>> >> > the
>> >>> >> > current service, then I will get the following error.
>> >>> >> >
>> >>> >> > java.io.IOException: UT001033: Invalid connection state
>> >>> >> > at
>> >>> >> >
>> >>> >> >
>> >>> >> >
>> >>> >> > io.undertow.client.http.HttpClientConnection.sendRequest(HttpClientConnection.java:336)
>> >>> >> >
>> >>> >> > Since HTTP 2.0 connection is multiplex, so I use instance
>> >>> >> > variables
>> >>> >> > for
>> >>> >> > UndertowClient instance and ClientConnection instance and don't
>> >>> >> > close
>> >>> >> > the
>> >>> >> > connection for each call.
>> >>> >> >
>> >>> >> > My question is how many requests can go through the same
>> >>> >> > connection?
>> >>> >> > Is
>> >>> >> > the
>> >>> >> > Invalid connection state caused by too many requests in the same
>> >>> >> > connection?
>> >>> >> > If yes, I can use a connection pool just like the HTTP 1.1. Also,
>> >>> >> > is
>> >>> >> > it
>> >>> >> > possible that the server will close the connection if it is idle
>> >>> >> > for
>> >>> >> > a
>> >>> >> > period of time?
>> >>> >> >
>> >>> >> > Here is the handler code for reference.
>> >>> >> >
>> >>> >> > public class DataGetHandler implements HttpHandler {
>> >>> >> >     UndertowClient client = UndertowClient.getInstance();
>> >>> >> >     ClientConnection connection;
>> >>> >> >
>> >>> >> >     @Override
>> >>> >> >     public void handleRequest(HttpServerExchange exchange) throws
>> >>> >> > Exception
>> >>> >> > {
>> >>> >> >         List<String> list = new ArrayList<>();
>> >>> >> >         final CountDownLatch latch = new CountDownLatch(1);
>> >>> >> >         if(connection == null) {
>> >>> >> >             try {
>> >>> >> >                 connection = client.connect(new URI(apidHost),
>> >>> >> > Http2Client.WORKER, Http2Client.SSL, Http2Client.POOL,
>> >>> >> > enableHttp2 ?
>> >>> >> > OptionMap.create(UndertowOptions.ENABLE_HTTP2, true):
>> >>> >> > OptionMap.EMPTY).get();
>> >>> >> >             } catch (Exception e) {
>> >>> >> >                 logger.error("Exeption:", e);
>> >>> >> >                 throw new ClientException(e);
>> >>> >> >             }
>> >>> >> >         }
>> >>> >> >         final AtomicReference<ClientResponse> reference = new
>> >>> >> > AtomicReference<>();
>> >>> >> >         try {
>> >>> >> >             ClientRequest request = new
>> >>> >> > ClientRequest().setMethod(Methods.GET).setPath(apidPath);
>> >>> >> >             connection.sendRequest(request,
>> >>> >> > client.createClientCallback(reference, latch));
>> >>> >> >             latch.await();
>> >>> >> >             int statusCode = reference.get().getResponseCode();
>> >>> >> >             if(statusCode >= 300){
>> >>> >> >                 throw new Exception("Failed to call API D: " +
>> >>> >> > statusCode);
>> >>> >> >             }
>> >>> >> >             List<String> apidList =
>> >>> >> >
>> >>> >> >
>> >>> >> >
>> >>> >> > Config.getInstance().getMapper().readValue(reference.get().getAttachment(Http2Client.RESPONSE_BODY),
>> >>> >> >                     new TypeReference<List<String>>(){});
>> >>> >> >             list.addAll(apidList);
>> >>> >> >         } catch (Exception e) {
>> >>> >> >             logger.error("Exception:", e);
>> >>> >> >             throw new ClientException(e);
>> >>> >> >         }
>> >>> >> >         list.add("API C: Message 1");
>> >>> >> >         list.add("API C: Message 2");
>> >>> >> >
>> >>> >> >
>> >>> >> >
>> >>> >> >
>> >>> >> > exchange.getResponseSender().send(Config.getInstance().getMapper().writeValueAsString(list));
>> >>> >> >     }
>> >>> >> > }
>> >>> >> >
>> >>> >> >
>> >>> >> > _______________________________________________
>> >>> >> > undertow-dev mailing list
>> >>> >> > undertow-dev at lists.jboss.org
>> >>> >> > https://lists.jboss.org/mailman/listinfo/undertow-dev
>> >>> >
>> >>> >
>> >>
>> >>
>> >>
>> >
>
>


More information about the undertow-dev mailing list