Re: PostAsync
От: vaa https://www.youtube.com/playlist?list=PLtrvASfI1KW7VOYRKjglcagQzWLoxlncl
Дата: 04.04.22 14:14
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>Есть такой код, но почему-то зависает запрос на PostAsync.

ET>Ни ошибки, ни результата. В фидлере тоже запроса не видно

ET>В постмане результат возвращается.

ET>Что тут не так?

касперский не установлен случайно на пк? антихакер иногда блочит.
Re[2]: PostAsync
От: e.thrash  
Дата: 05.04.22 06:41
Оценка:
Здравствуйте, vaa, Вы писали:

vaa>Здравствуйте, e.thrash, Вы писали:


ET>>Есть такой код, но почему-то зависает запрос на PostAsync.

ET>>Ни ошибки, ни результата. В фидлере тоже запроса не видно

ET>>В постмане результат возвращается.

ET>>Что тут не так?

vaa>касперский не установлен случайно на пк? антихакер иногда блочит.


симантек. но прям попробую повторить. может реально баг
Re: PostAsync
От: vasmann  
Дата: 05.04.22 07:28
Оценка: :)
Здравствуйте, e.thrash, Вы писали:

ET> using (var client = new HttpClient())


Без относительно проблемы, её уже разъяснили.
Хочу указать на еще одну: использование HttpClient в связке с new ну и понятно using. Это ошибка. Может привести к исчерпанию хендлов на процессе (зависит, понятно от частоты и времени непрерывной работы приложения)
https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-6.0
Почему этот момент не подсвечен красными жирными буквами в доке — не ясно.

> HttpClient is intended to be instantiated once and re-used throughout the life of an application. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. This will result in SocketException errors. Below is an example using HttpClient correctly.
Re[2]: PostAsync
От: Sharov Россия  
Дата: 05.04.22 13:03
Оценка:
Здравствуйте, vasmann, Вы писали:

V>Здравствуйте, e.thrash, Вы писали:


ET>> using (var client = new HttpClient())


V>Без относительно проблемы, её уже разъяснили.

V>Хочу указать на еще одну: использование HttpClient в связке с new ну и понятно using. Это ошибка. Может привести к исчерпанию хендлов на процессе (зависит, понятно от частоты и времени непрерывной работы приложения)
V>https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-6.0
V>Почему этот момент не подсвечен красными жирными буквами в доке — не ясно.

Почему ошибка использовать using, т.е. dispose это ошибка? Наоборот, раз каждый HttpClient==сокет, то как же иначе?
Кодом людям нужно помогать!
Re[3]: PostAsync
От: vasmann  
Дата: 05.04.22 13:08
Оценка: 5 (1)
Здравствуйте, Sharov, Вы писали:

S>Почему ошибка использовать using, т.е. dispose это ошибка? Наоборот, раз каждый HttpClient==сокет, то как же иначе?


Потому что в документации об этом явно указано. Я её даже процитировал.
Re[2]: PostAsync
От: Mr.Delphist  
Дата: 05.04.22 14:56
Оценка: +1
Здравствуйте, vasmann, Вы писали:

V>Хочу указать на еще одну: использование HttpClient в связке с new ну и понятно using. Это ошибка. Может привести к исчерпанию хендлов на процессе (зависит, понятно от частоты и времени непрерывной работы приложения)

V>https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-6.0
V>Почему этот момент не подсвечен красными жирными буквами в доке — не ясно.

Ну и вообще может быть полезно пересмотреть подход в пользу HttpClientFactory:

https://www.talkingdotnet.com/3-ways-to-use-httpclientfactory-in-asp-net-core-2-1/

Помнится, помогло разрулить ряд проблем
Re[3]: PostAsync
От: Mr.Delphist  
Дата: 05.04.22 15:07
Оценка: 10 (1)
Здравствуйте, Sharov, Вы писали:

S>Почему ошибка использовать using, т.е. dispose это ошибка? Наоборот, раз каждый HttpClient==сокет, то как же иначе?


Сокет — это не managed-ресурс, у него немного другой жизненный цикл. Поэтому Dispose для HttpClient не гарантирует незамедлительного возврата рабочего сокета обратно в пул ОС (linger options и вот это вот всё). А если нету сокетов — нету и паровозиков.
Re[4]: PostAsync
От: Sharov Россия  
Дата: 05.04.22 15:15
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

S>>Почему ошибка использовать using, т.е. dispose это ошибка? Наоборот, раз каждый HttpClient==сокет, то как же иначе?

MD>Сокет — это не managed-ресурс, у него немного другой жизненный цикл. Поэтому Dispose для HttpClient не гарантирует незамедлительного возврата рабочего сокета обратно в пул ОС (linger options и вот это вот всё). А если нету сокетов — нету и паровозиков.

