Мой сервер использует данные из внутренней веб-службы для построения своего ответа на основе запроса. Я использую Apache HttpClient 4.1 для выполнения запросов. Каждый первоначальный запрос приведет к 30 запросам к веб-службе. Из них 4 - 8 закончится тем, что в CLOSE_WAIT вставлены гнезда, которые никогда не выпускаются. В конце концов эти застрявшие сокеты превышают мой ulimit, и мой процесс заканчивается файловыми дескрипторами.Как я могу убедиться, что мой HttpClient 4.1 не утечки сокетов?
Я не хочу просто поднять мой ulimit (1024), потому что это просто замаскирует проблему.
Причина, по которой я перешел в HttpClient, заключается в том, что java.net.HttpUrlConnection ведет себя одинаково.
Я попытался переместиться в SingleClientConnManager для каждого запроса и вызывать client.getConnectionManager(). Shutdown() на нем, но сокеты все равно застревают.
Должен ли я попытаться решить это, чтобы в итоге я получил 0 открытых сокетов, пока нет запросов на запуск, или я должен сосредоточиться на сохранении запроса и пуле?
Для ясности я в том числе некоторые детали, которые могут иметь отношение:
ОС: Ubuntu 10,10
JRE: 1.6.0_22
Язык: Scala 2,8
Пример кода:
val cleaner = Executors.newScheduledThreadPool(1)
private val client = {
val ssl_ctx = SSLContext.getInstance("TLS")
val managers = Array[TrustManager](TrustingTrustManager)
ssl_ctx.init(null, managers, new java.security.SecureRandom())
val sslSf = new org.apache.http.conn.ssl.SSLSocketFactory(ssl_ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
val schemeRegistry = new SchemeRegistry()
schemeRegistry.register(new Scheme("https", 443, sslSf))
val connection = new ThreadSafeClientConnManager(schemeRegistry)
object clean extends Runnable{
override def run = {
connection.closeExpiredConnections
connection.closeIdleConnections(30, SECONDS)
}
}
cleaner.scheduleAtFixedRate(clean,10,10,SECONDS)
val httpClient = new DefaultHttpClient(connection)
httpClient.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY), new UsernamePasswordCredentials(username,password))
httpClient
}
val get = new HttpGet(uri)
val entity = client.execute(get).getEntity
val stream = entity.getContent
val justForTheExample = IOUtils.toString(stream)
stream.close()
Тест: netstat -a | grep {myInternalWebServiceName} | Grep CLOSE_WAIT
(Списки Патроны для моего процесса, которые находятся в состоянии CLOSE_WAIT)
Добавить комментарий Обсуждение:
Этот код в настоящее время демонстрирует правильное использование.
Спасибо за ваш ответ, я согласен с тем, что документация предполагает, что это должна быть эффективная мера. Количество сокетов, потерянных в CLOSE_WAIT, по-прежнему надежно растет с использованием этого очистителя вне потоковой передачи, поэтому он не был эффективным. Я добавил некоторые детали реализации к моему вопросу. –
Я отказываюсь. Я не понял, что в самом коде приложения я делал дополнительные образы изображений для выполнения бизнес-логики. Они все еще использовали методы WS.url до введения HttpClient и оставляли сокеты позади. –
Сломанная ссылка. (Пожалуйста, укажите названия и описания со ссылками.) Может быть, это одна и та же информация? http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html – danorton