【问题标题】:How to add a fix to avoid 504 Gateway timeout error如何添加修复程序以避免 504 网关超时错误
【发布时间】:2021-04-27 18:52:18
【问题描述】:

我的 GET 方法调用另一个服务时出现 504 网关超时错误。 最近我通过增加超时时间添加了一个修复程序,但这并没有帮助。

这是我尝试过的

   public void getUserInformation(final Integer userId) {
        HttpClient httpClient = getBasicAuthDefaultHttpClient();
        HttpGet httpGet = new HttpGet("http://xxxx/users/"+userId);
        httpGet.addHeader("userid", userid);
        httpGet.addHeader("secret", secret);
        try {
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();

            if (entity != null && HttpStatus.OK.value() == 
               response.getStatusLine().getStatusCode()) {
               ObjectMapper objectMapper = new ObjectMapper();
               userInfo = objectMapper.readValue(entity.getContent(), 
               UserInfo.class);
            } else {
                logger.error("Call to the service failed: response code: 
                {}", response.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            logger.error("Exception: "+ e);
        }

   }

  public HttpClient getBasicAuthDefaultHttpClient() {
    CredentialsProvider provider = new BasicCredentialsProvider();
    UsernamePasswordCredentials creds = new 
    UsernamePasswordCredentials(user, password);
    provider.setCredentials(AuthScope.ANY, creds);

    //Fix to avoid HTTP 504 ERROR (GATEWAY TIME OUT ERROR) for ECM calls
    RequestConfig.Builder requestBuilder = RequestConfig.custom();
    requestBuilder.setConnectTimeout(30 * 1000);
    requestBuilder.setConnectionRequestTimeout(30 * 1000);

    HttpClientBuilder builder = HttpClientBuilder.create();
    builder.setDefaultRequestConfig(requestBuilder.build());
    builder.setDefaultCredentialsProvider(provider).build();

    return builder.build();
  }

我在循环中调用此过程来处理记录,这适用于大多数记录,但对于其中的少数 userId 失败。 但是我注意到,当我只运行失败的记录时,一切都会正常工作,不知道这种情况下的问题是什么。

当我收到504时我想再次调用该方法以再次调用它希望下次收到200。

不确定这是不是个好主意。任何建议将不胜感激。

【问题讨论】:

  • 想到的一个想法...超时时间每次都不一样吗?我的猜测是,另一个网站正在限制他们将从特定 IP 地址处理的请求数量。也许您可以尝试限制您向网站发出的请求数量。也许哪怕是半秒的延迟就足够了……
  • @hooknc:超时时间每次都不一样,对传入的请求没有任何限制。对于那些失败的请求,我在日志中看到的是它只用了 10 秒并返回了 504 错误!
  • 确保代理 URL 正确且没有任何拼写错误。有时像这样的愚蠢错误会让你头疼好几个小时。

标签: java http-status-code-504


【解决方案1】:

根据504 Gateway Timeout状态码的描述,当你有一个服务器链通信来处理请求并且其中一个节点(不是你正在调用的服务器,而是稍后的一个)不是时返回它能够及时处理请求。

我想你的情况可以描述如下。

CLIENT -> USERS SERVICE -> SOME OTHER SERVICE

问题是SOME OTHER SERVICE 处理您的请求的时间过长。 USERS SERVICE 会在某个时间点放弃并返回此特定状态代码以表明这一点。

据我所知,您几乎无法解决这个问题。您需要联系USERS SERVICE 的所有者并要求他们延长超时时间或SOME OTHER SERVICE 的所有者并要求他们提高性能。

至于为什么会时不时出现这样的错误。您可能会与其他客户端一起使SOME OTHER SERVICE 超载,导致它处理请求的速度越来越慢。或者可能是SOME OTHER SERVICE 启用了节流或速率限制以防止拒绝服务攻击。通过向USERS SERVICE 发出过多请求,您可能正在消耗它的配额。

当然,这些都是推测,不知道你的实际情况。

【讨论】:

    【解决方案2】:

    我曾经遇到过同样的情况,以下是我为解决此问题所做的检查。我将在上面的类比中添加更多细节。

    客户端->用户服务->其他一些服务

    客户检查:

    “一些其他服务”检查: 如果设置节流/速率限制以避免 DOS 攻击。然后你需要增加一些其他服务的超时时间。我在 AWS 上使用了 tomcat 服务器:更改了 yaml 文件中的空闲超时

    metadata:
        annotations:
            #below for openshift which worked for me        
            haproxy.router.openshift.io/timeout:20000
            #below for kubernetes timeout in ELB
            service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout:20000 
    

    还更改了 tomcat 上的连接器超时

     <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
    

    瞧!它对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-22
      • 2019-09-09
      • 1970-01-01
      • 1970-01-01
      • 2021-04-05
      • 2011-04-08
      • 2017-06-16
      • 1970-01-01
      相关资源
      最近更新 更多