GameServer High CPU Debugging - Culprit: многопоточный WebSocketServer? - PullRequest
0 голосов
/ 13 сентября 2018

Фон

У нас есть динамичная многопользовательская онлайн-игра, в которую играют в веб-браузере.Через Secure WebSockets клиенты подключаются к GameServer и в некоторых случаях отправляют ~ 60 пакетов в секунду.Мы заметили, что наш GameServer получает ужасную производительность ЦП, когда Клиент отправляет любой запрос через WebSocket на GameServer , даже если GameServer не выполняет никакой логики, кроме захвата пакета сетью библиотеки в сети..Как вы можете подозревать, с большим количеством запросов, приводящих к более высокой загрузке процессора.Как плохо?Что ж, мы увидели ~ 30% загрузки ЦП только для нескольких запросов.Иногда он колеблется около 3%, но мне (не специалисту по многопоточности) кажется, что это происходит, когда нам просто везет на используемый поток.

Код GameServer работает на размещенном четырехъядерном сервере.от Linode .

Рассматриваемая библиотека GameServer WebSocket имеет вид TooTallNate Java-WebSocket .

Воспроизведение и профилирование

Выполнение jvmtop --profile дает следующий результат https://i.gyazo.com/6419081e6254cd82aec52eb451f24bd9.mp4 (развернуть и щуриться, чтобы прочитать данные).Вы можете видеть, что он достигает ~ 90%, указывая подозреваемому на WebSocketServer.run () .Мы заметили дополнительные большие удары ЦП, когда происходит gc, но вы можете увидеть увеличение до того, как это произойдет.

jstack предоставил дополнительную информацию .(Мы используем основную версию Java-WebSocket, но некоторые строки кода могут быть немного не в порядке, так как мы добавили некоторые операторы отладки).Мы подозреваем, что есть какие-то проблемы с блокировкой с LinkedBlockingQueue и методом take(), но у нас недостаточно опыта для дальнейшей отладки или устранения этой проблемы.

Дополнительные данные

  • Мы заметили некоторые тенденции: некоторые потоки иногда занимают определенную загрузку процессора.Например, если вы внимательно присмотритесь, то увидите, что иногда несколько потоков используют 1,7%, 1,7%, 1,7% и 0,7%.В другом случае вы можете увидеть 3,3%, 3,3% и 0,7%.Мне кажется, что эти потоки пытаются определенное количество времени вычислений (?), А затем отказываются, в то время как процессорный поток с небольшим использованием является тем, который фактически выполняет работу tiny .

  • Наш экземпляр является статическим, и мы указываем 1 декодер для этого конструктора (по умолчанию будет 4, так как у нас 4 ядра - изменение не дало никакой разницы).

  • Больше демонстраций ( первый , второй , третий , четвертый )
  • Серверработает Ubuntu 17.10, и мы попробовали java-8-openjdk-amd-64 и java-10-oracle, без разницы.
  • Мы в значительной степени используем библиотеку «как есть» из коробки без особогоизменение настроек.Мы отключаем алгоритм nagle ( ссылка ).
  • Мы попытались выделить дополнительную память для фляги с помощью -Xmx3g и -Xms3g и нескольких других опций, но ничего не помогло.
  • Как видно из jstack , мы также используем Kryonet в частном бэкэнде, чтобы позволить другим серверам связываться друг с другом.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...