我在Spring 4.x环境中使用 Couchbase Java SDK版本2.3.1
。当我用一个线程执行代码时,一切都很好。当代码在具有多个线程的Executor服务中运行时,我得到 Bucket Closed Exception 。 java类如下所示:
分类: AppConfig.java
@Configuration
@ComponentScan("com.demo")
public class AppConfig {
@Bean(name = BeanNames.CONFIGS)
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public Configs configs() {
// initialize the app configs.
}
@Bean(name = BeanNames.COUCHBASE_BUCKET)
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public Bucket couchbaseBucket() {
Bucket bucket = null;
try {
final DefaultCouchbaseEnvironment.Builder envBuilder = DefaultCouchbaseEnvironment.builder();
// Set the properties
final CouchbaseEnvironment couchbaseEnv = envBuilder.build();
final Cluster cluster = CouchbaseCluster.create(couchbaseEnv, nodes);
bucket = cluster.openBucket(bucketName, bucketPassword);
} catch (final Exception e) {
logger.error("Exception while configuring Couchbase bucket....", e);
throw new IllegalStateException("Couchbase cannot be configured.");
}
}
}
分类: CouchbaseDAO.java
@Component(BeanNames.COUCHBASE_DAO)
public class CouchbaseDAO {
@Autowired
@Qualifier(BeanNames.COUCHBASE_BUCKET)
private Bucket bucket;
public String getByKey(final String key) {
final JsonDocument jsonDocument = bucket.get(key);
if (jsonDocument != null && jsonDocument.content() != null) {
return Objects.toString(jsonDocument.content());
}
return null;
}
}
类: DataCollector.java
@Component(BeanNames.DATA_COLLECTOR)
public class DataCollector {
@Autowired
@Qualifier(BeanNames.COUCHBASE_DAO)
private CouchbaseDAO dao;
public void doCollect(key) {
// Call DAO to get doc.
final String doc = dao.getByKey(key);
// ... do other things
}
}
类: AppTask.java
public class AppTask implements Runnable {
private final dataCollector;
public AppTask(DataCollector dataCollector) {
this.dataCollector = dataCollector;
}
public void run() {
try {
// Get Couchbase key
dataCollector.doCollect(key);
} catch (Exception e) {
// This is printing Couchbase bucket closed exception
logger.error("Uncaught exception...", e);
}
}
}
分类: AppExecutor.java
@Component(BeanNames.APP_TASK_EXECUTOR)
public class AppTaskExecutor {
private final ExecutorService executor;
private final Configs configs;
@Autowired
@Qualifier(BeanNames.DATA_COLLECTOR)
private DataCollector dataCollector;
@Autowired
public AppTaskExecutor(@Qualifier(BeanNames.CONFIGS) final Configs configs) {
this.configs = configs;
executor = Executors.newFixedThreadPool(configs.taskCount());
}
public void execute() {
for (int i = 0; i < configs.count(); i++) {
executor.submit(new AppTask(dataCollector));
}
}
}
类: MainApp.java
public class MainApp {
public static void main(String[] args) {
try (final ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(ConnectorSpringConfig.class)) {
final AppExecutor appExecutor = applicationContext.getBean(BeanNames.APP_TASK_EXECUTOR, AppExecutor.class);
appExecutor.execute();
}
}
我在日志文件中看到的堆栈跟踪是:
com.couchbase.client.core.BucketClosedException: SLP has been closed
at com.couchbase.client.core.RequestHandler.dispatchRequest(RequestHandler.java:206)
at com.couchbase.client.core.RequestHandler.onEvent(RequestHandler.java:176)
at com.couchbase.client.core.RequestHandler.onEvent(RequestHandler.java:71)
at com.couchbase.client.deps.com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:129)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at com.couchbase.client.deps.io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
at java.lang.Thread.run(Thread.java:745)
组件的配置或组织有什么问题吗?
我尝试了以下更改: