powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / HttpServer - утечка соектов
18 сообщений из 18, страница 1 из 1
HttpServer - утечка соектов
    #39741766
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть такое вот поделие.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
    @Override
    public void handle(HttpExchange httpExchange) throws IOException {
        ....
        ....
                WebTarget webTarget = httpClientHolder.getClient().target(url);
                try (Response response = webTarget.request().get()) {
                    if (response.getStatusInfo().getStatusCode() != HttpStatus.SC_OK) {
                        logger.warn("Failed to download resource, url = " + url + " code = " +
                                response.getStatusInfo().getStatusCode());
                        throw new HttpException("Not found", 404);
                    }
                    httpExchange.sendResponseHeaders(200, response.getLength());
                    final InputStream is = response.readEntity(InputStream.class);
                    try (final OutputStream os = httpExchange.getResponseBody()) {
                        IOUtils.copy(is, os, 128);
                    } catch (IOException e) {
                        logger.warn("Error proxy data: " + e.getMessage());
                    }
                }
        ....
    }



Проблема в том, что иногда выпадает исключение при попытке закрыть OutputStream

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
java.io.IOException: Broken pipe
        at sun.nio.ch.FileDispatcherImpl.write0(Native Method) ~[?:1.8.0_191]
        at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) ~[?:1.8.0_191]
        at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93) ~[?:1.8.0_191]
        at sun.nio.ch.IOUtil.write(IOUtil.java:65) ~[?:1.8.0_191]
        at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471) ~[?:1.8.0_191]
        at sun.net.httpserver.Request$WriteStream.write(Request.java:391) ~[?:1.8.0_191]
        at sun.net.httpserver.FixedLengthOutputStream.write(FixedLengthOutputStream.java:78) ~[?:1.8.0_191]
        at sun.net.httpserver.PlaceholderOutputStream.write(ExchangeImpl.java:444) ~[?:1.8.0_191]
        at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2315) ~[cache-1.0-SNAPSHOT-jar-with-dependencies.jar:?]
        at org.apache.commons.io.IOUtils.copy(IOUtils.java:2270) ~[cache-1.0-SNAPSHOT-jar-with-dependencies.jar:?]
        at server.TimelineVttHandler.handle(TimelineVttHandler.java:129) [cache-1.0-SNAPSHOT-jar-with-dependencies.jar:?]
        at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) [?:1.8.0_191]
        at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83) [?:1.8.0_191]
        at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82) [?:1.8.0_191]
        at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675) [?:1.8.0_191]
        at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) [?:1.8.0_191]
        at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647) [?:1.8.0_191]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_191]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_191]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_191]
        Suppressed: java.io.IOException: insufficient bytes written to stream
                at sun.net.httpserver.FixedLengthOutputStream.close(FixedLengthOutputStream.java:89) ~[?:1.8.0_191]
                at sun.net.httpserver.PlaceholderOutputStream.close(ExchangeImpl.java:454) ~[?:1.8.0_191]
                at server.TimelineVttHandler.handle(TimelineVttHandler.java:130) [cache-1.0-SNAPSHOT-jar-with-dependencies.jar:?]
                at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) [?:1.8.0_191]
                at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83) [?:1.8.0_191]
                at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82) [?:1.8.0_191]
                at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675) [?:1.8.0_191]
                at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) [?:1.8.0_191]
                at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647) [?:1.8.0_191]
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_191]
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_191]
                at java.lang.Thread.run(Thread.java:748) [?:1.8.0_191]



Как я понял, проблема в том, что пока мы пишем - клиент отваливается и дописать не получается.

Оно происходит редко и в общем-то никто не жаловался. Вот только сокет остается жить в таком виде до завершения работы программы:

Код: plaintext
1.
2.
3.
4.
lsof -n -p 14121  | grep TCPv6
java    13161 cache  143u     sock                0,9      0t0 3617991518 protocol: TCPv6
java    13161 cache  180u     sock                0,9      0t0 3618027565 protocol: TCPv6
java    13161 cache  184u     sock                0,9      0t0 3618017649 protocol: TCPv6

Виден он только в lsof, в netstat - отсутствует, но думаю это не важно.

Естественно в конце концов упираемся в ulimit.
Как правильно обработать эту ситуацию?
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741777
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про исключение я не правильно наверное написал. Сначала ошибка записи, а потом при закрытии еще одно исключение, которое поглощено?
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741825
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HettКак правильно обработать эту ситуацию?- показать тут строку на которой исключение.
- сделать тест именно на.... Клиент отвалился.
- убрать автоматическое освобождение ресурсов и пробу ручного закрытия канала и ресурсов.
- пробовать и сравнить с другими библиотеками и версиями.
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741826
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вроде вот так решилось:


Код: java
1.
2.
3.
4.
5.
6.
                    try (final OutputStream os = httpExchange.getResponseBody()) {
                        IOUtils.copy(is, os, 128);
                    } catch (IOException e) {
                        logger.warn("Error proxy data", e);
                        throw e;
                    }



Т.е. выбрасываем IOException из хендлера. На этму мысль меня навел контракт метода `handle`.

Вчера с десяток примеров пересмотрел и доку оракловскую читал, ничего такого не нашел (хотя может и не обратил внимания).
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741827
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то можно настроить log4j2 так, чтобы он не записывал stacktrace на проде ?

Код: java
1.
logger.warn("Error proxy data", e);
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741828
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HettТ.е. выбрасываем IOException из хендлера.скорее ты его сам подавил и выше блок с try( ничего не знал об этом.
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741829
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123HettТ.е. выбрасываем IOException из хендлера.скорее ты его сам подавил и выше блок с try( ничего не знал об этом.
Ну как бы да, но я же все ресурсы закрыл.
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741830
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HettКак-то можно настроить log4j2 так, чтобы он не записывал stacktrace на проде ?

Код: java
1.
logger.warn("Error proxy data", e);

на проде свой конфиг или в конфине переменная окружения операционки.
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741831
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HettНу как бы да, но я же все ресурсы закрыл.фиг знает. Значит автомат не работает если в catch ничего нет кроме логирования.
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741832
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123HettКак-то можно настроить log4j2 так, чтобы он не записывал stacktrace на проде ?

Код: java
1.
logger.warn("Error proxy data", e);

на проде свой конфиг или в конфине переменная окружения операционки.

Понятно что свой. Собственно вопрос в этом и был, как в конфиге указать чтобы он стек-трейсы не валил в лог.
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741833
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hett,
Конфиг не знаю, тему создай.
Я бы warn поменял на info или debug.
Удачи!
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741841
Озверин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HettКак-то можно настроить log4j2 так, чтобы он не записывал stacktrace на проде ?

Код: java
1.
logger.warn("Error proxy data", e);



а в логге была просто запись Error proxy data?
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741842
Озверин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HettЕсть такое вот поделие.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
    @Override
    public void handle(HttpExchange httpExchange) throws IOException {
        ....
        ....
                WebTarget webTarget = httpClientHolder.getClient().target(url);
                try (Response response = webTarget.request().get()) {
                    if (response.getStatusInfo().getStatusCode() != HttpStatus.SC_OK) {
                        logger.warn("Failed to download resource, url = " + url + " code = " +
                                response.getStatusInfo().getStatusCode());
                        throw new HttpException("Not found", 404);
                    }
                    httpExchange.sendResponseHeaders(200, response.getLength());
                    final InputStream is = response.readEntity(InputStream.class);
                    try (final OutputStream os = httpExchange.getResponseBody()) {
                        IOUtils.copy(is, os, 128);
                    } catch (IOException e) {
                        logger.warn("Error proxy data: " + e.getMessage());
                    }
                }
        ....
    }



Проблема в том, что иногда выпадает исключение при попытке закрыть OutputStream

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
java.io.IOException: Broken pipe
        at sun.nio.ch.FileDispatcherImpl.write0(Native Method) ~[?:1.8.0_191]
        at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) ~[?:1.8.0_191]
        at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93) ~[?:1.8.0_191]
        at sun.nio.ch.IOUtil.write(IOUtil.java:65) ~[?:1.8.0_191]
        at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471) ~[?:1.8.0_191]
        at sun.net.httpserver.Request$WriteStream.write(Request.java:391) ~[?:1.8.0_191]
        at sun.net.httpserver.FixedLengthOutputStream.write(FixedLengthOutputStream.java:78) ~[?:1.8.0_191]
        at sun.net.httpserver.PlaceholderOutputStream.write(ExchangeImpl.java:444) ~[?:1.8.0_191]
        at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2315) ~[cache-1.0-SNAPSHOT-jar-with-dependencies.jar:?]
        at org.apache.commons.io.IOUtils.copy(IOUtils.java:2270) ~[cache-1.0-SNAPSHOT-jar-with-dependencies.jar:?]
        at server.TimelineVttHandler.handle(TimelineVttHandler.java:129) [cache-1.0-SNAPSHOT-jar-with-dependencies.jar:?]
        at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) [?:1.8.0_191]
        at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83) [?:1.8.0_191]
        at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82) [?:1.8.0_191]
        at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675) [?:1.8.0_191]
        at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) [?:1.8.0_191]
        at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647) [?:1.8.0_191]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_191]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_191]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_191]
        Suppressed: java.io.IOException: insufficient bytes written to stream
                at sun.net.httpserver.FixedLengthOutputStream.close(FixedLengthOutputStream.java:89) ~[?:1.8.0_191]
                at sun.net.httpserver.PlaceholderOutputStream.close(ExchangeImpl.java:454) ~[?:1.8.0_191]
                at server.TimelineVttHandler.handle(TimelineVttHandler.java:130) [cache-1.0-SNAPSHOT-jar-with-dependencies.jar:?]
                at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) [?:1.8.0_191]
                at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83) [?:1.8.0_191]
                at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82) [?:1.8.0_191]
                at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675) [?:1.8.0_191]
                at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79) [?:1.8.0_191]
                at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647) [?:1.8.0_191]
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_191]
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_191]
                at java.lang.Thread.run(Thread.java:748) [?:1.8.0_191]



Как я понял, проблема в том, что пока мы пишем - клиент отваливается и дописать не получается.

Оно происходит редко и в общем-то никто не жаловался. Вот только сокет остается жить в таком виде до завершения работы программы:

Код: plaintext
1.
2.
3.
4.
lsof -n -p 14121  | grep TCPv6
java    13161 cache  143u     sock                0,9      0t0 3617991518 protocol: TCPv6
java    13161 cache  180u     sock                0,9      0t0 3618027565 protocol: TCPv6
java    13161 cache  184u     sock                0,9      0t0 3618017649 protocol: TCPv6

Виден он только в lsof, в netstat - отсутствует, но думаю это не важно.

Естественно в конце концов упираемся в ulimit.
Как правильно обработать эту ситуацию?

а как часто такие запросы происходят?
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741845
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ОзверинHettКак-то можно настроить log4j2 так, чтобы он не записывал stacktrace на проде ?

Код: java
1.
logger.warn("Error proxy data", e);



а в логге была просто запись Error proxy data?

Ну запись и стек-трейс, я привел в первом посте это :)
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39741846
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автора как часто такие запросы происходят?
Около 1000 в сутки на одну ноду. Как я понял просто клиент прерывает соединение до того, как получил данные, вот и вся "проблема".
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39742120
qasta
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Озверин,

Не знаю, может ли с этим быть связано - вы не закрываете InputStream - его тоже надо добавить в try() {} (в try-with-resources можно добавлять сразу несколько записей). То есть получится что-то вроде
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
@Override
    public void handle(HttpExchange httpExchange) throws IOException {
        ....
        ....
                WebTarget webTarget = httpClientHolder.getClient().target(url);
                try (Response response = webTarget.request().get()) {
                    if (response.getStatusInfo().getStatusCode() != HttpStatus.SC_OK) {
                        logger.warn("Failed to download resource, url = " + url + " code = " +
                                response.getStatusInfo().getStatusCode());
                        throw new HttpException("Not found", 404);
                    }
                    httpExchange.sendResponseHeaders(200, response.getLength());
                    
                    try (final InputStream is = response.readEntity(InputStream.class);
                          final OutputStream os = httpExchange.getResponseBody()) {
                        IOUtils.copy(is, os, 128);
                    } catch (IOException e) {
                        logger.warn("Error proxy data: " + e.getMessage());
                    }
                }
        ....
    }



Ну, раз проблему уже решили, причем через другой способ работы с httpExchange, то и так гуд - видать утекали "серверные" сокеты, а не "клиентские". Тем более, что Response.close() должен по-идее закрыть и InputStream.
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39742128
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторТем более, что Response.close() должен по-идее закрыть и InputStream.
Да, он закрывается.
Я кстати пробовал и вариант с его закрытим даже сначала. Но ничего не изменилось.

Стоит ли закрывать инпут стрим из чисто эстетических соображений?
...
Рейтинг: 0 / 0
HttpServer - утечка соектов
    #39742148
qasta
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
HettСтоит ли закрывать инпут стрим из чисто эстетических соображений?

Часто применяется правило - где "открыл/создал" ресурс - там и закрывай (на том же "уровне").
Поэтому, я бы его закрывал - раз лишних try-catch-ей это не тянет за собой. Но это реально "вкусовщина" и "эстетство" :)

P.S. Оффтоп. Вообще, это правило здорово помогает. Например, при работе с JDBC ресурсами при закрытии Connection-а автоматически закрываются связанные с ним PreparedStatement-ы, ResultSet-ы и т.п. Казалось бы - закрывай только connection и всё. Но это не срабатывает при использовании пула соединений, т.к. физически соединение не закрывается, а возвращается в пул.
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / HttpServer - утечка соектов
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]