Jetty 9.4.14 ProxyServlet增加或禁用超时

时间:2019-01-15 09:54:55

标签: java jetty embedded-jetty jetty-9

我正在使用嵌入式码头(9.4.14.v20181114)来实现以下设置

JettySetup

如图所示,所有客户端都在访问代理服务器,并且基于某些业务规则,代理将转发到其中一台Web服务器 使用码头的ProxyServlet#rewriteTarget方法。为此,我定义了一个新类,该类扩展了ProxyServlet并覆盖了rewriteTarget

图片中的每个服务器都部署在不同的计算机上。

一些客户端请求需要花费一些时间来处理,事实证明,如果请求需要30秒以上,则代理会用

响应客户端
HTTP/1.1 504 Gateway Timeout
Date: Tue, 15 Jan 2019 09:04:37 GMT
Connection: close
Content-Type: application/json"

有没有办法增加或完全删除此超时。

我尝试了以下两件事,但都没有起作用

  1. 设置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 });
  1. 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服务器仍在处理它。

1 个答案:

答案 0 :(得分:1)

您有2个空闲超时需要担心,但最终听起来像是您从基于代理的客户端(due to the 504 Gateway Timeout response)中收到错误。

但是在我们去那里之前,请确保您的ServerConnector设置了正确的“空闲超时”(可能比您的代理客户端高)。这可以控制“客户端”和“代理服务器”之间的连接空闲超时(根据您的关系图)

接下来,如果您使用的是类似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;
    }
}