Я в кусре про разницу. Т.е. фактически тут не будет освобождения сразу, а надо ждать финализатора, т.е. недетерминизм на лицо, верно?
Кодом людям нужно помогать!
Re[5]: PostAsync
От: vasmann  
Дата: 05.04.22 15:51
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Я в кусре про разницу. Т.е. фактически тут не будет освобождения сразу, а надо ждать финализатора, т.е. недетерминизм на лицо, верно?


Нет, соединение (и связанный с ним сокет как хендл)будет жить только во время запроса и получения ответа. Когда ответ получен — соединение закроется, хендл освободится.
Т.е. HttpClient не равно Socket, скорее Post/GetAsync — это условно можно назвать тождественны, условно.
Re[6]: PostAsync
От: Sharov Россия  
Дата: 05.04.22 16:06
Оценка:
Здравствуйте, vasmann, Вы писали:

S>>Я в кусре про разницу. Т.е. фактически тут не будет освобождения сразу, а надо ждать финализатора, т.е. недетерминизм на лицо, верно?

V>Нет, соединение (и связанный с ним сокет как хендл)будет жить только во время запроса и получения ответа. Когда ответ получен — соединение закроется, хендл освободится.
V>Т.е. HttpClient не равно Socket, скорее Post/GetAsync — это условно можно назвать тождественны, условно.

У меня сессия -- один HttpClient, много сессиий -- много HttpClient'ов. Не так? Если так, то посути HttpClient==socket.
Кодом людям нужно помогать!
Re[7]: PostAsync
От: vasmann  
Дата: 05.04.22 16:23
Оценка: 5 (1)
Здравствуйте, Sharov, Вы писали:

S>У меня сессия -- один HttpClient, много сессиий -- много HttpClient'ов. Не так? Если так, то посути HttpClient==socket.


Об этом и говорил. Класс так спроектирован, что подталкивает использовать не корректно. Ровно так и использовали пока не воткнулись как раз в это самое истощение которое указано в документации на класс.
Ответ на твой вопрос: не так? — Да, не так.
Один HttpClient поддерживает много одновременных Post/Send/Get-ов. Выше тут рекомендовали использовать фабрики, или через методы расширения конфигурировать и уже через DI его инжектить в конструктуры нужных классов потребителей.
В общем посмотри документацию, там прям пример есть GoodController — понятно реализован примитивно через статическое поле, но от этого уже можно накрутить любой синглтон который по душе придётся.
Re[5]: PostAsync
От: Mr.Delphist  
Дата: 05.04.22 19:34
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Я в кусре про разницу. Т.е. фактически тут не будет освобождения сразу, а надо ждать финализатора, т.е. недетерминизм на лицо, верно?


Даже не финализатор.
Свободен сокет или ещё нет — решает сама ОС. Это было всегда в идеологии Berkley Sockets, и особо не зависит даже от Windows/Linux/etc.
https://superuser.com/questions/173535/what-are-close-wait-and-time-wait-states
Re[2]: PostAsync
От: vaa https://www.youtube.com/playlist?list=PLtrvASfI1KW7VOYRKjglcagQzWLoxlncl
Дата: 06.04.22 01:58
Оценка:
Здравствуйте, vasmann, Вы писали:

V> Это ошибка. Может привести к исчерпанию хендлов на процессе (зависит, понятно от частоты и времени непрерывной работы приложения)


Почитал, там нет слов "хендлов", "на процессе".
В ip v4 на один адрес доступно 65K портов. при клиентском соединении выбирается любой свободный.
по v6 не нашел, возможно такое же, но думаю больше.
к тому же время жизни осиротевшего сокета по умолчанию 60 сек.
сколько раз можно вызвать http-запрос с клиента, чтобы такое случилось?
Скорее сервак откажет в обслуживании такого количества запросов.

Впрочем к стартовому вопросу это не имеет отношения.
Согласен только что
Re[3]: PostAsync
От: Mr.Delphist  
Дата: 06.04.22 08:57
Оценка: 9 (1)
Здравствуйте, vaa, Вы писали:

vaa>В ip v4 на один адрес доступно 65K портов. при клиентском соединении выбирается любой свободный.

vaa>по v6 не нашел, возможно такое же, но думаю больше.

В протоколе IP нет понятия "порт", т.к. порт — это атрибут транспортного уровня (TCP, UDP, SCTP), а не сетевого (IPv4, IPv6).
Например, в процессе путешествия между отправителем и получателем транспортные пакеты, в зависимости от топологии сети, могут в одном сегменте идти по IPv4, в следующем перепаковаться в IPv6, затем снова IPv4 или даже более сложные варианты со всякими reassembling и т.п. (теоретически, даже через non-IP протокол, если тот обеспечивает должную маршрутизацию). Поэтому лимит портов неизменен.

Далее, про количество доступных портов вообще: несмотря на то, что в теоретический лимит 65К — как и всегда бывает на практике, актуальное число куда меньше.

vaa>к тому же время жизни осиротевшего сокета по умолчанию 60 сек.

vaa>сколько раз можно вызвать http-запрос с клиента, чтобы такое случилось?
vaa>Скорее сервак откажет в обслуживании такого количества запросов.

