我有以下代码来启动负载均衡器:
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();
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
在这方面的任何建议将不胜感激。
我试图根据错误文本更正代码,如下所示。
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