04-12-2015, 10:31 AM
В один прекрасный день (не такой уж и прекрасный, так как до этого было несколько дней безудержного веселья, но это уже другая история), мне написал заказчик, мол, так и так, на замесах игроки ужасно лагают, есть очень сильное падение ФПС и вообще, все плохо, когда 5 кланов сталкиваются вместе.
Ну бывало и хуже, поэтому не долго думая, я взялся за задачу, и вот уже через полчаса, был написан сбор статистики по отправляемым и принимаемым пакетам. Все это дело поставилось на лайв во время очередного планового рестарта и на несколько дней все забыли про это, так как началась новая порция безудержного веселья с заказчиком и его сервером.
Через некоторое время, заказчик вспомнил о проблеме, так как некоторые кланы уже начали уходить с сервера. Вооружившись собранной статистикой и потратив час на ее визуализацию + фильтрацию, был получен такой график:
прием: https://dl.dropboxusercontent.com/u/62505455/rcv1.png
отправка: https://dl.dropboxusercontent.com/u/62505455/snd1.png
Ось Х - временная шкала, ось У - количество пакетов.
Сразу оговорюсь, что сервер базируется на l2j like сборке, поэтому проблема актуальна, скорее всего на всех сборках такого вида :)
Немного прифигев от увиденного (рейт отсылки StatusUpdate выше CharInfo более чем в 2 раза, madness!), я стал думать, что делать. На графике ясно видно всплеск трафика, конечно же понятно, что в моменты всплеска происходили самые жесткие замесы между игроками. Вывод напрашивался сам - уменьшить количество броадкаста пакета StatusUpdate и жестко контроллить одиночную отсылку данных только по изменению каких-либо параметров персонажа.
Окей, сказано - сделано.
Идем в пакет StatusUpdate и смотрим трейс вызова конструктора. Тааакс, видим то что есть основные броадкаст методы, которые перегружаются в классах-наследниках L2Character (что уже радует, так как не надо бегать по всему коду), ну и конечно же видим одиночные посылки статуса во всяких богомерзких хандлерах и т.д.
В броадкасте нифига ничего не контролируется, логика тупа, как носок сапога - дернули метод, отослали всем игрокам в радиусе. Ну окей. Копаемся дальше и находим очень интересный код, который пытается контролить отсылку статуса (правда почему-то для пати, ну да фиг с этим), немного изучив код, понимаем, что его писали какие-то маньяки-индусы с корнями китайских программистов. Не долго думая, я наштопал свой, достаточно простой, контроллер - вычисляем процентное количество текущих показателей персонажа с поправкой на размер окошка в игре (что было как-то странно сделано в том самом контроллере) и запоминаем его после каждого вычисления (не забыв перед этим посмотреть, было ли прошлое значение таким же, если было, то в сад отправку пакета), в принципе, почти тоже самое, что и было в изначальном контроллере, но без индусокода.
Залив изменения и отчитавшись заказчику, я уже было решил, что задача выполнена, но не тут то было. По логике, это избавило бы людей от множества повторных пакетов на фарме мобов/РБ, но никак не избавило бы от кучи пакетов в массовом замесе (пакет то броадкастится всем в зоне видимости!).
Решение было найдено довольно быстро. По сути, всем окружающим игрокам нафиг не нужен этот пакет, он требуется только тем игрокам, у которых текущий моб в таргете, плюс отметается сразу посылка от игрока игроку (за исключением пати). Просто сохраняем игроков, которые взяли нашего актера в таргет, в блокирующей коллекции и потом делаем рассылку только по этим игрокам. Гениально! Обычно размер такой коллекции довольно скромный :)
Собственно графики, которые включают предыдущие (что бы сразу можно было сравнить):
отправка: https://dl.dropboxusercontent.com/u/62505455/snd12.png
Почему только отправка? Потому-что, в данном случае, правилось именно по ней, да и статья имеет заголовок об одном дне :)
P.S: графики намеренно оставил в виде ссылок, т.к. каждая пикча довольно тяжелая (по 1 мб)
Ну бывало и хуже, поэтому не долго думая, я взялся за задачу, и вот уже через полчаса, был написан сбор статистики по отправляемым и принимаемым пакетам. Все это дело поставилось на лайв во время очередного планового рестарта и на несколько дней все забыли про это, так как началась новая порция безудержного веселья с заказчиком и его сервером.
Через некоторое время, заказчик вспомнил о проблеме, так как некоторые кланы уже начали уходить с сервера. Вооружившись собранной статистикой и потратив час на ее визуализацию + фильтрацию, был получен такой график:
прием: https://dl.dropboxusercontent.com/u/62505455/rcv1.png
отправка: https://dl.dropboxusercontent.com/u/62505455/snd1.png
Ось Х - временная шкала, ось У - количество пакетов.
Сразу оговорюсь, что сервер базируется на l2j like сборке, поэтому проблема актуальна, скорее всего на всех сборках такого вида :)
Немного прифигев от увиденного (рейт отсылки StatusUpdate выше CharInfo более чем в 2 раза, madness!), я стал думать, что делать. На графике ясно видно всплеск трафика, конечно же понятно, что в моменты всплеска происходили самые жесткие замесы между игроками. Вывод напрашивался сам - уменьшить количество броадкаста пакета StatusUpdate и жестко контроллить одиночную отсылку данных только по изменению каких-либо параметров персонажа.
Окей, сказано - сделано.
Идем в пакет StatusUpdate и смотрим трейс вызова конструктора. Тааакс, видим то что есть основные броадкаст методы, которые перегружаются в классах-наследниках L2Character (что уже радует, так как не надо бегать по всему коду), ну и конечно же видим одиночные посылки статуса во всяких богомерзких хандлерах и т.д.
В броадкасте нифига ничего не контролируется, логика тупа, как носок сапога - дернули метод, отослали всем игрокам в радиусе. Ну окей. Копаемся дальше и находим очень интересный код, который пытается контролить отсылку статуса (правда почему-то для пати, ну да фиг с этим), немного изучив код, понимаем, что его писали какие-то маньяки-индусы с корнями китайских программистов. Не долго думая, я наштопал свой, достаточно простой, контроллер - вычисляем процентное количество текущих показателей персонажа с поправкой на размер окошка в игре (что было как-то странно сделано в том самом контроллере) и запоминаем его после каждого вычисления (не забыв перед этим посмотреть, было ли прошлое значение таким же, если было, то в сад отправку пакета), в принципе, почти тоже самое, что и было в изначальном контроллере, но без индусокода.
Залив изменения и отчитавшись заказчику, я уже было решил, что задача выполнена, но не тут то было. По логике, это избавило бы людей от множества повторных пакетов на фарме мобов/РБ, но никак не избавило бы от кучи пакетов в массовом замесе (пакет то броадкастится всем в зоне видимости!).
Решение было найдено довольно быстро. По сути, всем окружающим игрокам нафиг не нужен этот пакет, он требуется только тем игрокам, у которых текущий моб в таргете, плюс отметается сразу посылка от игрока игроку (за исключением пати). Просто сохраняем игроков, которые взяли нашего актера в таргет, в блокирующей коллекции и потом делаем рассылку только по этим игрокам. Гениально! Обычно размер такой коллекции довольно скромный :)
Собственно графики, которые включают предыдущие (что бы сразу можно было сравнить):
отправка: https://dl.dropboxusercontent.com/u/62505455/snd12.png
Почему только отправка? Потому-что, в данном случае, правилось именно по ней, да и статья имеет заголовок об одном дне :)
P.S: графики намеренно оставил в виде ссылок, т.к. каждая пикча довольно тяжелая (по 1 мб)
m0nster.art - clear client patches, linkz to utils & code.
Гадаю по капче.
Гадаю по капче.