https://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html

TIME_WAIT is often also known as the 2MSL wait state. This is because the socket that transitions to TIME_WAIT stays there for a period that is 2 x Maximum Segment Lifetime in duration. The MSL is the maximum amount of time that any segment, for all intents and purposes a datagram that forms part of the TCP protocol, can remain valid on the network before being discarded. This time limit is ultimately bounded by the TTL field in the IP datagram that is used to transmit the TCP segment. Different implementations select different values for MSL and common values are 30 seconds, 1 minute or 2 minutes. RFC 793 specifies MSL as 2 minutes and Windows systems default to this value but can be tuned using the TcpTimedWaitDelay registry setting.


Т.е. время полного закрытия всяко больше 60 секунд, если к этому не предпринимать спецусилий.
Re[3]: PostAsync
От: vasmann  
Дата: 06.04.22 09:18
Оценка: 9 (1) +1
Здравствуйте, vaa, Вы писали:

vaa>Здравствуйте, vasmann, Вы писали:


V>> Это ошибка. Может привести к исчерпанию хендлов на процессе (зависит, понятно от частоты и времени непрерывной работы приложения)


vaa>Почитал, там нет слов "хендлов", "на процессе".


Сокет — хендл, ну так было. Может что-то поменяли, но сомневаюсь. Их (сокетов) под 65 тысяч, на деле, для процесса — меньше, потому, что система еще отбирает. При этом это общесистемный ресурс.


vaa>сколько раз можно вызвать http-запрос с клиента, чтобы такое случилось?

vaa>Скорее сервак откажет в обслуживании такого количества запросов.

У нас при 4-5 тысячах запросах в секунду начинала возникать ситуация когда ни новые запросы мы отправить не можем, ни клиенты уже не могут подключиться (потому что как и сказал выше — ресурс общий на систему). Выявилась проблема очень быстро, как раз когда "веб апи запросы воткнули без кеширований и прочих ухищрений", исправилась не сразу, потому что и нагрузки были пиковыми — не постоянно 4-5. На саму проблему зашли именно через поддержку — начали поступать жалобы от клиентов, что не могут подключиться, хотя сервер молотил, вроде бы как + были моменты когда сама поддержка не могла зайти на сервер (по той же причине — исчерпались сокеты). При 2-3 запросах в минуту — проблема может и не возникнуть.
Тем не менее ключевое — классы нужно использовать правильно, конкретно HttpClient спроектирован так, что его легко использовать не правильно, а узнать о неправильности можно уже в проде. Хотя достаточно, лично с моей точки зрения, этот аспект в самом начале выделить секцией Warning и жирным текстом подсветить, а не так как сейчас, где-то мимолётом написан GoodController, а перед ним такое мало важное сообщение, что может возникнуть истощение по сокетам — ерунда, какая.
Re: PostAsync
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 06.04.22 12:58
Оценка:
Здравствуйте, e.thrash, Вы писали:

Подводные камни HttpClient в .NET
и солнце б утром не вставало, когда бы не было меня
Re[4]: PostAsync
От: vaa https://www.youtube.com/playlist?list=PLtrvASfI1KW7VOYRKjglcagQzWLoxlncl
Дата: 06.04.22 14:14
Оценка:
Здравствуйте, vasmann, Вы писали:



V>У нас при 4-5 тысячах запросах


кстати, 65К это же на айпи-адрес, как я понял проблема актуальна для серверных приложений,
на сервер можно поставить несколько интерфейсов, на которые привязать несколько адресов,
единственно не знаю, можно из дотнета управлять с какого интерфейса пойдет запрос.
Re[5]: PostAsync
От: Sharov Россия  
Дата: 08.04.22 12:03
Оценка:
Здравствуйте, vaa, Вы писали:

vaa>кстати, 65К это же на айпи-адрес, как я понял проблема актуальна для серверных приложений,

vaa>на сервер можно поставить несколько интерфейсов, на которые привязать несколько адресов,
vaa>единственно не знаю, можно из дотнета управлять с какого интерфейса пойдет запрос.

http://rsdn.org/forum/network/7787432?tree=tree
Автор: netch80
Дата: 28.07.20
Кодом людям нужно помогать!
Re[6]: PostAsync
От: vaa https://www.youtube.com/playlist?list=PLtrvASfI1KW7VOYRKjglcagQzWLoxlncl
Дата: 08.04.22 12:05
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, vaa, Вы писали:


vaa>>кстати, 65К это же на айпи-адрес, как я понял проблема актуальна для серверных приложений,

vaa>>на сервер можно поставить несколько интерфейсов, на которые привязать несколько адресов,
vaa>>единственно не знаю, можно из дотнета управлять с какого интерфейса пойдет запрос.

S>http://rsdn.org/forum/network/7787432?tree=tree
Автор: netch80
Дата: 28.07.20


отл. осталось понять как клиента заставить ходить с разных ip.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.