Jetty 9.4.14 ProxyServlet 增加或禁用超时
Jetty 9.4.14 ProxyServlet increase or disable timeout
我正在使用嵌入式码头 (9.4.14.v20181114) 来实现以下设置
.
如图所示,所有客户端都在访问代理服务器,并且根据一些业务规则,代理转发到其中一个 Web 服务器
使用码头的 ProxyServlet#rewriteTarget
方法。为此,我定义了一个新的 class ,它扩展了 ProxyServlet 并覆盖了 rewriteTarget
图片中的每个服务器都部署在不同的机器上。
一些客户端请求需要时间来处理,事实证明,如果请求需要超过 30 秒,代理会用
响应客户端
HTTP/1.1 504 Gateway Timeout
Date: Tue, 15 Jan 2019 09:04:37 GMT
Connection: close
Content-Type: application/json"
有没有办法增加此超时或完全删除它。
我尝试了以下 2 种方法,但都没有用
- 设置ServerConnector的idleTimeout
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setHost(ip);
connector.setPort(port);
connector.setIdleTimeout(45000);
server.setConnectors(new Connector[] { connector });
- 在覆盖
rewriteTarget
期间,我设置了一个 this.setTimeout(45000);
public class RoutingServlet extends ProxyServlet {
...
@Override
protected String rewriteTarget(HttpServletRequest request) {
this.setTimeout(45000);
// ... business logic based on request body and headers ...
return rewrittenUrl;
}
...
}
这两种方法都没有任何效果,在第 30 秒后,代理用 HTTP/1.1 504 Gateway Timeout
响应客户端,而实际处理请求的 Web 服务器仍在处理它。
您有 2 个空闲超时需要担心,但最终听起来您收到的错误来自基于代理的客户端 (due to the 504 Gateway Timeout response)。
但在我们去那里之前,请确保您的 ServerConnector
设置了合理的空闲超时(应该比您的代理客户端的值更高)。这控制了您的 "Client" 和 "ProxyServer" 之间的连接空闲超时(根据您的图表)
接下来,如果您使用 AsyncProxyServlet
之类的东西,只需设置 "idleTimeout"
初始参数 (which defaults to "30000"
if unspecified)。这控制了 "ProxyServer" 和 "Jetty Server" 之间的空闲超时(根据图表)
例如:
Server server = new Server();
HttpConfiguration http_config = new HttpConfiguration();
http_config.setSendServerVersion(true);
http_config.setSendDateHeader(false);
ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(http_config));
http.setPort(8080);
http.setIdleTimeout(45000);
server.addConnector(http);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
ServletHolder proxyHolder = new ServletHolder("proxy", AsyncProxyServlet.class);
proxyHolder.setInitParameter("idleTimeout", "44000");
context.addServlet(proxyHolder, "/proxy");
ServletHolder defHolder = new ServletHolder("default", DefaultServlet.class);
context.addServlet(defHolder, "/");
HandlerList handlers = new HandlerList();
handlers.addHandler(context);
handlers.addHandler(new DefaultHandler());
server.setHandler(handlers);
server.start();
server.join(); // wait for server thread to finish
或者,您也可以在自定义 AsyncProxyServlet
中执行此操作。
package jetty.proxy;
import javax.servlet.ServletException;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.proxy.AsyncProxyServlet;
public class MyProxyServlet extends AsyncProxyServlet
{
@Override
protected HttpClient createHttpClient() throws ServletException {
HttpClient client = super.createHttpClient();
client.setIdleTimeout(44000);
return client;
}
}
我正在使用嵌入式码头 (9.4.14.v20181114) 来实现以下设置
如图所示,所有客户端都在访问代理服务器,并且根据一些业务规则,代理转发到其中一个 Web 服务器
使用码头的 ProxyServlet#rewriteTarget
方法。为此,我定义了一个新的 class ,它扩展了 ProxyServlet 并覆盖了 rewriteTarget
图片中的每个服务器都部署在不同的机器上。
一些客户端请求需要时间来处理,事实证明,如果请求需要超过 30 秒,代理会用
响应客户端HTTP/1.1 504 Gateway Timeout
Date: Tue, 15 Jan 2019 09:04:37 GMT
Connection: close
Content-Type: application/json"
有没有办法增加此超时或完全删除它。
我尝试了以下 2 种方法,但都没有用
- 设置ServerConnector的idleTimeout
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setHost(ip);
connector.setPort(port);
connector.setIdleTimeout(45000);
server.setConnectors(new Connector[] { connector });
- 在覆盖
rewriteTarget
期间,我设置了一个this.setTimeout(45000);
public class RoutingServlet extends ProxyServlet {
...
@Override
protected String rewriteTarget(HttpServletRequest request) {
this.setTimeout(45000);
// ... business logic based on request body and headers ...
return rewrittenUrl;
}
...
}
这两种方法都没有任何效果,在第 30 秒后,代理用 HTTP/1.1 504 Gateway Timeout
响应客户端,而实际处理请求的 Web 服务器仍在处理它。
您有 2 个空闲超时需要担心,但最终听起来您收到的错误来自基于代理的客户端 (due to the 504 Gateway Timeout response)。
但在我们去那里之前,请确保您的 ServerConnector
设置了合理的空闲超时(应该比您的代理客户端的值更高)。这控制了您的 "Client" 和 "ProxyServer" 之间的连接空闲超时(根据您的图表)
接下来,如果您使用 AsyncProxyServlet
之类的东西,只需设置 "idleTimeout"
初始参数 (which defaults to "30000"
if unspecified)。这控制了 "ProxyServer" 和 "Jetty Server" 之间的空闲超时(根据图表)
例如:
Server server = new Server();
HttpConfiguration http_config = new HttpConfiguration();
http_config.setSendServerVersion(true);
http_config.setSendDateHeader(false);
ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(http_config));
http.setPort(8080);
http.setIdleTimeout(45000);
server.addConnector(http);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
ServletHolder proxyHolder = new ServletHolder("proxy", AsyncProxyServlet.class);
proxyHolder.setInitParameter("idleTimeout", "44000");
context.addServlet(proxyHolder, "/proxy");
ServletHolder defHolder = new ServletHolder("default", DefaultServlet.class);
context.addServlet(defHolder, "/");
HandlerList handlers = new HandlerList();
handlers.addHandler(context);
handlers.addHandler(new DefaultHandler());
server.setHandler(handlers);
server.start();
server.join(); // wait for server thread to finish
或者,您也可以在自定义 AsyncProxyServlet
中执行此操作。
package jetty.proxy;
import javax.servlet.ServletException;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.proxy.AsyncProxyServlet;
public class MyProxyServlet extends AsyncProxyServlet
{
@Override
protected HttpClient createHttpClient() throws ServletException {
HttpClient client = super.createHttpClient();
client.setIdleTimeout(44000);
return client;
}
}