java - Jetty 9.4.14 ProxyServlet 增加或禁用超时

标签 java jetty embedded-jetty jetty-9

我使用嵌入式 jetty (9.4.14.v20181114)来实现以下设置

JettySetup .

如图所示,所有客户端都在访问代理服务器,并根据某些业务规则,代理转发到其中一台 Web 服务器 使用jetty的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 });
  • 在重写 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 设置了合理的空闲超时(可能应该是高于代理客户端的值)。这控制“客户端”和“代理服务器”之间的连接空闲超时(根据您的图表)

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

    关于java - Jetty 9.4.14 ProxyServlet 增加或禁用超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54196453/

    相关文章:

    java - 对于给定的日期,检测该月的第 n 个星期几,然后在接下来的 6 个月内用 Java 确定相同的日期

    java - 服务器 Tomcat v7.0 服务器在 localhost 无法在 90 秒内启动

    spring - 在 Spring MVC 应用程序中测试转发

    java - Jetty 自定义错误处理程序类被调用但没有可抛出对象

    embedded-jetty - 在嵌入式 Jetty 上启用 TLS-1.2

    java - Jetty 在使用 http2 时以状态 200 而不是 304 响应

    java - 来自单个 Maven 模块的多个 Java 9 模块?

    java - J2ME - 一次编码到处运行?

    java - CountDownTimer 类中的构造函数 CountDownTimer 无法应用于给定类型

    java - ReSTLet 在 HTTPS BindException 上与 Jetty 一起运行