如何在与负载均衡器相关的http处理程序中读取请求正文

时间:2018-10-03 08:00:32

标签: java httprequest load-balancing undertow

我有以下代码来启动负载均衡器:

LoadBalancingProxyClient loadBalancer = new LoadBalancingProxyClientCustom()
        .addHost(new URI("http://localhost:8080"))
        .addHost(new URI("http://localhost:7777"))
        .setConnectionsPerThread(20);

Undertow reverseProxy = Undertow.builder()
        .addHttpListener(8081, "localhost")
        .setIoThreads(1)
        .setHandler(ProxyHandler.builder().setProxyClient(loadBalancer).setMaxRequestTime(30000000).build())
        .build();
reverseProxy.start();

LoadBalancingProxyClientCustom:

public class LoadBalancingProxyClientCustom extends LoadBalancingProxyClient {
    @Override
    protected Host selectHost(HttpServerExchange exchange) {

        exchange.startBlocking(); // another error without this line
        InputStream is = exchange.getInputStream();
        String bodyContent = toString(is);

        Field f = getField("hosts");
        Host[] hosts;
        try {
            hosts = (Host[]) f.get(this);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
        // I expect to choose  host depends  on body content
        return hosts[0];
    }


    private String toString(InputStream is) {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
            return br.lines().collect(Collectors.joining(System.lineSeparator()));
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    private Field getField(String fieldName) {
        Field f = null; //NoSuchFieldException
        try {
            f = LoadBalancingProxyClient.class.getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        f.setAccessible(true);
        return f;
    }
}

当我启动应用程序并发送任何请求时,我在日志中得到以下内容

07:54:20.195 [main] DEBUG io.undertow - Configuring listener with protocol HTTP for interface localhost and port 8081
07:54:38.089 [XNIO-1 I/O-1] DEBUG io.undertow.request.error-response - Setting error code 500 for exchange HttpServerExchange{ POST /api/v1/depot/ request {Accept=[*/*], Postman-Token=[90f08b87-fd1a-4be4-0e55-36afe99b5c37], Accept-Language=[ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,de;q=0.6], Cache-Control=[no-cache], Accept-Encoding=[gzip, deflate, br], Origin=[chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop], User-Agent=[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36], Connection=[keep-alive], Content-Length=[75], Content-Type=[application/json], Host=[localhost:8081]} response 500}
java.lang.RuntimeException: null
    at io.undertow.server.HttpServerExchange.setStatusCode(HttpServerExchange.java:1410)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:391)
    at io.undertow.server.protocol.http.HttpReadListener.handleEventWithNoRunningRequest(HttpReadListener.java:255)
    at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:136)
    at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:151)
    at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:92)
    at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:51)
    at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
    at org.xnio.ChannelListeners$10.handleEvent(ChannelListeners.java:291)
    at org.xnio.ChannelListeners$10.handleEvent(ChannelListeners.java:286)
    at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
    at org.xnio.nio.QueuedNioTcpServer$1.run(QueuedNioTcpServer.java:129)
    at org.xnio.nio.WorkerThread.safeRun(WorkerThread.java:582)
    at org.xnio.nio.WorkerThread.run(WorkerThread.java:466)
07:54:38.089 [XNIO-1 I/O-1] ERROR io.undertow.request - UT005071: Undertow request failed HttpServerExchange{ POST /api/v1/depot/ request {Accept=[*/*], Postman-Token=[90f08b87-fd1a-4be4-0e55-36afe99b5c37], Accept-Language=[ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,de;q=0.6], Cache-Control=[no-cache], Accept-Encoding=[gzip, deflate, br], Origin=[chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop], User-Agent=[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36], Connection=[keep-alive], Content-Length=[75], Content-Type=[application/json], Host=[localhost:8081]} response HttpServerExchange{ POST /api/v1/depot/ request {Accept=[*/*], Postman-Token=[90f08b87-fd1a-4be4-0e55-36afe99b5c37], Accept-Language=[ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,de;q=0.6], Cache-Control=[no-cache], Accept-Encoding=[gzip, deflate, br], Origin=[chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop], User-Agent=[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36], Connection=[keep-alive], Content-Length=[75], Content-Type=[application/json], Host=[localhost:8081]} response {}}}
java.lang.IllegalStateException: UT000126: Attempted to do blocking IO from the IO thread. This is prohibited as it may result in deadlocks
    at io.undertow.io.UndertowInputStream.read(UndertowInputStream.java:84)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)
    at java.io.BufferedReader$1.hasNext(BufferedReader.java:571)
    at java.util.Iterator.forEachRemaining(Iterator.java:115)
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at com.my.app.LoadBalancingProxyClientCustom.toString(LoadBalancingProxyClientCustom.java:56)
    at com.my.app.router.LoadBalancingProxyClientCustom.selectHost(LoadBalancingProxyClientCustom.java:38)
    at io.undertow.server.handlers.proxy.LoadBalancingProxyClient.getConnection(LoadBalancingProxyClient.java:251)
    at io.undertow.server.handlers.proxy.ProxyHandler$ProxyClientHandler.run(ProxyHandler.java:310)
    at io.undertow.util.SameThreadExecutor.execute(SameThreadExecutor.java:35)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:377)
    at io.undertow.server.protocol.http.HttpReadListener.handleEventWithNoRunningRequest(HttpReadListener.java:255)
    at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:136)
    at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:151)
    at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:92)
    at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:51)
    at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
    at org.xnio.ChannelListeners$10.handleEvent(ChannelListeners.java:291)
    at org.xnio.ChannelListeners$10.handleEvent(ChannelListeners.java:286)
    at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
    at org.xnio.nio.QueuedNioTcpServer$1.run(QueuedNioTcpServer.java:129)
    at org.xnio.nio.WorkerThread.safeRun(WorkerThread.java:582)
    at org.xnio.nio.WorkerThread.run(WorkerThread.java:466)
07:55:38.109 [XNIO-1 I/O-1] DEBUG io.undertow.request - Timing out idle connection from /127.0.0.1:49239

在这方面的任何建议将不胜感激。

P.S。

我试图根据错误文本更正代码,如下所示。

CountDownLatch countDownLatch = new CountDownLatch(1);

exchange.getRequestReceiver().receiveFullString(new Receiver.FullStringCallback() {
    @Override
    public void handle(HttpServerExchange exchange, String message) {
        System.out.println(message);
        countDownLatch.countDown();
    }
});
try {
    countDownLatch.await();
} catch (InterruptedException e) {
    e.printStackTrace();
}
....

在这种情况下,我会收到此错误。

08:09:08.184 [main] DEBUG io.undertow - Configuring listener with protocol HTTP for interface localhost and port 8081
{
  "dayCount": -1,
  "startDate": "2018-10-02",
  "templateId": 3434
}
08:09:29.126 [XNIO-1 I/O-1] DEBUG io.undertow.server.handlers.proxy - Sending request ClientRequest{path='/api/v1/depot/', method=POST, protocol=HTTP/1.1} to target localhost/127.0.0.1:8080 for exchange HttpServerExchange{ POST /api/v1/depot/ request {Accept=[*/*], Postman-Token=[87cce0ca-af75-4c28-515e-207469f51037], Accept-Language=[ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,de;q=0.6], Cache-Control=[no-cache], Accept-Encoding=[gzip, deflate, br], Origin=[chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop], User-Agent=[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36], Connection=[keep-alive], Content-Length=[75], Content-Type=[application/json], Host=[localhost:8081]} response ClientRequest{path='/api/v1/depot/', method=POST, protocol=HTTP/1.1}}
08:09:29.132 [XNIO-1 I/O-1] DEBUG io.undertow.server.handlers.proxy - Sent request ClientRequest{path='/api/v1/depot/', method=POST, protocol=HTTP/1.1} to target 127.0.0.1 for exchange HttpServerExchange{ POST /api/v1/depot/ request {Accept=[*/*], Postman-Token=[87cce0ca-af75-4c28-515e-207469f51037], Accept-Language=[ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,de;q=0.6], Cache-Control=[no-cache], Accept-Encoding=[gzip, deflate, br], Origin=[chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop], User-Agent=[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36], Connection=[keep-alive], Content-Length=[75], Content-Type=[application/json], Host=[localhost:8081]} response ClientRequest{path='/api/v1/depot/', method=POST, protocol=HTTP/1.1}}
08:09:29.135 [XNIO-1 I/O-1] DEBUG io.undertow.request.io - Fixed length stream closed with with 75 bytes remaining
08:09:29.136 [XNIO-1 I/O-1] DEBUG io.undertow.client.http.HttpClientExchange - request terminated for request to localhost/127.0.0.1:8080 /api/v1/depot/
08:09:29.138 [XNIO-1 I/O-1] ERROR io.undertow.proxy - UT005028: Proxy request to /api/v1/depot/ failed
io.undertow.server.TruncatedResponseException: null
    at io.undertow.client.http.HttpRequestConduit.truncateWrites(HttpRequestConduit.java:711)
    at io.undertow.conduits.AbstractFixedLengthStreamSinkConduit.terminateWrites(AbstractFixedLengthStreamSinkConduit.java:256)
    at org.xnio.conduits.ConduitStreamSinkChannel.shutdownWrites(ConduitStreamSinkChannel.java:178)
    at io.undertow.channels.DetachableStreamSinkChannel.shutdownWrites(DetachableStreamSinkChannel.java:79)
    at io.undertow.server.handlers.proxy.ProxyHandler$HTTPTrailerChannelListener.handleEvent(ProxyHandler.java:754)
    at io.undertow.server.handlers.proxy.ProxyHandler$ProxyAction$1.completed(ProxyHandler.java:646)
    at io.undertow.server.handlers.proxy.ProxyHandler$ProxyAction$1.completed(ProxyHandler.java:561)
    at io.undertow.client.http.HttpClientExchange.invokeReadReadyCallback(HttpClientExchange.java:212)
    at io.undertow.client.http.HttpClientConnection.initiateRequest(HttpClientConnection.java:410)
    at io.undertow.client.http.HttpClientConnection.sendRequest(HttpClientConnection.java:343)
    at io.undertow.server.handlers.proxy.ProxyHandler$ProxyAction.run(ProxyHandler.java:561)
    at io.undertow.util.SameThreadExecutor.execute(SameThreadExecutor.java:35)
    at io.undertow.server.HttpServerExchange.dispatch(HttpServerExchange.java:815)
    at io.undertow.server.handlers.proxy.ProxyHandler$ProxyClientHandler.completed(ProxyHandler.java:316)
    at io.undertow.server.handlers.proxy.ProxyHandler$ProxyClientHandler.completed(ProxyHandler.java:290)
    at io.undertow.server.handlers.proxy.ProxyConnectionPool.connectionReady(ProxyConnectionPool.java:338)
    at io.undertow.server.handlers.proxy.ProxyConnectionPool.access$900(ProxyConnectionPool.java:61)
    at io.undertow.server.handlers.proxy.ProxyConnectionPool$2.completed(ProxyConnectionPool.java:286)
    at io.undertow.server.handlers.proxy.ProxyConnectionPool$2.completed(ProxyConnectionPool.java:273)
    at io.undertow.client.http.HttpClientProvider.handleConnected(HttpClientProvider.java:156)
    at io.undertow.client.http.HttpClientProvider.access$000(HttpClientProvider.java:51)
    at io.undertow.client.http.HttpClientProvider$2.handleEvent(HttpClientProvider.java:127)
    at io.undertow.client.http.HttpClientProvider$2.handleEvent(HttpClientProvider.java:124)
    at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
    at org.xnio.nio.WorkerThread$ConnectHandle.handleReady(WorkerThread.java:326)
    at org.xnio.nio.WorkerThread.run(WorkerThread.java:561)
08:09:29.139 [XNIO-1 I/O-1] DEBUG io.undertow.request.error-response - Setting error code 503 for exchange HttpServerExchange{ POST /api/v1/depot/ request {Accept=[*/*], Postman-Token=[87cce0ca-af75-4c28-515e-207469f51037], Accept-Language=[ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,de;q=0.6], Cache-Control=[no-cache], Accept-Encoding=[gzip, deflate, br], Origin=[chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop], User-Agent=[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36], Connection=[keep-alive], Content-Length=[75], Content-Type=[application/json], Host=[localhost:8081]} response 503}
java.lang.RuntimeException: null
    at io.undertow.server.HttpServerExchange.setStatusCode(HttpServerExchange.java:1410)
    at io.undertow.server.handlers.proxy.ProxyHandler.handleFailure(ProxyHandler.java:668)
    at io.undertow.server.handlers.proxy.ProxyHandler$HTTPTrailerChannelListener.handleEvent(ProxyHandler.java:769)
    at io.undertow.server.handlers.proxy.ProxyHandler$ProxyAction$1.completed(ProxyHandler.java:646)
    at io.undertow.server.handlers.proxy.ProxyHandler$ProxyAction$1.completed(ProxyHandler.java:561)
    at io.undertow.client.http.HttpClientExchange.invokeReadReadyCallback(HttpClientExchange.java:212)
    at io.undertow.client.http.HttpClientConnection.initiateRequest(HttpClientConnection.java:410)
    at io.undertow.client.http.HttpClientConnection.sendRequest(HttpClientConnection.java:343)
    at io.undertow.server.handlers.proxy.ProxyHandler$ProxyAction.run(ProxyHandler.java:561)
    at io.undertow.util.SameThreadExecutor.execute(SameThreadExecutor.java:35)
    at io.undertow.server.HttpServerExchange.dispatch(HttpServerExchange.java:815)
    at io.undertow.server.handlers.proxy.ProxyHandler$ProxyClientHandler.completed(ProxyHandler.java:316)
    at io.undertow.server.handlers.proxy.ProxyHandler$ProxyClientHandler.completed(ProxyHandler.java:290)
    at io.undertow.server.handlers.proxy.ProxyConnectionPool.connectionReady(ProxyConnectionPool.java:338)
    at io.undertow.server.handlers.proxy.ProxyConnectionPool.access$900(ProxyConnectionPool.java:61)
    at io.undertow.server.handlers.proxy.ProxyConnectionPool$2.completed(ProxyConnectionPool.java:286)
    at io.undertow.server.handlers.proxy.ProxyConnectionPool$2.completed(ProxyConnectionPool.java:273)
    at io.undertow.client.http.HttpClientProvider.handleConnected(HttpClientProvider.java:156)
    at io.undertow.client.http.HttpClientProvider.access$000(HttpClientProvider.java:51)
    at io.undertow.client.http.HttpClientProvider$2.handleEvent(HttpClientProvider.java:127)
    at io.undertow.client.http.HttpClientProvider$2.handleEvent(HttpClientProvider.java:124)
    at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
    at org.xnio.nio.WorkerThread$ConnectHandle.handleReady(WorkerThread.java:326)
    at org.xnio.nio.WorkerThread.run(WorkerThread.java:561)
08:10:29.138 [XNIO-1 I/O-1] ERROR io.undertow.proxy - UT005028: Proxy request to /api/v1/depot/ failed
java.io.IOException: UT001000: Connection closed
    at io.undertow.client.http.HttpClientConnection$ClientReadListener.handleEvent(HttpClientConnection.java:572)
    at io.undertow.client.http.HttpClientConnection$ClientReadListener.handleEvent(HttpClientConnection.java:510)
    at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
    at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
    at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88)
    at org.xnio.nio.WorkerThread.run(WorkerThread.java:561)
08:10:29.143 [XNIO-1 I/O-1] DEBUG io.undertow.client.http.HttpClientConnection - close called on connection to localhost/127.0.0.1:8080
08:10:29.144 [XNIO-1 I/O-1] DEBUG io.undertow.request.io - Fixed length stream closed with with 75 bytes remaining
08:10:29.144 [XNIO-1 I/O-1] DEBUG io.undertow.client.http.HttpClientConnection - connection to localhost/127.0.0.1:8080 closed

0 个答案:

没有答案