mirror of
https://github.com/telemt/telemt.git
synced 2026-11-01 13:21:58 +03:00
Retry Jitter in Docs
This commit is contained in:
+39
-12
@@ -94,7 +94,7 @@ flowchart LR
|
||||
W5 --> W6["Получен TL_pong<br/>Отображаемый замер завершён"]
|
||||
X["Только если нужно ещё одно соединение<br/>TCP + TLS, возможный WebSocket Upgrade<br/>При переиспользовании нет handshake на каждый ping"] -.-> W3
|
||||
X -.-> W5
|
||||
R["Только при ошибках или перегрузке<br/>Повторы и backoff<br/>Retry-After: 1 может добавить около секунды"] -.-> W3
|
||||
R["Только при ошибках или перегрузке<br/>Повторы и backoff<br/>База Telemt 250 мс<br/>Плюс опциональный jitter"] -.-> W3
|
||||
R -.-> W5
|
||||
end
|
||||
classDef preparation fill:#eeeeee,stroke:#666666,color:#111111
|
||||
@@ -113,6 +113,30 @@ flowchart LR
|
||||
|
||||
Таким образом, в видимую разницу могут войти оставшееся открытие WEB-потока, дополнительные соединения, обработка транспорта, планирование и подтверждённые повторы. Это не фиксированная надбавка TLS и не арифметическая сумма блоков. Начальный настоящий TLS намеренно показан до таймера Android: он влияет на полное время проверки, но обычно не на отображаемый замер. Отдельный транспорт проверки также означает, что активное соединение приложения не гарантирует прогретую проверку в списке прокси.
|
||||
|
||||
### Настраиваемый jitter HTTP-повторов
|
||||
|
||||
`[web.retry_jitter]` добавляет независимо выбранную задержку к каждому существующему HTTP-повтору бриджа: сетевым ошибкам и ответам 408/429/502/503/504. Менять приложения Telegram не требуется. Без секции или при `enabled = false` сохраняются подсказка Telemt на 250 мс и прежний backoff/jitter.
|
||||
|
||||
```toml
|
||||
[web.retry_jitter]
|
||||
enabled = true
|
||||
min_ms = 0
|
||||
max_ms = 250
|
||||
distribution = "uniform"
|
||||
# Only for distribution = "triangular":
|
||||
# peak_ms = 125
|
||||
```
|
||||
|
||||
Диапазон задаёт **добавку**, а не полную паузу: подсказка Telemt 250 мс с этим примером даёт 250–500 мс. Без положительной серверной подсказки база остаётся 250, 500, 1000, затем 2000 мс. Включённый jitter заменяет прежний jitter до 25%. Корректный стандартный `Retry-After` во включённом режиме не сокращается прежним пределом в 30 секунд. Если пауза не помещается в оставшийся бюджет операции, бюджет истекает без раннего повтора.
|
||||
|
||||
Значения по умолчанию: `enabled = false`, `min_ms = 0`, `max_ms = 250`, `distribution = "uniform"`, `peak_ms` отсутствует. Требуется `0 <= min_ms <= max_ms <= 30000`. `uniform` выбирает целые миллисекунды равномерно; `triangular` использует треугольную плотность с округлением до миллисекунд. Необязательный пик по умолчанию находится посередине и должен входить в диапазон. Явный пик для `uniform`, неизвестные ключи/распределения и неверные границы отклоняются даже при выключенной опции. Одинаковые границы дают постоянную добавку.
|
||||
|
||||
Политика фиксируется в каждой странице бриджа. Reload через конфиг/API влияет на новые страницы; активные сохраняют настройки при recovery. Recovery JSON и HTTP-заголовки совместимости не меняются. Используется `crypto.getRandomValues`, при недоступности — `Math.random` для совместимости. Успешный трафик не задерживается. Лимиты попыток, общий бюджет, отмена и повтор неизменных payload/sequence сохраняются; более длинные паузы могут уменьшить число попыток, помещающихся в startup/recovery-бюджет.
|
||||
|
||||
Это размывает фиксированные интервалы повторов, но не гарантирует защиту от DPI. Планирование браузера, сетевые очереди и другие временные характеристики протокола остаются наблюдаемыми. Существующие примеры временной шкалы описывают выключенную опцию. Для включённого режима добавляйте выбранную задержку к каждой паузе повтора, а не к первому соединению или каждому кадру данных.
|
||||
|
||||
Политика меняет только уже предусмотренные паузы перед повтором. Более строгие ограничения отдельных вызовов сохраняются: обычный poll `/down` и вызов `/up` после commit выполняют одну попытку; их replay при восстановлении допускает две. Опция не создаёт новых циклов повторов. Она не продлевает `web.timeouts.bridge_retry_secs` и сроки запуска или восстановления.
|
||||
|
||||
## Ориентировочная временная шкала
|
||||
|
||||
**Поясняющая модель, а не бенчмарк и не норматив задержки.** Числа подобраны, чтобы показать сложение этапов. Они не восстанавливают наблюдавшиеся 1000–1500 мс. Условия примера: DNS уже закеширован, RTT от клиента до фронтенда — 40 мс, TCP-соединение новое, при необходимости выполняется полный TLS 1.3 handshake, ключ авторизации DC уже есть, потерь и сброса нативной временной метки запроса нет. Базовый вариант — Classic/DD. Для EE собственная подготовка FakeTLS добавляется до нативного таймера.
|
||||
@@ -126,10 +150,10 @@ flowchart LR
|
||||
gantt
|
||||
dateFormat x
|
||||
axisFormat %S.%L
|
||||
tickInterval 200millisecond
|
||||
tickInterval 100millisecond
|
||||
todayMarker off
|
||||
title Отображаемый ping - условная модель
|
||||
accTitle: Отображаемый ping - условная модель
|
||||
title Отображаемый ping - jitter выключен
|
||||
accTitle: Отображаемый ping - jitter выключен
|
||||
accDescr: Секунды от метки запроса, подписи этапов в миллисекундах
|
||||
section Classic/DD - 100 мс
|
||||
R 100 мс :n_r, 0, 100ms
|
||||
@@ -137,28 +161,31 @@ gantt
|
||||
U 40 мс :w_u, 0, 40ms
|
||||
R 100 мс :w_r, after w_u, 100ms
|
||||
D 60 мс :w_d, after w_r, 60ms
|
||||
section WEB с повтором - 1240 мс
|
||||
section WEB с повтором - 490 мс
|
||||
F 40 мс :crit, f_u, 0, 40ms
|
||||
Ожидание 1000 мс :crit, retry_wait, after f_u, 1000ms
|
||||
Ожидание 250 мс :crit, retry_wait, after f_u, 250ms
|
||||
U 40 мс :retry_u, after retry_wait, 40ms
|
||||
R 100 мс :retry_r, after retry_u, 100ms
|
||||
D 60 мс :retry_d, after retry_r, 60ms
|
||||
```
|
||||
|
||||
Длительности этапов: `R` = 100 мс базовой работы MTProxy relay/сети/DC для запроса и ответа. `U` = 40 мс дополнительной работы WEB на отправке/OPEN/клиенте. `D` = 60 мс дополнительной работы WEB на приёме и доставке. `F` = 40 мс одной неудачной попытки upload. `Ожидание` = 1000 мс ожидания по `Retry-After: 1`. `U` и `D` — условные дополнительные затраты сверх `R`, а не повторный учёт полного сетевого RTT. Ожидание ACK/commit учитывается лишь в той мере, в какой оно действительно задержало доставку.
|
||||
Длительности этапов: `R` = 100 мс базовой работы MTProxy relay/сети/DC для запроса и ответа. `U` = 40 мс дополнительной работы WEB на отправке/OPEN/клиенте. `D` = 60 мс дополнительной работы WEB на приёме и доставке. `F` = 40 мс одной неудачной попытки upload. `Ожидание` = 250 мс ожидания по `X-Telemt-Retry-After-Ms: 250`. `U` и `D` — условные дополнительные затраты сверх `R`, а не повторный учёт полного сетевого RTT. Ожидание ACK/commit учитывается лишь в той мере, в какой оно действительно задержало доставку.
|
||||
|
||||
| Сценарий | До таймера ping | Отображаемый ping | Полное время проверки в модели |
|
||||
| --- | --- | --- | --- |
|
||||
| Classic/DD | 40 мс | 100 мс | 140 мс |
|
||||
| WEB без ошибок | 750 мс | 40 + 100 + 60 = 200 мс | 950 мс |
|
||||
| WEB с одной неудачной загрузкой и одним ожиданием повтора | 750 мс | 40 + 1000 + 40 + 100 + 60 = 1240 мс | 1990 мс |
|
||||
| WEB с одной неудачной загрузкой и одним ожиданием повтора | 750 мс | 40 + 250 + 40 + 100 + 60 = 490 мс | 1240 мс |
|
||||
| WEB, тот же повтор с uniform jitter 0–250 мс | 750 мс | 490–740 мс | 1240–1490 мс |
|
||||
|
||||
Ещё одно TCP + TLS 1.3 соединение, открытое **внутри** замера, могло бы добавить здесь около 80 мс при полностью последовательном выполнении: замер 200 мс превратился бы в 280 мс. При переиспользовании соединения затраты на этот дополнительный handshake равны нулю. Замена начального полного TLS 1.3 handshake на TLS 1.2 при этих условиях добавляет примерно 40 мс к подготовке, а не к показанному ping. В примерах не учтены обработка TLS, возобновление сессии и потери пакетов.
|
||||
|
||||
Строка с 1240 мс показывает один возможный механизм секундного результата — повтор, подтверждённый HTTP-трассировкой. Она не доказывает, что исходное наблюдение вызвано повторами. Если такого повтора нет, нужно найти другие фактические задержки: очереди, буферизацию фронтенда, открытие соединений или работу upstream. Не подставляйте таймауты вместо пауз и не переносите перекрывающиеся этапы в эту последовательную модель без проверки.
|
||||
Строка с 490 мс и диаграмма показывают один повтор при выключенном jitter. Дополнительная строка таблицы применяет к тому же повтору `enabled = true`, `min_ms = 0`, `max_ms = 250`, `distribution = "uniform"`; её диапазон получен из модели, а не измерений. Прежний JavaScript-мост без миллисекундного расширения или посредник, удаляющий эту подсказку при выключенном jitter, сохраняет стандартную секундную паузу: отображаемый ping в той же модели составит 1240 мс. Ни один сценарий не устанавливает причину исходного наблюдения. Если повторы не подтверждены трассировкой, ищите другие задержки: очереди, буферизацию фронтенда, открытие соединений или upstream. Не подставляйте таймауты вместо пауз и не переносите перекрывающиеся этапы в эту последовательную модель без проверки.
|
||||
|
||||
## HTTP, WebSocket и другие источники задержки
|
||||
|
||||
Ответы Telemt при перегрузке содержат `Retry-After: 1` и `X-Telemt-Retry-After-Ms: 250`. Только статус `503` с этой точной парой заголовков задаёт сгенерированному мосту **базовую паузу 250 мс**. При `web.retry_jitter.enabled = false` пауза равна 250 мс; при включении добавляется настроенная случайная задержка. Для остальных ответов действуют стандартная обработка `Retry-After` или резервный backoff, описанные ниже. Ранее загруженные страницы JavaScript-моста без поддержки миллисекундной подсказки используют секундную паузу до загрузки новой страницы; обновлять приложение Telegram для этого не нужно. Лимиты попыток, абсолютные бюджеты, отмена и ограничения admission не меняются.
|
||||
|
||||
| Фактор | Влияние и подтверждение |
|
||||
| --- | --- |
|
||||
| HTTP uplink | Генерируемый мост предлагает `X-Telemt-Up-Window: 4`; сервер принимает 1–4, при отсутствии согласования используется 1. Окно 1 ждёт ACK перед следующей загрузкой, окно 4 допускает ограниченный параллелизм. Не весь HTTP работает по схеме «отправить и ждать». См. [согласование][runtime] и [обработчик сессии][session]. |
|
||||
@@ -168,7 +195,7 @@ gantt
|
||||
| Буферизация фронтенда | Буферизация запросов/ответов или отсутствие поддержки streaming/Upgrade могут задерживать короткие сообщения. Сверьте настройки с существующим примером NGINX, сохраняя маршрутизацию, аутентификацию и лимиты. |
|
||||
| Планирование клиента | Java accept/read, UI dispatch, WebView/JavaScript и возврат в нативный код добавляют очереди. Нагрузка CPU, энергосбережение и смена мобильной сети могут усиливать задержки. |
|
||||
| Пересылка и сеть | Могут учитываться оставшийся admission потока, внутренний MTProxy-handshake, подключение Direct или регистрация ME, ответ Telegram, потери/повторная передача и очереди. Готовая WEB-сессия не доказывает готовность upstream. |
|
||||
| Ошибки и повторы | Telemt может вернуть `503` с `Retry-After: 1`. Мост учитывает его; для других повторов backoff начинается с 250 мс и удваивается до 2000 мс плюс jitter примерно до 25%, в пределах бюджета повторов. Повторяемые HTTP-статусы включают 408/429/502/503/504. Прежде чем объяснять секундную ступень этим механизмом, нужно увидеть события в трассировке. См. [ответы][response] и [повторы][request]. |
|
||||
| Ошибки и повторы | Повторяемые статусы: 408/429/502/503/504. При выключенном jitter точная подсказка Telemt задаёт паузу 250 мс; без положительной подсказки сервера backoff начинается с 250 мс и удваивается до базовых 2000 мс плюс прежний jitter менее 25%. При включённом jitter пауза равна положительной подсказке сервера или этой базе **плюс** настроенная случайная добавка, заменяющая прежний jitter. Бюджеты и ограничения попыток отдельных вызовов сохраняются. Фиксируйте политику загруженного моста и фактическое время повторов. См. [ответы][response] и [повторы][request]. |
|
||||
|
||||
Дедлайны не являются обязательными паузами. Стандартные 10 с для запроса моста, 90 с бюджета повторов, 30 с ожидания первого байта потока и 10 с handshake потока нельзя складывать в обычный ping. `carrier_probe_coalesce_ms=0` отключает соответствующую дополнительную задержку объединения проб. Дедлайны переключения транспорта относятся к неудачным попыткам, а не к каждому успешному обмену. См. [значения по умолчанию](../../src/config/types/web/defaults.rs).
|
||||
|
||||
@@ -176,7 +203,7 @@ gantt
|
||||
|
||||
## Диагностика с сохранением защит
|
||||
|
||||
1. Запишите клиент/сборку, версию Android WebView, транспорт, публичный endpoint, семейство IP, сеть, маршрут Direct/ME, DC и нагрузку. Сравнивайте при одинаковых условиях. Учитывайте двухминутное кеширование Android: повторное чтение интерфейса не означает новый замер.
|
||||
1. Запишите клиент/сборку, версию Android WebView, политику `web.retry_jitter` загруженного моста, транспорт, публичный endpoint, семейство IP, сеть, маршрут Direct/ME, DC и нагрузку. Сравнивайте при одинаковых условиях. Учитывайте двухминутное кеширование Android: повторное чтение интерфейса не означает новый замер.
|
||||
2. Разделяйте три эксперимента: новую проверку в списке прокси; новый логический поток на готовом транспорте; прикладной RPC в установленной MTProto-сессии. Последние два требуют подходящих средств измерения в клиенте и не предоставляются автоматически списком прокси. Собирайте отдельные замеры и распределения, а не сравнивайте единичный холодный замер с прогретым.
|
||||
3. Используйте аутентифицированный `GET /web-status` и существующие настройки `[web.debug]`: `capture_timings=true`, `capture_frames=true`, `body_capture="metadata"`. Включите ограниченный сбор по [руководству диагностики WEB](WEB_PROXY.ru.md), затем восстановите предыдущее состояние. Payload, capabilities и секреты для этой задачи не нужны.
|
||||
4. Сопоставьте создание сессии, выбор/commit/ошибку транспорта, `stream_admitted`, `stream_first_byte`, `handshake_succeeded`, OPEN/DATA, HTTP-статусы и повторы. `relay_started` предшествует работе с upstream и не означает готовность DC. `GET /v1/runtime/web/status` и `GET /v1/runtime/web/sessions` дают контекст ёмкости и давления очередей, а не сквозной RTT.
|
||||
@@ -184,7 +211,7 @@ gantt
|
||||
6. Добавьте измерения соединений/TLS/запросов фронтенда и временные метки клиента, чтобы найти задержку вне Telemt. Проверьте повторное использование соединений, согласованный HTTP, буферизацию и Upgrade. Sideband-события запуска моста/HELLO не дают полную временную шкалу клиента. Для сравнения разных хостов синхронизируйте часы либо используйте локальные длительности.
|
||||
7. При ME сопоставьте существующий trace `ME RTT sample` (`rtt_ms`, `ema_ms`, `base_ms`, `degraded`). Метка ставится до очереди writer/flush; EMA состоит из 80% прежнего значения и 20% нового замера. Планирование keepalive до этой метки не учитывается. Низкий ME RTT при высоком Android ping указывает на работу вне измеренного участка ME, но не определяет конкретную причину. См. [writer][writer] и [reader][reader].
|
||||
|
||||
Примеры интерпретации: быстрая обработка Telemt при поздней доставке клиенту направляет проверку к фронтенду, сети и очередям клиента; `503` вместе с `Retry-After: 1` подтверждает задержку повтора; длительная работа upstream требует изучения Direct/ME. Ни один из признаков сам по себе не доказывает, что 1000–1500 мс вызваны криптографией TLS. При сборе данных сохраняйте совместимость, проверку сертификатов, лимиты admission и backpressure.
|
||||
Примеры интерпретации: быстрая обработка Telemt при поздней доставке клиенту направляет проверку к фронтенду, сети и очередям клиента; `503` и его retry-заголовки определяют базовую задержку, а политика jitter загруженного моста и клиентские отметки времени позволяют установить фактическую паузу; длительная работа upstream требует изучения Direct/ME. Ни один из признаков сам по себе не доказывает, что 1000–1500 мс вызваны криптографией TLS. При сборе данных сохраняйте совместимость, проверку сертификатов, лимиты admission и backpressure.
|
||||
|
||||
## Границы подтверждения
|
||||
|
||||
|
||||
Reference in New Issue
Block a user