TGStat
TGStat
Qidiruv uchun matnni kiriting
Ilg‘or kanal qidiruvi
  • flag Uzbek
    Sayt tili
    flag Russian flag English flag Uzbek
  • Saytga kirish
  • Katalog
    Kanal va guruhlar katalogi Hududiy to‘plamlar Tematik to‘plamlar Платные каналы Kanallar qidiruvi
    Kanal/guruh qo‘shish
  • Reytinglar
    Kanallar reytingi Guruhlar reytingi Postlar reytingi
    Brendlar va shaxslar reytingi
  • Analitika
  • Postlarda qidiruv
  • Telegram'ni kuzatish
  • Targ‘ibot
    Yandex Business orqali reklama TGStat Agency orqali kanallarda reklama TGStat.ru saytida reklama
.NET sh blog

4 Feb 2025, 20:42

Telegram'da ochish Ulashish Shikoyat qilish

Немного про CancellationToken.

Основная её цель - иметь источник уведомлений о том, что результат работы которую выполняет ваш API или метод больше никто не ждет. Грустно, но такое бывает.

Начну чуть издалека :)

Существует миф что сеть стабильна. Но это не так. К тому же сейчас очень многие применяют микросервисную архитектуру, которая намного более интенсивно использует сеть. А значит больше точек отказа.
Еще обычно всё хостится в k8s, что еще больше усложняет топологию и перед вашим микросервисом может быть 5-6 балансировщиков и прокси, а то и больше :)

Типичный маршрут запроса в микросервис который расположен допустим в Yandex Cloud Managed k8s:

Yandex Network LoadBalancer -> k8s gateway / ingress -> k8s service -> ApiGateway -> k8s service -> ваш микросервис

Перед всем этим можно еще подключить защиту от DDoS (в виде еще одного прокси).
Часто еще делают AuthN/AuthZ прокси перед ApiGateway.. или еще Service Mesh.
Помимо этого в компании могут быть еще общие внешние балансировщики и вполне вероятно что даже и не один.

Так вот цепочек сетевых вызовов много, сеть нестабильна и на любом вызове может произойти ошибка, таймауты или просто пользователь закрыл вкладку браузера или перешел на другую страницу.
Во всех этих случаях, о результатах работы сервера уже никто не узнает и не ждет.

Как HTTP отменяет запросы?
HTTP/1.x - клиент просто закрывает TCP соединение
HTTP/2 - отправляет фрейм RST_STREAM, чтобы отменить запрос (стрим), но не закрывать соединение.
HTTP/3 - аналогично HTTP/2

Если погрузиться в исходники Kestrel, можно найти обработку этих ситуаций и вызов CancellationTokenSource.Cancel(),
CancellationToken которого пробрасывается в HttpContext.RequestAborted или в параметр экшена контроллера.

Нам надо только пробросить его дальше в наши методы и обязательно туда где есть IO операции или тяжелые CPU bound задачи.
Например HTTP, запросы в бд, чтение файлов. Чтобы если такая ситуация произойдет, мы могли отменить тяжелые операции и быстро освободить ресурсы на что-нибудь полезное.

Помимо экономии ресурсов, отмена запросов позволяет в некоторых случаях сделать систему более консистентной.

Бывало ли у Вас такое, что вы отправляете во внешнюю систему POST запрос на создание ресурса, ловите таймаут, делаете ретрай с помощью Polly, а потом внезапно обнаруживаете, что создалось 2 (или более) ресурсов, вместо одного.

Такое часто возникает когда в API не предусмотрели отмену запроса. Или если запрос был прерван по другой причине и Вы не успели прочитать успешный ответ от сервера и сделали повторный запрос.

Эта проблема решается реализацией идемпотентности, о котором я расскажу в следующий раз.

Так вот я провел бенчмарк, на простых HTTP эндпойнтах, которые просто ждут 1 секунду и отдают 200 OK. В одном используется CancellationToken, а в другом нет.

Сетап бенчмарка простой - 250VUs, 1 сек sleep между итерациями.
Каждую итерацию отправляется запрос и отменяется спустя случайное кол-во мс (от 1 до 600).
Так как тестируемый эндпойнт выполняется минимум 1000 мс, то все запросы гарантированно завершаются ошибочным ответом (499).

Результаты бенчмарков с точки зрения клиента не имеют особого смысла, так как запрос отправляется и отменяется достаточно быстро и результаты будут одинаковыми.

'https://t.me/sh_dotnet/103?comment=334' rel='nofollow'>Первый - эндпойнт который корректно отменяет запрос
'https://t.me/sh_dotnet/103?comment=335' rel='nofollow'>Второй - эндпойнт который не отменяет запрос

Но больше всего интересно не с точки зрения клиента, а с точки зрения сервера.
В проекте BookLibrary у меня настроена сборка метрик с помощью OpenTelemetry, поэтому можно посмотреть как долго в итоге эти запросы отрабатывались, а значит тратили процессорное время.

Смотрим на 'https://t.me/sh_dotnet/103?comment=336' rel='nofollow'>http_server_request_duration_seconds_sum, это суммарное кол-во секунд которое затратил сервер в разбивке по эндпойнтам.

Первый - 596s / 2006 = 298 ms на один запрос
Второй - 2094s / 2000 =1047ms на один запрос т.е. здесь тратятся ресурсы значительно больше

Бенчмарки и 'https://t.me/sh_dotnet/103?comment=333' rel='nofollow'>доп. материал в комментариях.

529 0 9 11 20
Katalog
Kanal va guruhlar katalogi Kanallar to‘plamlari Kanallar qidiruvi Kanal/guruh qo‘shish
Reytinglar
Telegram-kanallar reytingi Telegram-guruhlar reytingi Postlar reytingi Brendlar va shaxslar reytingi
API
Statistika API'si Postlar qidiruvi API'si API Callback
Kanallarimiz
@TGStat @TGStat_Chat @telepulse @TGStatAPI
O‘qish
Академия TGStat Telegram tadqiqoti 2019 Telegram tadqiqoti 2021 Telegram tadqiqoti 2023
Kontaktlar
Справочный центр Qo‘llab-quvvatlash Email Vakansiyalar
Har xil narsalar
Foydalanuvchi shartnomasi Maxfiylik siyosati Ommaviy oferta
Botlarimiz
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot