Couchbase并发超时异常:Java SDK

时间:2016-11-23 08:02:28

标签: java couchbase

我在maven项目中使用java。我正在使用couchbase 2.3.1,但在尝试解决此问题时,我回滚到2.2.8无济于事。

我得到的问题是,当我确实将日期发送到我的couchbase群集时,我看到很多这样的事情:

java.lang.RuntimeException: java.util.concurrent.TimeoutException
at com.couchbase.client.java.util.Blocking.blockForSingle(Blocking.java:75)
at com.couchbase.client.java.CouchbaseBucket.upsert(CouchbaseBucket.java:359)
at com.couchbase.client.java.CouchbaseBucket.upsert(CouchbaseBucket.java:354)

以下是我的couchbase环境的设置:

CouchbaseEnvironment: {sslEnabled=false, sslKeystoreFile='null', sslKeystorePassword='null', queryEnabled=false, queryPort=8093, bootstrapHttpEnabled=true, bootstrapCarrierEnabled=true, bootstrapHttpDirectPort=8091, bootstrapHttpSslPort=18091, bootstrapCarrierDirectPort=11210, bootstrapCarrierSslPort=11207, ioPoolSize=24, computationPoolSize=24, responseBufferSize=16384, requestBufferSize=16384, kvServiceEndpoints=1, viewServiceEndpoints=1, queryServiceEndpoints=1, searchServiceEndpoints=1, ioPool=NioEventLoopGroup, coreScheduler=CoreScheduler, eventBus=DefaultEventBus, packageNameAndVersion=couchbase-java-client/2.2.8 (git: 2.2.8, core: 1.2.9), dcpEnabled=false, retryStrategy=BestEffort, maxRequestLifetime=75000, retryDelay=ExponentialDelay{growBy 1.0 MICROSECONDS, powers of 2; lower=100, upper=100000}, reconnectDelay=ExponentialDelay{growBy 1.0 MILLISECONDS, powers of 2; lower=32, upper=4096}, observeIntervalDelay=ExponentialDelay{growBy 1.0 MICROSECONDS, powers of 2; lower=10, upper=100000}, keepAliveInterval=30000, autoreleaseAfter=2000, bufferPoolingEnabled=true, tcpNodelayEnabled=true, mutationTokensEnabled=false, socketConnectTimeout=1000, dcpConnectionBufferSize=20971520, dcpConnectionBufferAckThreshold=0.2, dcpConnectionName=dcp/core-io, callbacksOnIoPool=false, queryTimeout=75000, viewTimeout=75000, kvTimeout=2500, connectTimeout=5000, disconnectTimeout=25000, dnsSrvEnabled=false}

我真的不太清楚这里要看什么。据我所知,应用程序运行的服务器和couchbase集群之间应该有足够的连接。任何帮助或方向都会有所帮助。这是一个从中抛出错误的片段。

LockableItem<InnerVertex> lv = this.getInnerVertex(id);
lv.lock();
    try {
        String content;
        try {
            content = mapper.writeValueAsString(lv.item);
        } catch (JsonProcessingException e) {
            LOG.warning(e.getMessage());
            return;
        }
        RawJsonDocument d = RawJsonDocument.create(VertexId.toKey(id), content);
        bucket.upsert(d);
    } finally {
        lv.unlock();
    }

2 个答案:

答案 0 :(得分:10)

我正在寻找答案。我得到了很多解决方案都在讨论异常。我还检查了jar代码,它被称为超时异常。

根本原因分析

来自couchbase的以下部分的错误:https://github.com/couchbase/couchbase-java-client/blob/master/src/main/java/com/couchbase/client/java/util/Blocking.java#L71

public static <T> T blockForSingle(final Observable<? extends T> observable, final long timeout,
    final TimeUnit tu) {
    final CountDownLatch latch = new CountDownLatch(1);
    TrackingSubscriber<T> subscriber = new TrackingSubscriber<T>(latch);

    observable.subscribe(subscriber);

    try {
        if (!latch.await(timeout, tu)) { // From here, this error occurs.
            throw new RuntimeException(new TimeoutException());
        }
} 
  

如果超时启动,则嵌套在a中的TimeoutException   抛出RuntimeException以与。完全兼容   Observable.timeout(long,TimeUnit)行为。

资源链接:

http://docs.couchbase.com/sdk-api/couchbase-java-client-2.2.0/com/couchbase/client/java/util/Blocking.html

您的配置分析和解决方案:

您的couchbase环境connectionTimeout为5000ms或5秒,这是连接超时的默认值。

您需要将此值增加到10000ms or greater。你的问题将得到解决。

//this tunes the SDK (to customize connection timeout)
CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder()
        .connectTimeout(10000) //10000ms = 10s, default is 5s
        .build();

完整的解决方案

Simonbasle在本教程中提供了完整的解决方案:

  

从短日志中,看起来SDK能够连接到   节点,但需要一点时间打开桶。这有多好   两台机器之间的网络连接?这是VM /云计算机吗?

     

您可以尝试做的是增加连接超时:

public class NoSQLTest {
public static void main(String[] args) {
        try {
            //this tunes the SDK (to customize connection timeout)
            CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder()
                    .connectTimeout(10000) //10000ms = 10s, default is 5s
                    .build();
            System.out.println("Create connection");
            //use the env during cluster creation to apply
            Cluster cluster = CouchbaseCluster.create(env, "10.115.224.94");
            System.out.println("Try to openBucket");
            Bucket bucket = cluster.openBucket("beer-sample"); //you can also force a greater timeout here (cluster.openBucket("beer-sample", 10, TimeUnit.SECONDS))
            System.out.println("disconnect");
            cluster.disconnect();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  

作为旁注,您应该始终重用CouchbaseEnvironment,   CouchbaseCluster和Bucket实例一旦创建(通常通过制作   他们是公共静态的某个地方,还是Spring的单身人士......等等。这些   是线程安全的,应该共享(并且它们的创建成本很高   反正)。

资源链接:

  1. Couchbase connection timeout with Java SDK

答案 1 :(得分:0)

感谢您的问题和@SkyWalker的答案。 当我遇到这个烦人的超时时,他们提供了帮助。

对于Spring Data Couchbase 2,在application.properties中添加以下内容即可解决

spring.couchbase.env.timeouts.connect=20000