当前位置: 首页 > 知识库问答 >
问题:

Apache HTTPClient5-如何防止连接/流被拒绝

夹谷弘亮
2023-03-14
  • 我是一名软件工程师,负责测试餐厅菜单项的订单排列,以确认它们通过POS成功下单
    • 简而言之,这会将一个JSON负载发布到一个endpoint,该endpoint然后验证带有POS的顺序,以定义成功/失败/其他
    • 其中POS和每秒交易量(TPS)可能不同,但每个后端使用相同的核心处理
    • 这可能高达每项22000个排列,JSON大小易于管理,需要尽快处理
    • 根据正在测试的餐厅和/或地区的不同,网络可能会有很大的差异
      • E、 g.其中一些延迟比其他延迟高得多
      • 我正在使用Apache的HTTP客户端5 w/poolgasyncclientconnectionmanager来执行菜单内容的GET和检查订单是否成功的POST
      if (connState == ConnectionHandshake.GRACEFUL_SHUTDOWN) {
          throw new H2StreamResetException(H2Error.PROTOCOL_ERROR, "Stream refused");
      }
      
      • 尝试使用搜索引擎查找答案,但HTTPClient5的点击次数很少
      • 尝试使用官方留档但这很稀疏
      • 将每个路由的最大连接更改为减少的数量,移动不活动验证或连接存活时间
        • 其中不活动检查可能会修复POST,但会为某些事务暂停GET
        • 一个区域/餐厅的调整可能适用于1个区域/餐厅,然后适用于另一个区域/餐厅,仅将网络作为变量
        PoolingAsyncClientConnectionManagerBuilder builder = PoolingAsyncClientConnectionManagerBuilder
                .create()
                .setTlsStrategy(getTlsStrategy())
                .setMaxConnPerRoute(12)
                .setMaxConnTotal(12)
                .setValidateAfterInactivity(TimeValue.ofMilliseconds(1000))
                .setConnectionTimeToLive(TimeValue.ofMinutes(2))
                .build();
        
        • 转换到自定义Request配置不同的超时
        java prettyprint-override">private HttpClientContext getHttpClientContext() {
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(Timeout.of(10, TimeUnit.SECONDS))
                    .setResponseTimeout(Timeout.of(10, TimeUnit.SECONDS))
                    .build();
        
            HttpClientContext httpContext = HttpClientContext.create();
            httpContext.setRequestConfig(requestConfig);
            return httpContext;
        }
        

        (除上述部分外,还有变更尝试)

        • 对init和get响应的包装处理
        public SimpleHttpResponse getFullResponse(String url, PoolingAsyncClientConnectionManager manager, SimpleHttpRequest req) {
                    try (CloseableHttpAsyncClient httpclient = getHTTPClientInstance(manager)) {
                        httpclient.start();
        
                        CountDownLatch latch = new CountDownLatch(1);
                        long startTime = System.currentTimeMillis();
                        Future<SimpleHttpResponse> future = getHTTPResponse(url, httpclient, latch, startTime, req);
        
                        latch.await();
                        return future.get();
                    } catch (IOException | InterruptedException | ExecutionException e) {
                        e.printStackTrace();
                        return new SimpleHttpResponse(999, CommonUtils.getExceptionAsMap(e).toString());
                    }
                }
        
        • 使用实际处理程序和探测代码
        private Future<SimpleHttpResponse> getHTTPResponse(String url, CloseableHttpAsyncClient httpclient, CountDownLatch latch, long startTime, SimpleHttpRequest req) {
                    return httpclient.execute(req, getHttpContext(), new FutureCallback<SimpleHttpResponse>() {
        
                        @Override
                        public void completed(SimpleHttpResponse response) {
                            latch.countDown();
                            logger.info("[{}][{}ms] - {}", response.getCode(), getTotalTime(startTime), url);
                        }
        
                        @Override
                        public void failed(Exception e) {
                            latch.countDown();
                            logger.error("[{}ms] - {} - {}", getTotalTime(startTime), url, e);
                        }
        
                        @Override
                        public void cancelled() {
                            latch.countDown();
                            logger.error("[{}ms] - request cancelled for {}", getTotalTime(startTime), url);
                        }
        
                    });
                }
        
        • 有没有一种方法可以配置客户端,使其能够在不显式修改每个endpoint上下文的配置的情况下自己处理这些差异

共有1个答案

蓝昊然
2023-03-14

(或至少是稳定的)

HttpAsyncClients.custom()
    .setConnectionManager(manager)
    .setRetryStrategy(getRetryStrategy())
    .setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_1)
    .setConnectionManagerShared(true);
  • 特别是关闭标头
    • req.set标头(连接,关闭,TE);
    • 注意:不活动检查有帮助,但有时仍然会被拒绝
    • 将帖子设置为在不活动后立即验证
      • 注:两者都使用1000会导致某些系统的高下降率
      PoolingAsyncClientConnectionManagerBuilder
          .create()
          .setValidateAfterInactivity(TimeValue.ofMilliseconds(0))
      
      • 设置GET在1s后验证
      PoolingAsyncClientConnectionManagerBuilder
          .create()
          .setValidateAfterInactivity(TimeValue.ofMilliseconds(1000))
      
      • 跟踪stacktrace到AbstractH2StreamMultiplexer中的连接问题
       if (connState == ConnectionHandshake.GRACEFUL_SHUTDOWN) {
          throw new H2StreamResetException(H2Error.PROTOCOL_ERROR, "Stream refused");
      }
      
      • 对应于
      connState = streamMap.isEmpty() ? ConnectionHandshake.SHUTDOWN : ConnectionHandshake.GRACEFUL_SHUTDOWN;
      
      • 如果我理解正确:
        • 连接未被/故意关闭
          • 然而,在再次执行之前,它们没有被确认准备好
          • 这导致它失败,因为流不可行
          • 给定强制HTTP1允许管理单个上下文
          • 通过合理的周期性检查GET的有效性

          将接受这一点,直到出现更好的答案,因为这是稳定但次优的。

 类似资料:
  • 我想使用连接到我的网络服务,发布一个XML并得到一个结果。我使用的是以下代码: 问题是,当我调用方法时,它失败了,说我“已经连接”。显然,实际上打开了与URL的连接(在我的调试器中,我可以看到布尔设置为)。但是根据Oracle的留档,它不应该这样做。Android文档对此并不清楚。 如何防止连接,以便设置额外属性? 更新它看起来好像在某个池中,没有断开连接,甚至在调用之后也没有断开连接,甚至没有杀

  • 我正在使用NAT开发一个微服务web应用程序(React和Node)并在GCP Kubernetes集群上运行它。 我无法连接到NAT流服务器POD。端口4222和8222是打开的。我收到连接拒绝错误。 $kubectl描述服务NAT-Srv

  • 问题内容: 我是 HBase 和 Hadoop的 新手。我已经完全设置了HBase并完美启动。现在,当我尝试使用Java客户端从 p1 连接到HBase(HBase安装在 p2上 )时,它抛出了一个奇怪的异常。 问题答案: 我找到了解决方案。 通过仅从我的 主机中 删除 localhost 条目。现在我的本地主机条目就像 192.169.19.50 [这是我的hbase IP] =本地主机,而不是

  • 问题内容: 我正在尝试实现TCP连接,从服务器端一切正常,但是当我运行客户端程序(从客户端计算机)时,出现以下错误: 我尝试更改套接字号以防万一,但无济于事,有谁知道导致此错误的原因和解决方法。 服务器代码: 客户代码: 问题答案: 此异常意味着你尝试连接的IP /端口上没有侦听服务: 你试图连接到错误的IP /主机或端口。 你尚未启动服务器。 你的服务器没有监听连接。 在Windows服务器上,

  • 我无法连接到RabbitMQ。RabbitMQ不在本地计算机上。 我的应用程序.属性看起来像 我可以使用https://urltologinscreen:15671访问Rabbitmq gui 我得到以下错误 如何解决问题?

  • 我试着让我的selenium测试在debian服务器上运行,但是我一直从我的GeckoDriver得到连接拒绝错误。在运行Ubuntu的本地机器上,它运行得很好。你们谁知道怎么了?我找不到任何有用的东西。 OS:Debian Jessie 构建工具:Gradle Java-版本:8 设置方法 错误信息