Ця стаття є дзеркальною статтею машинного перекладу, будь ласка, натисніть тут, щоб перейти до оригінальної статті.

Вид: 6079|Відповідь: 4

[Джерело] Неправильне використання HttpClient може пошкодити ваше програмне забезпечення

[Копіювати посилання]
Опубліковано 14.05.2022 17:11:56 | | | |
Я неправильно користувався HttpClient роками, але зрештою настала справжня катастрофа. Мій сайт був нестабільним, мої клієнти були дуже розлючені, і з простим виправленням продуктивність значно покращилася, а нестабільність усунута.



Водночас я навіть покращив продуктивність свого додатка, ефективніше використовуючи сокет.

Мікросервіси можуть бути складною проблемою. Зі збільшенням кількості сервісів і розкладанням монолітних додатків між сервісами з'являється все більше шляхів зв'язку. Існує багато варіантів зв'язку, але HTTP — дуже популярний варіант. Якщо мікросервіс побудований на C# або будь-якій мові .NET, швидше за все, ви вже використовуєте HttpClient.


Проблема полягає в тому, що

Оператор using — це функція C#, яка обробляє одноразові об'єкти. Після завершення використання блоку єдиний об'єкт (у цьому випадку HttpClient) виходить за межі сфери об'єкта і зникає. Зателефонуйте до системи утилізації та приберіть усі ресурси, які використовуються. Це дуже типовий шаблон у .NET, який ми використовуємо для всього — від бази даних до flow writer. Насправді будь-який об'єкт із зовнішнім ресурсом, який потрібно очистити, використовує цей IDisposable інтерфейс.

І тебе не можна звинувачувати в тому, що ти хочеш загорнути його у вживання. По-перше, це вважається доброю практикою. Насправді офіційна документація Microsoft використовує:


Загалом, при використанні IDisposable об'єкта його слід оголосити та інстанціювати у операторі use.
По-друге, весь код, який ви могли бачити...... Початок HttpClient підкаже використовувати блок операторів використання, включаючи останню документацію ASP.NET самого сайту. Те саме сказано в статті в Інтернеті.

Але HttpClient — це інший. Хоча він реалізує інтерфейс IDisposable, насправді це спільний об'єкт. Це означає, що за лаштунками він є реентрантом і безпечним для потоків. Вам слід ділитися екземпляром HttpClient протягом усього життя вашого додатка, а не створювати новий екземпляр для кожного виконання. HttpClient, давайте подивимось чому.

Подивись сам

Ось проста програма для демонстрації HttpClient:

Це буде адресовано  http://aspnetmonsters.comВідкрийте 10 запитів і зробите GET, ми просто друкуємо статус коду, щоб бути впевненими, що все працює. Результат буде:

Зачекайте, це ще не все!

Вся робота і все — це правильне для світу. Але це не так. Якщо ми дістанемо інструмент netstat і подивимося на стан сокета на машині, що його запускає, ми побачимо:

C:\code\socket>NETSTAT.EXE
...
  Прото-локальна адреса Стан іноземної адреси
  TCP 10.211.55.6:12050 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12051 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12053 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12054 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12055 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12056 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12057 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12058 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12059 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12060 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12061 waws-prod-bay-017:http TIME_WAIT
  TCP 10.211.55.6:12062 waws-prod-bay-017:http TIME_WAIT
  TCP 127.0.0.1:1695 SIMONTIMMS742B:1696 СТВОРЕНО
...
Ну, це дивно...... Додаток вийшов, але до Azure-машини, яка хостить сайт ASP.NET Monsters, все ще відкрито багато таких з'єднань. Вони всерединіTIME_WAITстатус, тобто з'єднання закрито з одного боку (нашого), але ми все ще чекаємо, чи надходять інші пакети, бо вони могли затриматися десь у мережі. Ось діаграма статусу TCP/IP:



Windows залишатимуться підключеними в цьому стані протягом 240 секунд (встановлено налаштуванням [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay]). Windows має обмеження на швидкість відкриття нового сокета, тому якщо у вас закінчаться пули підключень, ви можете побачити таку помилку:

