TLDR:Riak Java HTTPClientAdapter TCP CLOSE_WAIT
Множество TCP соединений в состоянии OPEN_WAIT будет отключена сервер
установки:
riak_1.2.0-1_amd64.deb установлен на Ubuntu12 Spring MVC 3.2.5 riak-client-1.1.0.jar Tomcat7.0.51 размещен на Windows Server 2008 R2 JRE6_45
Полное описание:
Как убедиться, что Java RiakClient правильно очистки это подключение к, что я не ушел с обилием соединений TCP CLOSE_WAIT?
У меня есть приложение Spring MVC, которое использует клиент Riak java для подключения к удаленному экземпляру/кластеру.
Мы видим много TCP-соединений на сервере, на котором размещено приложение Spring MVC, которое продолжает расти до тех пор, пока сервер больше не сможет подключиться к чему-либо, потому что нет доступных портов.
Перезапуск кластера Riak не очищает соединения вверх.
Перезапуск webapp очищает дополнительные подключения.
Мы используем HTTPClientAdapter и REST api.
При подключении к реляционной базе данных я обычно очищал бы соединения, либо явным образом закрывая соединение, либо регистрируя источник данных с помощью пула и диспетчера транзакций, а затем аннотируя мои службы с помощью @Transactional.
Но так как с помощью HTTPClientAdapter я ожидал, что это больше похоже на HttpClient. С HttpClient я бы использовал объект Response с EntityUtils.consume (...), чтобы убедиться, что все правильно очищено.
HTTPClientAdapter имеет метод выключения, и я вижу, что он вызывается в онлайн-примерах. Когда я проследил вызов метода до фактического RiakClient, метод пуст. Кроме того, когда я копаю исходный код, нигде в нем он никогда не закрывает поток на HttpResponse или не потребляет никакой объект ответа (как со стандартным примером Apache EntityUtils).
Вот пример того, как выполняются вызовы.
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.
Независимо от того, что «RiakClient», он должен закрыть или отключить или отпустить или что-то еще, что вы не вызываете. – EJP
Да, это так. «HTTPClientAdapter имеет метод выключения, и я вижу, что он вызывается в онлайн-примерах. Когда я прослеживал вызов метода к фактическому RiakClient, метод пуст». Свяжите поворот java-riak-ckient в github: https : //github.com/basho/riak-java-client – Pytry