首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Riak TCP CLOSE_WAIT

Riak TCP CLOSE_WAIT
EN

Stack Overflow用户
提问于 2015-05-07 23:49:08
回答 1查看 331关注 0票数 0

TLDR:

OPEN_WAIT状态下的大量TCP连接关闭服务器

设置:

Ubuntu12 Spring 3.2.5 riak-client-1.1.0.jar Tomcat7.0.51托管在Windows 2008 R2 JRE6_45上

全称:

如何确保Java正确地清理它的连接,使我没有剩下大量的RiakClient CLOSE_WAIT连接?

我有一个Spring应用程序,它使用Riak客户机连接到远程实例/集群。

我们在承载Spring应用程序的服务器上看到了许多TCP连接,这些连接在不断积累,直到服务器无法再连接到任何东西,因为没有可用的端口。

重新启动Riak集群不会清理连接。

重新启动webapp确实会清理额外的连接。

我们正在使用HTTPClientAdapter和REST。

当连接到关系数据库时,我通常会清除连接,方法是显式地在连接上调用close,或者通过向池和事务管理器注册数据源,然后用@ transaction注释manager。

但是由于使用了HTTPClientAdapter,我希望这更像是一个HttpClient。对于HttpClient,我将使用EntityUtils.consume(.)来使用响应实体,以确保所有内容都被正确清理。

HTTPClientAdapter确实有一个关机方法,我在在线示例中看到了它的调用。当我将方法调用跟踪到实际的RiakClient时,方法是空的。另外,当我深入研究源代码时,它在任何地方都不会关闭HttpResponse上的流或使用任何响应实体(如标准的Apache示例)。

这是一个如何打电话的例子。

代码语言:javascript
复制
      private RawClient getRiakClientFromUrl(String riakUrl) {
    return new HTTPClientAdapter(riakUrl);
  }


  public IRiakObject fetchRiakObject(String bucket, String key, boolean useCache) {

      try {
         MethodTimer timer = MethodTimer.start("Fetch Riak Object Operation");
         //logger.debug("Fetching Riak Object {}/{}", bucket, key);
         RiakResponse riakResponse;
         riakResponse = riak.fetch(bucket, key);
         if(!riakResponse.hasValue()) {
            //logger.debug("Object {}/{} not found in riak data store", bucket, key);
            return null;
         }

         IRiakObject[] riakObjects = riakResponse.getRiakObjects();
         if(riakObjects.length > 1) {
            String error = "Got multiple riak objects for " + bucket + "/" + key;
            logger.error(error);
            throw new RuntimeException(error);
         }

         //logger.debug("{}", timer);
         return riakObjects[0];
      }
      catch(Exception e) {
         logger.error("Error fetching " + bucket + "/" + key, e);
         throw new RuntimeException(e);
      }
   }

我能想到的唯一选择是,将RiakClient与适配器分开创建,这样我就可以访问HttpClient和ConnectionManager。

我目前正致力于切换到PBClientAdapter,看看这是否有帮助,但是为了这个问题的目的(而且因为团队的其他成员可能不喜欢我,不管出于什么原因),让我们假设我必须继续通过HTTP连接。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-27 15:34:25

所以已经快一年了,所以我想我应该继续写我是如何解决这个问题的。

解决方案是将我们使用的客户端实现更改为java客户机提供的HTTPClientAdapter,传递配置以实现池和最大连接。下面是一些如何实现的代码示例。

首先,我们使用了一个旧版本的RIAK,下面是一个amven依赖项:

代码语言:javascript
复制
<dependency>
    <groupId>com.basho.riak</groupId>
    <artifactId>riak-client</artifactId>
    <version>1.1.4</version>
</dependency>

下面是一个例子:

代码语言:javascript
复制
public RawClient riakClient(){

    RiakConfig config = new RiakConfig(riakUrl);
    //httpConnectionsTimetolive is in seconds, but timeout is in milliseconds
    config.setTimeout(30000);
    config.setUrl("http://myriakurl/);
    config.setMaxConnections(100);//Or whatever value you need

    RiakClient client = new RiakClient(riakConfig);

    return new HTTPClientAdapter(client);
}

实际上,我在实现中对此进行了一些分解,并使用Spring注入值;我只想给出一个简化的示例。

通过将超时设置为低于标准的5分钟,系统将不会在连接上挂起太长时间(因此,5分钟+设置超时的任何内容),从而导致连接更快地进入close_wait状态。

当然,在池中设置最大连接会阻止应用程序打开10/数千个连接。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30113523

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档