Не вдається підключитися до віддаленого сервера
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
Пошук у Google дасть вам погані поради щодо скорочення тайм-аутів з'єднання. Насправді, при правильному запуску на сервері з HttpClient або подібно побудованим додатком скорочення тайм-аутів може призвести до інших негативних наслідків. Нам потрібно розуміти, що означає «правильно», і вирішувати основну проблему, а не возитися з машинними змінними.

Виправ це

Якщо ми поділимося екземпляром HttpClient, то можемо зменшити втрати сокета, повторно використовуючи їх:

Зверніть увагу, що для всього додатку у нас є лише один спільний екземпляр. HttpClient все ще працює як раніше (насправді трохи швидше через повторне використання сокета). Netstat тепер показує лише:

TCP 10.211.55.6:12254 waws-prod-bay-017:http ВСТАНОВЛЕНО
У продакшн-сценарії середня кількість сокетів становить близько 4000, а пік — понад 5000, фактично стискаючи доступні ресурси на сервері і спричиняючи збій сервісу. Після впровадження цієї зміни кількість використаних розеток зменшилася з середнього понад 4000 до стабільно менше ніж 400, зазвичай близько 100.

Це частина діаграми з нашого інструменту моніторингу, яка показує, що відбувається після розгортання обмеженої кількості proofproofs для вибраної кількості мікросервісів.




Це було драматично. Якщо у вас є будь-яке навантаження, слід пам'ятати про ці дві речі:

Зробіть свій HttpClient статичним.
Не відкидайте і не пакуйте своє використання, якщо тільки ви не шукаєте конкретну поведінку (наприклад, спричинити збій вашого сервісу). HttpClient


зведення

Проблема виснаження суглобів, з якою ми боремося місяцями, зникла, і наші клієнти мають віртуальний парад. Я не можу недооцінювати, наскільки ця помилка неочевидна. За ці роки ми звикли працювати з реалізованими об'єктами, IDisposable, і багато інструментів рефакторингу, таких як R# і CodeRush, насправді попереджають, якщо ви цього не зробите. У цьому випадку позбавлення HttpClient є неправильним підходом. HttpClient реалізує IDisposable і заохочує погану поведінку, на жаль

Оригінальний:Вхід за гіперпосиланням видно.




Попередній:ASP.NET Core розміщує моделі In-Process та Out-of-Process у IIS
Наступний:ASP.NET Core (XV) використовує HttpClient для надсилання HTTP-запитів
 Орендодавець| Опубліковано 14.05.2022 17:25:22 |
TCP TIME_WAIT — це звичайна операція протоколу TCP, тобто після проходження останнього FIN-ACK клієнт чекає на завершення подвійного максимального часу життя (MSL), щоб переконатися, що віддалений TCP отримає підтвердження запиту на завершення з'єднання. За замовчуванням MSL триває 2 хвилини. Ви можете залишатися в TIME_WAIT до 4 хвилин, що називається двома MSL.

https://docs.microsoft.com/en-us ... t-from-netstat.html
Опубліковано 14.05.2022 22:35:22 |
Вчитися вчитися
Опубліковано 19.05.2022 09:39:05 |
Це все китайська, але я не можу зрозуміти, коли це пов'язано у речення
 Орендодавець| Опубліковано 06.11.2023 07:16:05 |
тест
Застереження:
Усе програмне забезпечення, програмні матеріали або статті, опубліковані Code Farmer Network, призначені лише для навчання та досліджень; Вищезазначений контент не повинен використовуватися в комерційних чи незаконних цілях, інакше користувачі несуть усі наслідки. Інформація на цьому сайті надходить з Інтернету, і спори щодо авторських прав не мають до цього сайту. Ви повинні повністю видалити вищезазначений контент зі свого комп'ютера протягом 24 годин після завантаження. Якщо вам подобається програма, будь ласка, підтримуйте справжнє програмне забезпечення, купуйте реєстрацію та отримайте кращі справжні послуги. Якщо є будь-яке порушення, будь ласка, зв'яжіться з нами електронною поштою.

Mail To:help@itsvse.com