# Анатомия игровых лагов (Game Lag White Paper) > Справочник о том, откуда в онлайн-играх берутся лаги (микрофризы, телепортация, откидывание назад, перемотка, задержка ввода, фриз, дисконнект и другие). Причины (228) разобраны по 13 слоям, от вашего экрана до серверной базы данных, и 3 темам (архитектура синхронизации, проблемы только у части игроков, повторная передача TCP). Справочник написан на примерах MMO, но большая часть относится к онлайн-играм любого жанра. Для каждой причины: три шага «почему → следствие → на экране», связанные симптомы, цифры для ориентира, ответственные (команда разработки, команда инфраструктуры, внешние стороны) и задачи каждой команды, форма графика и способ проверки, авторитетные источники (RFC, официальная документация по ядру, ОС, облакам, движкам и БД, научные статьи). Причины обозначаются ID (например, mem-gc), и у каждой есть своя страница (например, https://jungrok5.github.io/mmo-lag-anatomy/ru/c/mem-gc.html). Цифры приведены для типичной среды сервиса, значения по умолчанию и версии подтверждены источниками на страницах причин. Для цитирования используйте адрес страницы причины. Лицензия MIT. Оригинал написан на корейском, это перевод: https://jungrok5.github.io/mmo-lag-anatomy/ ## Документы - [Полное содержание (Markdown)](https://jungrok5.github.io/mmo-lag-anatomy/ru/llms-full.txt): Все причины, симптомы, ответственные, термины и источники одним файлом - [Текстовая версия](https://jungrok5.github.io/mmo-lag-anatomy/ru/text.html): То же содержание на одной HTML-странице, без JavaScript - [Анатомия игровых лагов](https://jungrok5.github.io/mmo-lag-anatomy/ru/): Основная версия с иллюстрациями и интерактивными экспериментами ## Причины по симптомам - [Микрофризы](https://jungrok5.github.io/mmo-lag-anatomy/ru/s/stutter.html): Причин: 60. Движение теряет плавность: короткие остановки чередуются с рывками. - [Телепортация](https://jungrok5.github.io/mmo-lag-anatomy/ru/s/teleport.html): Причин: 47. Персонаж без промежуточного движения сразу оказывается далеко от прежнего места. - [Откидывание назад](https://jungrok5.github.io/mmo-lag-anatomy/ru/s/rubber.html): Причин: 14. Персонаж бежит вперёд, и его утягивает обратно на только что пройденное место. - [Перемотка](https://jungrok5.github.io/mmo-lag-anatomy/ru/s/burst.html): Причин: 36. Замерший экран снова оживает, и накопившиеся движения, удары и урон проносятся разом на большой скорости. - [Слоумо](https://jungrok5.github.io/mmo-lag-anatomy/ru/s/slowmo.html): Причин: 24. Всё движется медленно. Применение умений и перемещение монстров выглядят растянутыми. В зависимости от устройства сервера скорость может остаться прежней, и тогда проблема проявляется как микрофризы и телепортация. - [Задержка ввода](https://jungrok5.github.io/mmo-lag-anatomy/ru/s/delay.html): Причин: 76. Между нажатием и результатом проходит заметное время. При этом картинка может оставаться плавной. - [Фриз](https://jungrok5.github.io/mmo-lag-anatomy/ru/s/freeze.html): Причин: 67. Всё на экране ненадолго (от 0,5 с до нескольких секунд) замирает, а потом снова движется. - [Съеденные действия / роллбэк](https://jungrok5.github.io/mmo-lag-anatomy/ru/s/dropped.html): Причин: 36. Действие, которое точно было сделано, как будто не происходило, или его результат отменяется намного позже. - [Дисконнект](https://jungrok5.github.io/mmo-lag-anatomy/ru/s/disconnect.html): Причин: 51. Посреди игры соединение рвётся, и игрока возвращает на экран входа или в окно переподключения. - [Ошибка входа / бесконечная загрузка](https://jungrok5.github.io/mmo-lag-anatomy/ru/s/noconnect.html): Причин: 45. В игру не пускает, или всё застревает на экране загрузки или входа. - [Невидимки / фантомы](https://jungrok5.github.io/mmo-lag-anatomy/ru/s/invisible.html): Причин: 20. NPC, монстра или игрока, которые должны быть рядом, нет только на вашем экране, или уже исчезнувший объект остался только у вас. ## L1 Процесс игрового клиента - [Всплески времени кадра](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-hitch.html): Расчёт одного кадра занимает в несколько раз больше времени, чем обычно, и картинка на миг замирает. - [Сборка мусора на клиенте](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-gc.html): Пока освобождается использованная и уже ненужная память (мусор), вся игра стоит. Характерный признак: микрофризы через равные промежутки. - [Синхронная загрузка и компиляция шейдеров в главном потоке](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-sync-load.html): Перед первой отрисовкой новой локации, монстра или эффекта игра останавливается, чтобы прочитать файлы и скомпилировать шейдеры. - [Стриминг ассетов отстаёт из-за медленного накопителя](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-asset-stream.html): На медленном накопителе вроде HDD текстуры и модели открытого мира читаются медленнее, чем перемещается игрок. Объекты появляются с опозданием, или игра дёргается, ожидая окончания чтения. - [Нагрузка на рендеринг при большом скоплении игроков](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-crowd.html): Когда в кадр попадают сотни игроков, как на осаде или у мирового босса, клиент не справляется уже с самой отрисовкой. - [Узкое место: обработка пакетов в главном потоке](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-net-mainthread.html): Если за кадр обрабатывается только фиксированное число полученных пакетов, при наплыве пакеты всё время переносятся на следующие кадры. - [Буфер интерполяции отсутствует или слишком короткий](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-no-buffer.html): Если отрисовывать пакеты сервера сразу после получения, джиттер (неравномерность интервалов между пакетами) целиком виден на экране. - [Чрезмерная экстраполяция (dead reckoning)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-extrap.html): Пока пакеты не приходят, клиент продолжает двигать объект с последней известной скоростью, а обнаружив ошибку, возвращает его назад. - [Расхождение клиентского предсказания с сервером](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-predict.html): Клиент заранее показал движение персонажа игрока, но сервер посчитал иначе, и персонажа утягивает на серверную позицию. - [Лавина догоняющих шагов при фиксированном таймстепе](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-fixed-step.html): После одной остановки игра разом досчитывает накопившиеся шаги и из-за этого снова отстаёт. - [Ошибка синхронизации часов](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-clock.html): Если клиент неверно оценивает серверное время, сбиваются момент интерполяции и проверка кулдаунов. - [Потеря точности времени во float](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-float-time.html): Если игровое время хранится в формате с плавающей точкой низкой точности (float), то чем дольше работает клиент, тем хуже разрешение времени (наименьшая различимая разница во времени), и движения и эффекты начинают дрожать. - [V-Sync и очередь рендеринга](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-vsync.html): Отрисованные GPU кадры по несколько штук ждут в очереди и выводятся в такт монитору, поэтому ввод доходит до экрана с опозданием. - [Утечка памяти на клиенте](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-leak.html): Чем дольше работает игра, тем больше памяти она занимает, всё сильнее тормозит и в итоге принудительно закрывается. - [Краш клиента](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-crash.html): Игра закрывается из-за необработанной ошибки. Игроку это кажется дисконнектом, хотя сервер работает нормально. - [Проверки модуля защиты игры (античита)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/cg-anticheat.html): Модуль защиты от взлома работает вместе с игрой и периодически выполняет проверки. Если проверка тяжёлая или хартбит (периодический сигнал «я жив») с сервером защиты запаздывает, появляются микрофризы или дисконнект. ## L2 ОС и устройство клиента - [Фоновые процессы занимают CPU](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-background.html): Когда ядра заняты антивирусной проверкой, обновлением Windows, программой для стримов или видео в браузере, игровой поток не получает процессорного времени и ждёт. - [Энергосбережение и тепловой троттлинг](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-power.html): Из-за работы ноутбука от батареи, режима энергосбережения на телефоне или нагрева устройства падает скорость CPU и GPU. Характерный признак перегрева: сначала всё нормально, а тормоза начинаются заметно позже. - [Разрешение таймера](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-timer.html): Стандартный таймер Windows работает с шагом 15,6 ms, поэтому «подождать всего 1 ms» на деле растягивается до следующего тика таймера, то есть до 15,6 ms. - [Сворачивание мобильного приложения в фон](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-mobile-bg.html): Если ненадолго свернуть игру, чтобы посмотреть уведомление, через несколько секунд ОС приостанавливает приложение (suspend), а сервер тем временем отключает игрока. - [Переключение Wi-Fi ↔ LTE/5G](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-netswitch.html): Когда игрок выходит из дома, Wi-Fi пропадает и устройство переключается на LTE или 5G. IP-адрес меняется, и старое соединение перестаёт работать. - [Проверка пакетов защитным ПО](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-security.html): Когда антивирус или файрвол проверяет каждый пакет, задержка растёт, а при слишком строгих правилах игра принимается за атаку и блокируется. - [Переполнение буфера приёма](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-rcvbuf.html): Если игра занята и поздно забирает пакеты из сокета (интерфейса ОС для приёма и отправки данных по сети), буфер ОС переполняется. - [Нехватка памяти и своп на клиенте](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-swap.html): Если вместе с игрой открыты десятки вкладок браузера, ОС выгружает часть памяти игры на диск. - [Нехватка видеопамяти (VRAM)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-vram.html): Если графическим настройкам нужно больше памяти, чем есть на видеокарте, ОС выгружает текстуры в оперативную память ПК и загружает обратно, и появляются микрофризы. - [Фоновое сканирование Wi-Fi](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-wifi-scan.html): ОС периодически перебирает радиоканалы в поисках соседних сетей Wi-Fi, и на это время связь ненадолго прерывается. - [Энергосбережение NIC и проблемы драйверов](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-driver.html): Если сетевая карта или модуль Wi-Fi уходят в энергосбережение между пакетами, на пробуждение нужно время. - [Другие приложения на устройстве забирают пропускную способность](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-other-apps.html): Если на том же ПК идёт синхронизация с облаком, большая загрузка или скачивание патча игры, игровые пакеты ждут в очереди. - [Ограничение обработки в свёрнутом или неактивном окне](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-unfocused.html): Когда игрок переключается на другое окно или сворачивает игру, и сама игра, и Windows ради экономии энергии замедляют её работу. По возвращении накопившиеся пакеты приходят разом, или соединение уже оборвано. - [Вмешательство оверлеев](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-overlay.html): Мессенджеры, лаунчеры, программы записи и счётчики FPS встраиваются в рендеринг игры (хукинг), чтобы рисовать свой UI поверх игровой картинки. Работы в каждом кадре становится больше, а иногда оверлей конфликтует с игрой, и она дёргается или принудительно закрывается. - [Задержка дисплея, устройств ввода и генерации кадров](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/co-display-input.html): Если пинг в норме, а управление ватное, задержку между вводом и экраном может добавлять обработка изображения в телевизоре, беспроводной контроллер или генерация кадров. ## L3 Домашняя сеть - [Помехи и слабый сигнал Wi-Fi](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/hn-wifi.html): При слабом сигнале или помехах пакеты на беспроводном участке приходится отправлять повторно по нескольку раз, и они приходят неравномерно. - [Перегруженный радиоканал Wi-Fi](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/hn-channel.html): Там, где рядом десятки роутеров (например, в многоквартирном доме), они делят один радиоканал, и каждому приходится ждать своей очереди на передачу. - [Bufferbloat (очередь в роутере)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/hn-bufferbloat.html): Когда кто-то из домашних выкладывает видео или качает большой файл, в очереди роутера скапливаются пакеты на сотни ms, и игровые пакеты ждут за ними. - [Истечение записи в таблице NAT](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/hn-nat.html): Роутер удаляет из таблицы NAT неактивные соединения, по которым какое-то время не было пакетов. Это частая причина дисконнекта в тот момент, когда игрок после простоя снова начинает двигаться. - [Слабый или перегретый роутер](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/hn-router.html): Когда на дешёвый роутер приходятся десятки устройств и тысячи соединений, он сам перестаёт справляться. - [Хендовер между базовыми станциями (в движении)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/hn-handover.html): В автобусе или метро связь прерывается на время смены базовой станции. - [Задержка перехода состояний RRC (энергосбережение радиомодуля)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/hn-rrc.html): Если связи какое-то время нет, телефон переводит радиосоединение в экономичное состояние, а при следующем пакете поднимает его снова, и пакет опаздывает. - [Слабый сигнал мобильной сети и мёртвые зоны](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/hn-weak-cell.html): В лифте, под землёй или в глубине здания растёт число повторных передач, падает скорость, и в итоге дело доходит до дисконнекта. - [Частые переключения 5G ↔ LTE (на границе покрытия 5G)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/hn-5g-flip.html): Внутри зданий со слабым сигналом 5G или на границе покрытия 5G телефон часто переключается между 5G и LTE, и при каждом переключении пинг скачет или связь ненадолго прерывается. - [Ограничения публичного Wi-Fi и корпоративной сети](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/hn-captive.html): Страница входа в Wi-Fi кафе или корпоративный файрвол блокируют подключение к игре. ## L4 Интернет-маршрут - [Задержка распространения (физическое расстояние)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-distance.html): Даже свет в оптоволокне проходит всего около 200 000 km в секунду. Если сервер далеко, задержка будет большой, каким бы хорошим он ни был. - [Спутниковый интернет (низкоорбитальный и геостационарный)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-satellite.html): В спутниковом интернете радиосигнал летит в космос и обратно. Через геостационарный спутник один только путь туда и обратно занимает больше 0,5 с. Низкоорбитальные спутники вроде Starlink обычно быстрые, но в моменты перераспределения маршрута задержка скачет, а связь может ненадолго прерываться. - [Неоптимальная маршрутизация](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-routing.html): Из-за договоров о соединении между провайдерами трафик даже до близкого сервера идёт в обход через далёкие точки. - [Перегрузка пиринга в часы пик](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-peak.html): Примерно с 21:00 до 23:00 резко растёт видеотрафик, и стыки между провайдерами (пиринг) легко перегружаются. - [Аварии на подводных кабелях и международных линиях](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-cable.html): После обрыва подводного кабеля трафик несколько недель (иногда месяцев), пока идёт ремонт, ходит дальними обходными маршрутами, а оставшиеся линии перегружены. - [Смена маршрута BGP и сходимость](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-bgp.html): Когда в интернете меняется маршрутная информация, пакеты теряются, пока маршруты снова не сойдутся: от нескольких секунд до нескольких десятков секунд (изредка несколько минут). - [Неисправность одного из путей ECMP](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-ecmp.html): Провайдеры и ЦОД держат несколько путей к одной цели и для каждого соединения выбирают один из них. Если неисправен только один путь, лаги постоянно бывают только у тех, кому достался этот путь. - [Ограничение скорости и управление трафиком у провайдера](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-shaping.html): Если превышен лимит трафика или тариф предусматривает управление определённым трафиком, пакеты задерживаются или отбрасываются. - [Ограничение UDP и DPI на уровне страны или провайдера](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-udp-block.html): Некоторые сети блокируют отдельные UDP-адреса и порты или ограничивают скорость UDP, а оборудование инспекции пакетов (DPI) отсеивает протоколы, которые не может распознать. Игры, работающие по UDP, в таких сетях не подключаются или часто теряют соединение. - [Плохое качество линии связи](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-line.html): Плохой контакт в разъёмах, старый кабель или неисправный модем дают постоянные потери и периодические обрывы связи. - [Сбои и задержки DNS](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-dns.html): DNS превращает имя сервера в адрес. Если DNS отвечает медленно или с ошибкой, клиент не может найти сервер авторизации и сервер патчей. - [Перегрузка общих линий из-за DDoS](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-ddos-path.html): Массированная атака на игровую компанию или на другого клиента в той же сети забивает общие линии связи. - [Общий IP провайдера (CGNAT)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-cgnat.html): В мобильных сетях и у некоторых провайдеров один IP делят много абонентов, а записи NAT для неактивных соединений быстро удаляются. - [Трафик через VPN или игровой ускоритель](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/isp-vpn.html): С включённым VPN или игровым ускорителем пакеты идут через промежуточные серверы этого сервиса. Если такой сервер далеко или перегружен, соединение становится даже медленнее, чем без него. ## L5 Сетевое оборудование ЦОД - [Переполнение таблицы сессий файрвола](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dc-firewall.html): Файрвол записывает каждое пропущенное соединение в таблицу сессий и отслеживает его. Когда таблица заполнена, новые соединения принять нельзя. - [Задержка и ложные срабатывания защиты от DDoS](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dc-ddos.html): Когда для отражения атаки трафик заворачивают через центр очистки, маршрут удлиняется, а нормальных пользователей защита иногда принимает за атаку и блокирует. - [Таймаут простоя балансировщика](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dc-lb-idle.html): Балансировщик нагрузки удаляет неактивное соединение через определённое время. Игра считает, что соединение живо, и в итоге получает дисконнект. - [Истечение отслеживания соединений в облачной группе безопасности](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dc-cloud-conntrack.html): Файрвол облачного сервера (группа безопасности) тоже отслеживает соединения, и запись о неактивном соединении истекает через заданное время. Поэтому даже на сервере, к которому подключаются напрямую без балансировщика, игрок после бездействия может получить дисконнект. - [Лимиты соединений и портов облачного NAT-шлюза](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dc-nat-gateway.html): Исходящие соединения серверов из частной подсети во внешний мир (авторизация на платформе, платежи, внешние API) проходят через NAT-шлюз, который подменяет адрес и порт. Если одновременных соединений к одной цели больше, чем позволяет лимит портов шлюза, новые соединения не устанавливаются. - [Перекос балансировки и ошибки health check](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dc-lb-imbalance.html): Соединения скапливаются на одном сервере, или балансировщик продолжает отправлять игроков на уже упавший сервер. - [Микробёрсты на коммутаторе](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dc-microburst.html): Когда несколько серверов в один и тот же момент разом отправляют пакеты тысячам игроков, маленький буфер порта коммутатора, где сходится этот трафик, переполняется меньше чем за 1 ms. - [Перегрузка линии связи ЦОД](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dc-uplink.html): Если раздача патчей, отправка логов и бэкапы идут по той же линии, что и игра, линия забивается. - [Переключение сетевого оборудования на резерв (failover)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dc-failover.html): Когда маршрутизатор или файрвол выходит из строя и трафик переключается на резервное устройство (failover), на эти несколько секунд у всех фриз. - [Неисправный кабель и ошибки порта](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dc-bad-cable.html): Если оптический модуль или кабель неисправен, определённая доля пакетов на этом пути повреждается. - [Несовпадение MTU (пропадают только большие пакеты)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dc-mtu.html): Если на промежуточном участке MTU (максимальный размер пакета за одну передачу) меньше, а уведомления о превышении размера блокируются, постоянно пропадают только большие пакеты. ## L6 Сетевая карта сервера - [Все прерывания NIC на одном ядре](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/nic-irq.html): Если NIC отправляет прерывания о приходе пакетов только на одно ядро CPU, это ядро становится узким местом. - [Слишком маленький кольцевой буфер](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/nic-ring.html): Если кольцевой буфер, где NIC ненадолго держит пакеты, маленький, при резком наплыве пакетов он переполняется, и пакеты отбрасываются. - [Избыточное объединение прерываний](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/nic-coalesce.html): Если ради разгрузки CPU NIC копит пакеты и сообщает о них разом, пакеты задерживаются на время накопления. - [Превышен лимит PPS в облаке](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/nic-cloud-pps.html): У каждого типа облачного сервера есть лимиты пакетов в секунду и пропускной способности, и всё сверх лимита молча отбрасывается. - [Исчерпание пропускной способности NIC](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/nic-saturate.html): Если карта на 1 Gbps или 10 Gbps загружена до предела, очередь отправки растёт, и в итоге пакеты отбрасываются. - [Накладные расходы виртуализации и шумные соседи](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/nic-noisy.html): Если другие виртуальные машины на том же физическом сервере активно используют сеть и CPU, обработка на нашем сервере нерегулярно запаздывает. - [Обслуживание облачного хоста и живая миграция](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/nic-host-maintenance.html): Во время обслуживания физического сервера (хоста) облачный провайдер переносит виртуальную машину на другой хост (живая миграция) или ненадолго её приостанавливает. На это время замирает весь сервер, а если пауза долгая, соединения рвутся. - [Проблемы драйвера и прошивки NIC](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/nic-reset.html): Из-за ошибки драйвера или сбоя какой-то функции карта зависает и перезапускается, и на это время весь приём и отправка прекращаются. - [Ожидание объединения пакетов в GRO/LRO](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/nic-offload.html): GRO и LRO объединяют несколько пакетов в один, чтобы снизить нагрузку на CPU. При некоторых настройках маленький игровой пакет ненадолго ждёт следующий, чтобы объединиться с ним. ## L7 ОС сервера (ядро) - [Переполнение очереди подключений (backlog)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-backlog.html): Когда сразу после техработ одновременно подключаются десятки тысяч игроков, очередь подключений ядра (backlog) переполняется и попытки подключения отбрасываются. - [Лимит файловых дескрипторов](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-fd.html): Каждому соединению нужен файловый дескриптор (fd, номер, который ОС присваивает открытому файлу или сокету), а число fd, которые может открыть один процесс, ограничено. - [Нехватка буферов сокетов в ядре](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-sockbuf.html): Если буферы приёма и отправки маленькие, то при всплеске трафика принятые по UDP пакеты отбрасываются, а отправка по TCP встаёт, потому что в буфере нет места. - [Избыток потоков и переключение контекста](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-context.html): Если потоков намного больше, чем ядер, заметная часть CPU уходит только на то, чтобы ОС запускала их по очереди. - [CPU steal (виртуальная машина)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-steal.html): Пока физический сервер (гипервизор) временно отдаёт процессорное время виртуальной машины другим виртуальным машинам (CPU steal), игровой сервер стоит. - [Троттлинг CPU в контейнере (квота CFS)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-cpu-quota.html): Если у контейнера задан лимит CPU, то, израсходовав квоту в пределах периода (обычно 100 ms), он принудительно останавливается до конца периода (троттлинг). - [Всплески задержки из-за управления питанием сервера (C-state, управление частотой)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-cstate.html): Простаивающее ядро CPU ради экономии энергии переходит в глубокое состояние сна (C-state) и снижает частоту. Когда приходит пакет или срабатывает таймер, на пробуждение и подъём частоты уходит время, и к обработке даже маленьких пакетов добавляется задержка. - [OOM killer](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-oom.html): Когда память заканчивается, Linux выбирает процесс, который занимает больше всего памяти, и принудительно его завершает. Обычно это игровой сервер. - [Остановки из-за освобождения и уплотнения памяти](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-reclaim.html): Процесс останавливается, пока ОС уплотняет память (compaction), чтобы собрать большие страницы (huge pages), или освобождает память, чтобы пополнить запас свободной (reclaim). - [Скачок системных часов (шаговая коррекция NTP)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-timejump.html): Если часы сервера разом переводятся на несколько секунд вперёд или назад, таймеры, завязанные на системные часы, срабатывают пачкой или замирают. - [Плановые задания](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-cron.html): Сжатие логов, бэкапы и проверки безопасности, которые запускаются каждый день в одно и то же время, занимают CPU и диск. - [Изменение производительности после обновления ОС, ядра, драйверов или прошивки](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-os-update.html): Игровой код не менялся, но после обновления ОС, ядра, драйверов или прошивки сервер стал работать медленнее. Обновление может поменять значения по умолчанию, планировщик, защиту от уязвимостей CPU (mitigations) и поведение драйверов. - [Переполнение таблицы conntrack на сервере](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-conntrack.html): Когда таблица отслеживания соединений (conntrack), в которую файрвол Linux записывает все соединения, достигает лимита, новые пакеты отбрасываются. - [Исчерпание эфемерных портов в межсерверных соединениях](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/so-ports.html): Если игровой сервер часто открывает и закрывает короткие соединения с БД или другими серверами, закрытые соединения ещё какое-то время занимают порты, и новые соединения открыть не удаётся. ## L8 Сокеты и протоколы - [HOL-блокировка в TCP](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-hol.html): Чтобы сохранить порядок, TCP не передаёт игре пакеты, пришедшие позже, пока заново не получит один потерянный пакет. - [TCP RTO и экспоненциальный backoff](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-rto.html): С каждой новой неудачной повторной передачей ожидание удваивается, и короткий обрыв связи превращается в долгую остановку. - [Алгоритм Нейгла + отложенный ACK](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-nagle.html): Алгоритм Нейгла, который копит мелкие пакеты перед отправкой, и отложенный ACK, который придерживает подтверждения, мешают друг другу, и каждое сообщение, записанное по частям, задерживается на 40–200 ms. - [Блокирующая отправка из-за медленного клиента](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-block-send.html): Если у одного игрока с медленным подключением заполнился буфер отправки, а сервер отправляет данные блокирующим способом (вызов не возвращается, пока в буфере не освободится место), поток сервера ждёт этого одного игрока. - [Политика для медленных клиентов (slow consumer)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-slow-client.html): Если для клиента постоянно копятся неотправленные данные, сервер выбрасывает устаревшие обновления или разрывает соединение. - [Keepalive по умолчанию: 2 часа](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-keepalive.html): Если другая сторона пропадает без сигнала о закрытии, TCP замечает это очень нескоро. Keepalive (механизм TCP, который проверяет, живо ли неактивное соединение) по умолчанию выключен, а если его включить, проверка начинается только после 2 часов простоя. - [IP-фрагментация UDP-пакетов](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-fragment.html): UDP-пакет больше MTU (размера, который можно отправить за один раз) фрагментируется на уровне IP, и при потере всего одного фрагмента выбрасывается весь пакет. - [Настройка повторных передач в надёжном UDP](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-reliable-udp.html): Если собственные правила повторной передачи поверх UDP слишком осторожные, потери восстанавливаются поздно, а если слишком агрессивные, они ещё сильнее забивают линию. - [Медленный старт после простоя](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-slowstart.html): Если соединение какое-то время простаивало, TCP снова уменьшает окно перегрузки (объём, который можно отправить за раз), и внезапно понадобившийся большой объём данных уходит в несколько заходов. - [Резкий спад передачи из-за управления перегрузкой](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-congestion.html): TCP считает потери признаком перегрузки и снижает скорость передачи на 30–50%. Точно так же он реагирует и на потери в Wi-Fi. - [Потеря последних данных при принудительном закрытии через RST](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-linger.html): Если сервер резко рвёт соединение, последнее отправленное сообщение или подтверждение сохранения пропадает. - [Архитектура с блокирующим вводом-выводом](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-blocking-io.html): Если поток, ожидая один сокет, не может делать ничего другого, то с ростом числа игроков тормозит всё. - [Перекос распределения в SO_REUSEPORT](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-reuseport.html): Когда несколько процессов принимают трафик на одном порту, ядро закрепляет каждое подключение за процессом по хешу адреса и больше его не меняет. Если один процесс зависает, ждут только игроки, закреплённые за ним. - [Ошибка WSAECONNRESET на UDP-сокете в Windows](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sk-udp-connreset.html): Когда сервер на Windows отправляет UDP уже ушедшему клиенту, обратно приходит уведомление «порт недоступен» (ICMP). Из-за него следующий вызов приёма завершается ошибкой, и если код сервера считает её поломкой самого сокета, страдают все, кто работает через этот сокет. ## L9 Процесс игрового сервера - [Превышение бюджета тика](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-tick-overrun.html): Если работа одного тика не укладывается в бюджет, интервал тиков сервера растягивается, и вся локация идёт замедленно или с микрофризами. - [Взрывной рост расчёта видимости (AOI, N²)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-aoi.html): Если выяснять, кто кого видит, сравнивая всех со всеми, то при росте числа игроков в 10 раз расчёты растут в 100 раз. - [Взрывной рост рассылки (broadcast)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-broadcast.html): Если движение каждого игрока отправлять всем, кто его видит, число обновлений растёт как квадрат числа собравшихся. - [Перегрузка однопоточной локации (хотспот)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-hotzone.html): Если каждую локацию обслуживает один поток, то при скоплении игроков в одном месте на 100% загружается только одно ядро. - [Конкуренция за блокировки](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-lock.html): Если несколько потоков ждут одну блокировку, чтобы работать с одними и теми же данными, то сколько потоков ни добавляй, выполняется только один за раз. - [Дедлок](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-deadlock.html): Если два потока ждут блокировки, захваченные друг другом, они встают навсегда. - [Синхронные вызовы в игровом потоке](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-sync-call.html): Если посреди тика ждать ответа БД или записи в файл, на это время останавливается вся игра на сервере. - [Затор в очереди сообщений](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-queue.html): Если запросы поступают быстрее, чем обрабатываются, и копятся в очереди, запросы в её хвосте обрабатываются лишь через несколько секунд или выбрасываются. - [Одновременное срабатывание таймеров](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-timer-burst.html): Если респавн всех монстров, окончание всех баффов и награды ровно в начале часа приходятся на один тик, этот тик становится в десятки раз тяжелее. - [Лавина поиска пути](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-pathfinding.html): Когда сотни монстров одновременно гонятся за игроками и рассчитывают путь, это сильно нагружает CPU. - [Затраты на сериализацию и сжатие](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-serialize.html): Превращение данных для отправки в байты и их сжатие тоже требуют CPU, и при большом числе игроков эти затраты резко растут. - [Падение сервера](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-crash.html): Если процесс сервера падает из-за необработанной ошибки, у всех, кто был на этом сервере, одновременно обрывается соединение. - [Исчерпание пула потоков](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-threadpool.html): Если все рабочие потоки заняты медленными задачами, новые запросы ждут неопределённо долго. - [Бесконечный цикл и неконтролируемая логика](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-infinite-loop.html): Если из-за бага тик не заканчивается, сервер встаёт, и watchdog принудительно его перезапускает. - [Бой, сосредоточенный на одной цели (мировой босс)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-hot-entity.html): Когда сотни игроков одновременно бьют одного босса, все расчёты по этому боссу сходятся в одной точке, а информация о каждом ударе рассылается всем, кто его видит. - [Лавина спавна при входе в людное место](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-spawn-burst.html): Когда игрок телепортируется в город, полный людей, сервер должен разом отправить внешность, экипировку и состояние сотен персонажей, которые стали видны. - [Накопление объектов (неубранные предметы и призванные существа)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-entity-buildup.html): Если предметы на земле, призванные существа и отработавшие таймеры, которые должны исчезать, не удаляются и копятся, то чем дольше сервер работает, тем больше работы в каждом тике. - [Патч изменил характер трафика](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sp-patch-traffic.html): Если новый контент, эффекты и синхронизируемые поля увеличивают размер и частоту пакетов, сервер, который работал нормально, после патча упирается в MTU, пропускную способность или лимиты по числу пакетов. ## L10 Память - [Полная пауза GC на сервере](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/mem-gc.html): Сервер на Java или C# останавливает все потоки на время сборки мусора (stop-the-world), и на это время замирает весь сервер. - [Паузы GC в скриптовом движке](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/mem-script-gc.html): Если на сервере, пусть даже написанном на C++, квесты, AI и умения выполняются скриптами (например, на Lua), то на время работы GC скриптового движка эта зона останавливается. - [Лавина аллокаций](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/mem-alloc.html): Если во время события создаётся масса временных объектов, GC запускается намного чаще обычного. - [Утечка памяти](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/mem-leak.html): Неосвобождённая память понемногу накапливается, и через несколько дней это заканчивается трешингом GC, свопом или принудительным завершением процесса. - [Трешинг GC (мало свободного места в куче)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/mem-gc-thrash.html): Когда живые данные приближаются к пределу кучи, GC почти нечего освобождать, и сборки идут одна за другой без перерыва. - [Своп](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/mem-swap.html): Когда памяти не хватает и ОС выгружает её часть на диск, при каждом обращении к этой памяти приходится ждать диск, который медленнее больше чем в 1 000 раз. - [Промах кэша](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/mem-cache-miss.html): Если данные разбросаны по памяти, CPU каждый раз ждёт медленную RAM. - [Фрагментация памяти](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/mem-fragment.html): Когда из-за постоянных выделений и освобождений свободное место дробится на мелкие куски, процесс занимает намного больше памяти, чем реально использует. - [Удалённая память NUMA](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/mem-numa.html): На сервере с двумя процессорами обращение к памяти, подключённой к другому процессору, идёт медленнее. ## L11 Диск - [Синхронная запись логов](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dk-sync-log.html): Если игровой поток на каждой строке лога ждёт, пока диск завершит запись, то при занятом диске останавливается и игра. - [Лавина fsync](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dk-fsync.html): Запрос записать данные на диск «гарантированно» занимает от 0,1 ms до десятков ms в зависимости от диска, а когда таких запросов много, очередь растёт. - [Исчерпание burst-кредитов облачного диска](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dk-burst.html): У некоторых облачных дисков и небольших конфигураций серверов есть burst-кредиты, которые позволяют какое-то время работать быстрее базовой производительности. Если высокая нагрузка держится долго и кредиты кончаются, скорость резко падает. - [Лимит IOPS и насыщение очереди](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dk-iops.html): Если запросов больше, чем диск может обработать за секунду, очередь растёт и задержка резко увеличивается. - [Диск заполнен](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dk-full.html): Когда логи и дампы заполняют диск, запись завершается ошибкой, и если к этому не подготовиться, сервер падает. - [Бэкап, сжатие и сканирование](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dk-backup.html): Когда ночной бэкап, сжатие логов или проверка безопасности занимают диск целиком, чтение и запись игрового сервера застревают. - [Ленивая загрузка на сервере](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dk-lazy-load.html): Если сервер читает данные данжа или карты с диска в момент первого запроса, на этот тик останавливаются все. - [Запись core dump](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dk-coredump.html): При падении сервер пишет на диск несколько GB памяти, и перезапуск может задерживаться на несколько минут. - [Задержка позиционирования HDD](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/dk-hdd.html): У HDD головка должна перемещаться над пластинами (позиционирование, seek), поэтому каждое чтение или запись разбросанных данных занимает почти 10 ms. ## L12 База данных - [Запрос без индекса](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-no-index.html): Без индекса, чтобы найти строки по условию, приходится читать всю таблицу (полное сканирование). - [Конкуренция за блокировку горячей строки](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-hot-row.html): Когда все пытаются изменить одну и ту же строку (гильдейский склад, популярный лот на аукционе, общий счётчик сервера), блокировку получает только один запрос за раз. - [Дедлок в БД](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-deadlock.html): Если две транзакции (операции БД, которые выполняются как единое целое) ждут строки, заблокированные друг другом, БД принудительно отменяет одну из них. - [Исчерпание пула соединений](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-pool.html): Число соединений с БД фиксировано, поэтому, когда медленные запросы занимают соединения, остальные запросы ждут. - [Отставание репликации](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-replica-lag.html): Если запись идёт в основную БД, а чтение с реплики, то при отставании реплики только что записанные данные не видны. - [Контрольные точки и сброс журнала](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-checkpoint.html): В моменты, когда БД периодически сбрасывает накопленные в памяти изменения на диск, запросы замедляются. - [Холодный кэш (сразу после перезапуска)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-cold-cache.html): После перезапуска БД кэш в памяти пуст, и какое-то время все запросы читают данные с диска. - [Наплыв входов и запросы N+1](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-login-storm.html): Если для загрузки одного персонажа нужны десятки отдельных запросов, одновременный вход десятков тысяч игроков превращается в миллионы запросов. - [Тяжёлые пакетные задания](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-batch.html): Если подсчёт рейтингов, массовую рассылку почты или чистку старых данных запускать во время работы сервиса, они занимают блокировки и диск. - [Переключение БД на резерв](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-failover.html): Пока после отказа основной БД идёт переключение на резервную, запись невозможна, а последние данные, которые не успели реплицироваться, могут пропасть. - [Потеря прогресса из-за редких сохранений](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-save-interval.html): Если ради снижения нагрузки сохранять прогресс раз в несколько минут, то при падении сервера в промежутке прогресс пропадает. - [Cache stampede](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-cache-stampede.html): Когда кэш популярных данных истекает одновременно, тысячи запросов разом идут в БД. - [Долго открытая транзакция](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-long-tx.html): Если одна транзакция долго остаётся открытой, она продолжает держать блокировки, а БД не может очистить (purge) старые версии данных, и всё постепенно замедляется. - [Медленные команды Redis](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-redis-block.html): Redis обрабатывает команды по одной, поэтому одна медленная команда блокирует все запросы за ней. - [Замедление запроса из-за смены плана выполнения](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-plan-flip.html): Код не менялся, но если БД меняет способ выполнения того же запроса (план выполнения), вчерашний запрос на 2 ms сегодня занимает сотни ms. - [Блокировка при изменении схемы (DDL) на работающем сервисе](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/db-ddl-lock.html): Если во время работы сервиса добавить в таблицу столбец или индекс, из-за одной кратковременной блокировки могут встать все запросы к этой таблице. ## L13 Архитектура и эксплуатация серверов - [Трафик через шлюз или прокси](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-gateway.html): Если поставить между клиентом и игровым сервером промежуточный сервер, каждый проход через него добавляет время обработки, а сам он становится единой точкой отказа. - [Переход между зонами (передача на другой сервер)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-zone-transfer.html): При входе в другую локацию или данж данные персонажа передаются на другой сервер, и на этом этапе возникают задержки и сбои. - [Каскадный отказ](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-cascade.html): Когда один сервис тормозит, вызывающие его серверы зависают в ожидании ответа, и останавливаются даже функции, которые с ним не связаны. - [Сбой вспомогательного сервера](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-subservice.html): Если отказывает сервер, который работает отдельно от игрового (чат, группы, аукцион), перестаёт работать только эта функция. - [Деплой и перезапуск](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-deploy.html): Если при перезапуске сервера ради обновления не перенести соединения, у всех игроков на этом сервере будет дисконнект, а сохранения перед остановкой и переподключения придут разом. - [Задержка автомасштабирования](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-autoscale.html): При наплыве игроков серверы добавляются автоматически, но подготовка занимает несколько минут, и всё это время существующие серверы перегружены. - [Перегрузка логирования и мониторинга](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-monitoring.html): При сбое логи растут лавиной, и серверы, которые отправляют логи синхронно, из-за этого тормозят ещё сильнее. - [Расхождение часов между серверами](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-clock-skew.html): Если часы на серверах немного расходятся, проверки кулдаунов, баффов и начала событий на разных серверах дают разный результат. - [Избыток макросов и ботов](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-bots.html): Боты шлют запросы гораздо чаще людей и съедают производительность сервера. - [Зависимость от внешних сервисов](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-external.html): Если тормозит или останавливается внешний сервис (вход через платформу, оплата, подтверждение личности), всё застревает на этом этапе. - [Ошибки матчмейкинга и выбора региона](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-region-match.html): Если игрока отправили на сервер в дальнем регионе вместо ближнего, у него одного пинг всегда высокий, даже если с подключением всё в порядке. - [Истёкший или неверно настроенный TLS-сертификат](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-cert.html): Если у сервера авторизации, API или патчей истекает сертификат или пропадает промежуточный сертификат, с этого момента у новых подключений клиентов не устанавливается TLS-соединение. - [Лимит очереди на вход и короткое окно переподключения](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/in-login-queue.html): Когда сразу после релиза или техработ идёт наплыв подключений, очередь на вход упирается в лимит и перестаёт принимать новых игроков, а тот, кто уже ждал, при коротком обрыве теряет место и снова оказывается в конце очереди. ## Архитектура синхронизации - [Отклик только после ответа сервера (модель запрос-ответ)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-request-response.html): После нажатия кнопки нет ни анимации, ни звука, пока не придёт ответ сервера. Скорость отклика становится равна пингу. - [Протокол с множеством последовательных обменов (chatty)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-chatty.html): Если для одного действия нужно несколько обменов с сервером по очереди, пинг умножается на их число. - [Нет буферизации ввода умений](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-no-queue.html): Если следующее умение можно нажать только после подтверждения сервера, что предыдущее закончилось, в каждую связку вклинивается путь туда и обратно. - [Короткое окно реакции, которое съедает пинг](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-short-window.html): Если на реакцию (уклонение, парирование, блок) отведено мало времени, пинг съедает это время, и появляются атаки, от которых невозможно уйти. - [Проверка попадания без компенсации задержки](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-no-lagcomp.html): Если сервер проверяет попадание только по «текущей позиции на сервере», результат расходится с тем, что игрок видел на своём экране. - [Чрезмерная компенсация задержки](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-lagcomp-overreach.html): Если отматывать время слишком далеко в пользу атакующего, в того, кто уже спрятался, всё равно попадают. - [Клиентский авторитет](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-client-auth.html): Если каждый клиент сам определяет свои результаты, на экране игрока всё плавно, но результаты расходятся с экранами других, и игра уязвима для читов. - [Ожидание самого медленного игрока в lockstep](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-lockstep.html): В схеме, где все вместе рассчитывают один и тот же ход, при опоздании ввода одного игрока ждут все. - [Ошибки предсказания в роллбэк-неткоде](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-rollback.html): Игра предсказывает ввод соперника и показывает результат заранее, а при ошибке отматывает назад и пересчитывает. Чем больше пинг, тем глубже отмотка. - [Воспроизведение сразу по приходу без меток времени](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-no-timestamp.html): Если сервер не прикрепляет к событиям время, когда они произошли, а клиент проигрывает их сразу при получении, сетевой джиттер напрямую сбивает тайминг анимаций. - [Двойное ожидание тика](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-double-tick.html): Если запросы копятся до следующего тика и только тогда обрабатываются, а результат уходит ещё через тик, интервал тика добавляется дважды. - [Слишком строгая серверная проверка](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-strict-check.html): Если сервер слишком строго проверяет скорость перемещения, кулдауны и дальность, он отклоняет даже нормальный ввод, пришедший пачкой из-за джиттера. - [Архитектура с хостом-игроком](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-host.html): Если сервером служит ПК одного из игроков, его подключение и производительность ПК определяют ощущения всех. - [Отказ сервера после опережающего фидбека](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-optimistic-reject.html): Если сервер потом не засчитывает удар или умение, которые экран игрока уже показал, результат, который игрок точно видел, отменяется. - [Расхождение расчёта пути при синхронизации команд](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-path-mismatch.html): Если стороны обмениваются только командой «иди сюда», а путь каждая сторона рассчитывает сама, то даже при небольшом расхождении персонаж или монстр идёт другим путём, а потом его утягивает на правильное место. - [Низкая частота отправки снапшотов](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/sy-low-send-rate.html): Если сервер отправляет обновления позиций (снапшоты) всего несколько раз в секунду, буфер интерполяции приходится делать соответственно длинным, и другие персонажи видны в более далёком прошлом. ## Проблемы только у части игроков - [Игрок с плохой связью движется на чужих экранах рывками](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-slow-burst.html): Ввод игрока с плохим подключением приходит на сервер неравномерно, пачками. Если сервер в каждом тике применяет всё, что успело прийти, другие видят, как этот персонаж замирает, а потом делает сразу несколько шагов. - [Перемотка на сервере, который обрабатывает ввод сразу по приходу](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-event-server.html): На сервере, который обрабатывает и рассылает пакеты сразу по приходу, действия тормозящего игрока, пришедшие пачкой, выполняются подряд и немедленно. - [Размер буфера ввода на игрока](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-input-buffer.html): Если сервер немного накапливает ввод каждого игрока и берёт по одной команде за тик, на чужих экранах движение плавное, но момент, когда действие самого игрока подтверждается сервером, сдвигается на столько же. - [Ложные срабатывания проверок у абонентов одного провайдера](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-isp-validation.html): У игроков на подключениях с большим джиттером ввод приходит пачками и часто попадает под серверную проверку скорости и кулдаунов. - [Один тормозящий участник группы и механики босса](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-raid-member.html): В рейдовых механиках, где все должны отреагировать в один и тот же момент, запоздалая реакция одного тормозящего игрока проваливает всю группу. - [Управление монстром у тормозящего клиента](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-mob-control.html): В некоторых играх, чтобы снизить нагрузку на сервер, расчёт перемещения монстров поручают клиенту одного из ближайших игроков. Если у этого игрока плохое подключение, монстр странно движется на экранах у всех. - [Раздутые данные отдельного персонажа](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-heavy-char.html): У персонажа, у которого накопились тысячи предметов и писем или необычно много друзей, записей в чёрном списке и баффов, данных для загрузки при входе, сохранения и рассылки окружающим в разы больше, чем у других. Тормозит только этот персонаж, независимо от подключения. - [Разные каналы, инстансы и фазы](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-phase.html): Если два персонажа находятся в разных каналах или инстансах или в разных «фазах», где набор видимых NPC зависит от прогресса квеста, они видят разные миры. - [Отбрасывание уведомлений о появлении во время загрузки](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-loading-drop.html): Сразу после входа в зону сервер отправляет уведомления о появлении NPC вокруг, а клиент ещё загружает карту и отбрасывает эти уведомления. - [Сбой порядка регистрации в зоне видимости](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-aoi-race.html): Если момент регистрации персонажа в сетке видимости совпадает с моментом, когда NPC переходит в другую ячейку, уведомление о появлении этого NPC может потеряться. - [Потеря опорного снапшота](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-baseline.html): Если сервер отправляет «только то, что изменилось с прошлого раза», то при потере первой полной посылки (опорного снапшота) последующие изменения применить невозможно. - [Потеря уведомления об исчезновении (фантомные объекты)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-ghost.html): И наоборот, если пропущено уведомление «исчез», уже убитые или ушедшие NPC и игроки остаются только на экране этого игрока. - [Потеря данных о появлении из-за наплыва сразу после входа](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-spawn-burst.html): В момент входа в зону сервер разом отправляет данные о появлении десятков и сотен окружающих объектов. Если отправлять их по ненадёжному каналу доставки (unreliable) или если буфер приёма переполнится, пока клиент занят загрузкой и не читает сокет, часть данных пропадает и повторно не приходит. - [Путаница из-за повторного использования ID объектов](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-id-reuse.html): Если при возрождении убитого NPC сервер снова использует тот же ID объекта, клиент, пропустивший за это время уведомление об исчезновении, принимает новый NPC за старый. - [Конфликт фиксированного UDP-порта](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-port-collision.html): Если клиент рассчитан на конкретный локальный порт, второй клиент на том же ПК не может занять порт или делит пакеты с первым. - [Ошибка разделения сессий по IP или устройству](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-session-key.html): Если сервер или промежуточный сервер различает соединения по IP или ID устройства, два клиента на одном ПК (с одним публичным IP) считаются одним игроком. - [Ограничение на несколько клиентов](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-multiclient.html): Если модуль защиты или политика сервера ограничивает число клиентов на одном ПК, второй клиент не запускается или не подключается, либо у первого случается дисконнект. Некоторые игры блокируют только функции дополнительного клиента. - [Ограничение обработки в фоновом окне](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-background.html): Для клиента в фоновом окне игра, движок и ОС снижают частоту кадров и объём обработки. Полученные пакеты не успевают обрабатываться, копятся и переполняют буфер. - [Конфликт одновременного доступа к файлам кэша и ассетов](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-asset-lock.html): Если два клиента одновременно пишут в одну папку кэша или блокируют файлы, один из них не может загрузить модели и текстуры NPC. - [Сбой стриминга из-за нехватки памяти или VRAM](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-vram.html): Когда два клиента делят видеопамять, для новых моделей и текстур не остаётся места, и часть объектов не рисуется. - [Разные настройки отображения](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-display-option.html): Если у двух клиентов различаются настройки вроде лимита отображаемых персонажей, скрытия табличек с именами и моделей NPC или режима для слабых ПК, они показывают разное. - [Несовпадение версии клиента или данных](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-version.html): Если второй клиент установлен отдельно или не до конца пропатчен, он не знает новых ID NPC от сервера и молча их игнорирует. - [Бюджет отправки и приоритеты для каждого соединения](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-priority.html): Если сервер ограничивает объём отправки для каждого соединения и отправляет сначала ближние объекты, соединение с низким лимитом получает дальних NPC поздно или не получает вовсе. - [Отложенный показ объектов из-за ошибки оценки серверного времени](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/pt-clock-hold.html): Если клиент неверно оценивает серверное время, только что пришедшие данные объекта он откладывает как «ещё из будущего» или отбрасывает как «слишком старые». ## Первопричины повторных передач TCP - [Потери на беспроводном участке](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-wireless.html): Wi-Fi и мобильная сеть несколько раз повторяют передачу на беспроводном участке, а если и это не помогает, выбрасывают пакет. Выброшенный пакет TCP отправит повторно только спустя заметное время. - [Переполнение очереди в узком месте (потери от перегрузки)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-queue-drop.html): Когда заполняется очередь в самом узком месте (в роутере, на стыке провайдеров, на линии связи ЦОД), новые пакеты выбрасываются. - [Переполнение неглубоких буферов всплесками отправки](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-burst.html): Когда сервер каждый тик разом выплёскивает обновления для тысяч игроков, маленький буфер коммутатора или мгновенный лимит облака переполняется меньше чем за 1 ms, и часть пакетов выбрасывается. - [Отбрасывание избытка полисером](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-policer.html): Тарифы провайдеров, лимиты облачных инстансов и оборудование защиты от DDoS могут сразу отбрасывать пакеты сверх заданной скорости, не ставя их в очередь. - [Физические ошибки (неисправные кабели, оптические модули и разъёмы)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-physical.html): Повреждённый кабель, запылённый оптический разъём или выработавший ресурс оптический модуль дают битовые ошибки, и оборудование молча выбрасывает испорченные пакеты. - [Несовпадение дуплекса](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-duplex.html): Если на одной стороне включено автосогласование, а на другой скорость и дуплекс заданы жёстко, одна сторона работает в полудуплексе и под нагрузкой каждый раз теряет пакеты из-за коллизий. - [Отбрасывание пакетов на принимающем сервере](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-host-drop.html): Пакеты дошли до сервера, но выбрасываются: переполнен кольцевой буфер NIC (буфер, где ненадолго лежат пришедшие пакеты) или загружено до предела процессорное ядро, на котором ОС обрабатывает приём. - [Отбрасывание пакетов файрволом или conntrack](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-stateful-fw.html): Файрвол или conntrack в Linux (функция, которая записывает проходящие соединения в таблицу) выбрасывает пакеты, если таблица заполнена или состояние соединения кажется ему неверным. - [Перегрузка промежуточного оборудования (файрвол, IPS, защита от DDoS)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-appliance-pps.html): Файрволы, системы предотвращения вторжений (IPS) и оборудование защиты от DDoS проверяют каждый проходящий пакет. Как только поток превышает их возможности, необработанные пакеты выбрасываются. - [Чёрная дыра MTU (большие пакеты теряются раз за разом)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-mtu.html): Если на промежуточном участке допустимый размер пакета уменьшился, а уведомление «слишком большой» (ICMP) блокируется, большие пакеты пропадают, сколько бы раз их ни отправляли повторно. - [Истечение записи NAT или балансировщика посреди соединения](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-mapping.html): Если промежуточное оборудование удаляет запись неактивного соединения (запись о том, куда пересылать это соединение), следующий отправленный пакет не доходит. Повторные передачи идут, пока соединение не оборвётся, или оборудование возвращает отказ в соединении (RST), и связь рвётся сразу. - [Смена маршрута и неисправный путь ECMP](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-path.html): Пакеты пропадают в течение нескольких секунд, пока меняется интернет-маршрут, или постоянно на соединениях, попавших на неисправный путь среди нескольких путей ECMP. - [Ложные повторные передачи из-за скачков задержки](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-spurious-delay.html): Пакет цел и лишь ненадолго сильно задерживается. Если эта задержка дольше RTO, отправитель считает пакет потерянным и передаёт его повторно. - [Ложные быстрые повторные передачи из-за нарушения порядка](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-reorder.html): Если на нескольких путях или агрегированных линках порядок пакетов меняется, получатель дублирующими ACK сообщает «пакета не хватает», и отправитель повторно отправляет пакеты, которые не терялись. - [Задержка и потеря ACK (забитая отдача)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-ack-path.html): Данные дошли нормально, но если ACK «получено» задерживается или теряется в забитой очереди отдачи, отправитель считает данные потерянными и передаёт их повторно. - [Неподходящая настройка RTO](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-rto-setting.html): Если слишком занизить минимальный RTO, от малейшей задержки возникают ложные повторные передачи, а значение по умолчанию (200 ms) для игры слишком велико, и каждая потеря даёт долгий фриз. - [Медленное восстановление потерь в thin stream](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-thin.html): Когда мелкие пакеты отправляются редко, как в играх, RTO наступает раньше, чем соберутся «3 следующих пакета». От тех же потерь поток стоит намного дольше, чем при больших передачах. - [Удаление опций TCP промежуточным оборудованием](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-sack-stripped.html): Если некоторые файрволы или ускорители удаляют или меняют опции TCP, то при потере нескольких пакетов они восстанавливаются по одному за RTT или окно (сколько можно отправить за раз) становится маленьким, и передача замедляется. - [Нулевое окно (остановка, похожая на повторную передачу)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-zero-window.html): Если программа-получатель не успевает вовремя читать сокет и буфер заполняется, отправитель останавливает передачу и шлёт только пробы нулевого окна. С линией связи это не связано. - [Повторная передача запроса на подключение (SYN)](https://jungrok5.github.io/mmo-lag-anatomy/ru/c/rt-syn.html): Если запрос на подключение теряется из-за переполнения очереди подключений (backlog) или блокировки файрволом, ОС клиента отправляет его повторно через 1 с, а затем с растущими интервалами. ## Диагностика и инциденты - [Диагностика по метрикам](https://jungrok5.github.io/mmo-lag-anatomy/ru/#judge): Порядок диагностики «охват → момент → слой», таблица признаков, 13 форм графиков, как читать цифры (среднее и p99) - [Инструкции по ситуациям](https://jungrok5.github.io/mmo-lag-anatomy/ru/text.html#playbooks): Лаги после патча, запуск в новой стране или регионе - [Реальные инциденты](https://jungrok5.github.io/mmo-lag-anatomy/ru/text.html#cases): Постмортемы, опубликованные самими разработчиками и операторами сервисов, и связанные с ними причины ## Другие языки - [한국어 (Korean)](https://jungrok5.github.io/mmo-lag-anatomy/llms.txt) - [English](https://jungrok5.github.io/mmo-lag-anatomy/en/llms.txt) - [日本語 (Japanese)](https://jungrok5.github.io/mmo-lag-anatomy/ja/llms.txt) - [简体中文 (Chinese (Simplified))](https://jungrok5.github.io/mmo-lag-anatomy/zh-cn/llms.txt) - [繁體中文 (Chinese (Traditional, Taiwan))](https://jungrok5.github.io/mmo-lag-anatomy/zh-tw/llms.txt) - [Deutsch (German)](https://jungrok5.github.io/mmo-lag-anatomy/de/llms.txt) - [ไทย (Thai)](https://jungrok5.github.io/mmo-lag-anatomy/th/llms.txt) - [Tiếng Việt (Vietnamese)](https://jungrok5.github.io/mmo-lag-anatomy/vi/llms.txt) - [Português (Brasil) (Portuguese (Brazil))](https://jungrok5.github.io/mmo-lag-anatomy/pt-br/llms.txt) - [Español (Spanish)](https://jungrok5.github.io/mmo-lag-anatomy/es/llms.txt) - [Bahasa Indonesia (Indonesian)](https://jungrok5.github.io/mmo-lag-anatomy/id/llms.txt) ## Optional - [Репозиторий на GitHub](https://github.com/jungrok5/mmo-lag-anatomy): Исходный код, формат данных, как внести вклад - [Автор: Jeongrok Oh](https://jungrok5.github.io/resume/en/): Резюме