spigot netty что это

Netty Spigot

Ребят, кто-то пробывал ставить Spigot с Netty?
Как у вас работало, была ли больше или меньше нагрузка на CPU, сколько потоков включали?
Еще укажите плз сборку spigot стабильную на 1.5.2 с netty пожалуйста :3

Ребят, кто-то пробывал ставить Spigot с Netty?
Как у вас работало, была ли больше или меньше нагрузка на CPU, сколько потоков включали?
Еще укажите плз сборку spigot стабильную на 1.5.2 с netty пожалуйста :3

Данная библиотека если мне не изменяет память присутствует в ядре с февраля.

В другом топикt я скинул пример хабра как это работает.

Чуть позже протестирую сие чудо и скину в тему форума.

Данная библиотека если мне не изменяет память присутствует в ядре с февраля.

В другом топикt я скинул пример хабра как это работает.

Чуть позже протестирую сие чудо и скину в тему форума.

Intel Xeon E3 1245v2 (4 cores / 8 Threads)

3.4GHz (3.8GHz Turbo Boost)

Intel Xeon E3 1245v2 (4 cores / 8 Threads)

3.4GHz (3.8GHz Turbo Boost)

netty-threads при 101 слоте сколько лучше поставить?

то есть выставить 0?

Опять начинаешь говорить очевидное?)

Опять начинаешь говорить очевидное?)

Я дал ответ на вопрос выше, не приводя никаких бесполезных тестов, которые ТСу в данный момент не помогут вообще никак.

Для тебя специально запятую выделил. Он спрашивает про конкретную нагрузку по сравнению с ведром.

Я дал ответ на вопрос выше, не приводя никаких бесполезных тестов, которые ТСу в данный момент не помогут вообще никак.

то есть выставить 0?

Я использовал стандартное значение.

Источник

Введение в Netty

Узнайте, как настроить небольшой сервер Netty и клиента на Java.

Введение в Netty

1. Введение

В этой статье мы собираемся взглянуть на Netty – асинхронную систему сетевых приложений, управляемых событиями.

Основной целью Netty является создание высокую производительность протокольных серверов на основе NIO (или, возможно, NIO.2) с разделением и свободным соединением компонентов сетевой и бизнес-логики. Он может реализовать широко известный протокол, такой как HTTP, или ваш собственный конкретный протокол.

2. Основные концепции

Netty — это не блокирующая структура. Это приводит к высокой пропускной способности по сравнению с блокированием IO. Понимание не блокируя IO имеет решающее значение для понимания основных компонентов Netty и их отношений.

2.1. Канал

Канал является основой Java NIO. Он представляет собой открытое соединение, способное выполнять io-операции, такие как чтение и письмо.

2.2. Будущее

Каждая операция IO на канал в Netty не блокируется.

Это означает, что каждая операция возвращается сразу после вызова. Существует Будущие интерфейс в стандартной библиотеке Java, но это не удобно для целей Netty – мы можем спросить только Будущие о завершении операции или о блокировке текущего потока до завершения операции.

Вот почему Netty имеет свои собственные ChannelFuture интерфейс . Мы можем передать обратный звонок ChannelFuture которые будут призваны к завершению операции.

2.3. События и обработчики

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

Исходящие события проще и, как правило, связаны с открытием/закрытием данных соединения и написания/промывки.

Кроме того, существует множество реализаций конкретных протоколов, таких, как HTTP, например, HttpRequestDecoder, HttpResponseEncoder, HttpObjectAggregator. Было бы хорошо, чтобы познакомиться с ними в Javadoc Нетти.

2.4. Кодеры и декодеры

Работая с сетевым протоколом, мы должны выполнять сериализацию данных и дезириализацию. Для этого Netty вводит специальные расширения ChannelInboundHandler для декодеры которые способны декодировать входящие данные. Базовый класс большинства декодеров ByteToMessageDecoder.

Для кодирования исходящих данных Netty имеет расширения ChannelOutboundHandler называется Кодеры. СообщениеToByteEncoder является основой для большинства кодера реализации . Мы можем преобразовать сообщение из последовательности byte в java-объект и наоборот с помощью кодеров и декодеров.

3. Пример серверного приложения

Давайте создадим проект, представляющий простой протокольный сервер, который получает запрос, выполняет расчет и отправляет ответ.

3.1. Зависимости

Прежде всего, мы должны обеспечить зависимость Netty в нашей пом.xml :

3.2. Модель данных

Класс данных запросов будет иметь следующую структуру:

Допустим, сервер получает запрос и возвращает intValue умножается на 2. Ответ будет иметь одно int значение:

3.3. Запрос декодера

Теперь нам нужно создать кодеры и декодеры для наших протокольных сообщений.

Мы должны убедиться, что мы получили полное сообщение перед и есть много способов сделать это.

Прежде всего, мы можем создать временную ByteBuf и придаток к нему все входящие байты, пока мы не получим необходимое количество байтов:

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

Мы сознательно не использовали stringValue – расшифровка таким образом была бы неоправданно сложной. Именно поэтому Netty предоставляет полезные классы декодеров, которые являются реализациями ChannelInboundHandler : ByteToMessageDecoder и Воспроизведениедекодера.

Как мы уже отмечали выше, мы можем создать канал обработки трубопровода с Netty. Таким образом, мы можем поставить наш декодер в качестве первого обработчика и обработчик логики обработки может прийти после него.

Декодер для RequestData отображается следующим:

Идея этого декодера довольно проста. Он использует реализацию ByteBuf который бросает исключение, когда в буфере недостаточно данных для операции чтения.

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

3.4. Ответ Encoder

Кроме того, расшифровка ЗапросДанные нам нужно закодировать сообщение. Эта операция проще, потому что у нас есть полные данные сообщения, когда происходит операция записи.

Мы можем писать данные Канал в нашем главном обработчике или мы можем отделить логику и создать обработчик, расширяющий СообщениеToByteEncoder который будет ловить писать ОтветДанные операция:

3.5. Обработка запросов

Так как мы провели расшифровку и кодирование в отдельных обработчиках, мы должны изменить наши ОбработкаХэндлер :

3.6. Сервер Bootstrap

Теперь давайте ставим все это вместе и запустить наш сервер:

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

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

4. Клиентская заявка

Клиент должен выполнять обратное кодирование и расшифровку, поэтому мы должны иметь ЗапросDataEncoder и ОтветДанныйдекодер :

Кроме того, мы должны определить КлиентХэндлер который отправит запрос и получит ответ с сервера:

Теперь давайте bootstrap клиента:

Как мы видим, Есть много деталей, общих с сервера загрузки.

Теперь мы можем запустить основной метод клиента и взглянуть на выход консоли. Как и ожидалось, мы ОтветДанные с intValue равно 246.

5. Заключение

Источник

Топ 6 оптимизаций для netty

Всем привет. Эта статья продолжение 10к на ядро с конкретными примерами оптимизаций, которые были проделаны для повышения производительности сервера. С написания первой части прошло уже 5 мес и за это время нагрузка на наш продакшн сервер выросла с 500 рек-сек до 2000 с пиками до 5000 рек-сек. Благодаря netty, мы даже не заметили это повышение (разве что место на диске уходит быстрее).

spigot netty что это. Смотреть фото spigot netty что это. Смотреть картинку spigot netty что это. Картинка про spigot netty что это. Фото spigot netty что это
(Не обращайте внимание на пики, это баги при деплое)

Эта статья будет полезна всем тем кто работает с netty или только начинает. Итак, поехали.

Нативный Epoll транспорт для Linux

Одна из ключевых оптимизаций, которую стоит использовать всем — это подключение нативного Epoll транспорта вместо реализации на java. Тем более, что с netty это означает добавить лишь 1 зависимость:

и автозаменой по коду осуществить замену следующих классов:

Нативный OpenSSL

Не знаю как на просторах СНГ, но ТАМ — безопасность ключевой фактор для любого проекта. “What about security?” — неминуемый вопрос, который Вам обязательно зададут, если заинтересуются Вашим проектом, системой, сервисом или продуктом.

В аутсорс мире, из которого я пришел, в команде всегда обычно был 1-2 DevOps на которых я всегда мог переложить данный вопрос. Например, вместо добавлять поддержку https, SSL/TLS на уровне приложения, всегда можно было попросить администраторов настроить nginx и с него уже прокидывать обычный http на свой сервер. И быстро и эффективно. Сегодня, когда я и швец и жнец и на дуде игрец — мне все приходится делать самому — заниматься разработкой, деплоить, мониторить. Поэтому подключить https на уровне приложения гораздо быстрее и проще чем разворачивать nginx.

Заставить openSSL работать с netty немного сложнее чем подключить нативный epoll транспорт. Вам понадобится подключить в проект новую зависимость:

Указать в качестве провайдера SSL — openSSL:

Добавить еще один обработчик в pipeline:

15%.
Полный пример можно глянуть тут и тут.

Экономим на системных вызовах

Очень часто приходится отправлять несколько сообщений в один и тот же сокет. Это может выглядеть так:

Этот код можно оптимизировать

Во втором случае при write нетти не будет сразу отсылать сообщение по сети, а обработав положит его в буфер (в случае если сообщение меньше буфера). Таким образом уменьшая количество системных вызовов для отправки данных по сети.

Лучшая синхронизация — отсутствие синхронизации.

Как я уже писал в предыдущей статье — netty асинхронный фреймворк с малым количеством потоков обработчиков логики (обычно n core * 2). Поэтому каждый такой поток-обработчик должен выполнятся как можно быстрее. Любого рода синхронизация может этому помешать, особенно при нагрузках в десятки тысяч запросов в секунду.

С этой целью netty каждое новое соединение привязывает к одному и тому же обработчику (потоку) чтобы снизить необходимость кода для синхронизации. Например, если пользователь присоединился к серверу и выполняет некие действия — допустим, изменяет состояние модели, которая связана только с ним, то никакой синхронизации и volatile не нужно. Все сообщения этого пользователя будут обрабатываться одним и тем же потоком. Это отлично и работает для части проектов.

Но что, если состояние может изменятся из нескольких соединений, которые вероятней всего будут привязаны к разным потокам? Например, для случая, когда мы делаем игровую комнату и команда от пользователя должна менять окружающий мир?

Для этого в netty существует метод register, который позволяет перепривязать соединение из одного обработчика к другому.

Этот подход позволяет обрабатывать события для одной игровой комнаты в одном потоке и полностью избавится от сихронизаций и volatile для изменения состояния этой комнаты.
Пример перепривязки на логин в моем коде тут и тут.

Переиспользуем EventLoop

Netty довольно часто выбирают для серверного решения, так как сервера должны поддерживать работу разных протоколов. Например, мое скромное IoT облако поддерживает HTTP/S, WebSockets, SSL/TCP сокеты для разного hardware и собственного бинарного протокола. Это значит, что для каждого из этих протоколов должен быть IO поток (boss group) и потоки обработчики логики (work group). Обычно создание нескольких таких обработчиков выглядит так:

Но в случае netty чем меньше лишних потоков вы создаете, тем больше вероятность создать более производительное приложение. К счастью, в netty EventLoop можно переиспользовать:

Off-heap сообщения

Ни для кого уже не секрет, что для высоконагруженных приложений одним из узких мест является сборщик мусора. Netty быстра, в том числе, как раз за счет повсеместного использования памяти вне java heap. У netty есть даже своя экосистема вокруг off-heap буферов и система обнаружения утечек памяти. Так можете поступить и Вы. Например:

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

Надеюсь эти простые советы позволят Вам ускорить ваше приложение.
Напомню, что мой проект open-source. Поэтому если Вам интересно как эти оптимизации выглядят в существующем коде — смотрите тут.

Источник

Высокопроизводительный NIO-сервер на Netty

Преамбула

Здравствуйте. Я являюсь главным разработчиком крупнейшего в СНГ сервера Minecraft (не буду рекламировать, кому надо, те знают). Уже почти год мы пишем свою реализацию сервера, рассчитанную на больше чем 40 человек (мы хотим видеть цифру в 500 хотя бы). Пока всё было удачно, но последнее время система начала упираться в то, что из-за не самой удачной реализации сети (1 поток на ввод, 1 на вывод + 1 на обработку), при 300 игроках онлайн работает более 980 потоков (+ системные), что в сочетании с производительностью дефолтного io Явы даёт огромное падение производительности, и уже при 100 игроках сервер в основном занимается тем, что пишет/читает в/из сети.

Поэтому я решила переходить на NIO. В руки совершенно случайно попала библиотека Netty, структура которой показалась просто идеально подходящей для того, чтобы встроить её в уже готовое работающее решение. К сожалению, мануалов по Netty мало не только на русском, но и на английском языках, поэтому приходилось много экспериментировать и лазить в код библиотеки, чтобы найти лучший способ.

Здесь я постараюсь расписать серверную часть работы с сетью через Netty, может быть это кому-то будет полезно.

Создание сервера

Используется OrderedMemoryAwareThreadPoolExecutor для выполнения задач Netty, по опыту французских коллег они самые эффективные. Можно использовать другие Executor’ы, например Executors.newFixedThreadPool(n). Ни в коем случае не используйте Executors.newCachedThreadPool(), он создаёт неоправданно много потоков и ни какого выигрыша от Netty почти нет. Использовать более 4 рабочих потоков нет смысла, т.к. они более чем справляются с огромной нагрузкой (программисты из Xebia-France на 4 потоках тянули более 100 000 одновременных подключений). Босс-потоки должны быть по одному на каждый слушаемый порт. Channel, который возвращает функция bind, а так же ServerBootsrap необходимо сохранить, чтобы потом можно было остановить сервер.

PipelineFactory

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

В данном коде PacketFrameDecoder, PacketFrameEncoder и PlayerHandler — обработчки событий, которые мы определяем. Функция Channels.pipeline() создаёт новый pipeline с переданными ей обработчиками. Будьте внимательны: события проходят обработчики в том порядке, в котором Вы передали из функции pipeline!

Протокол

Немного опишу протокол, чтобы дальше было понятно.

Обмен данными происходит с помощью объектов классов, расширяющих класс Packet, в которых определены две функции, get(ChannelBuffer input) и send(ChannelBuffer output). Соответственно, первая функция читает необходимые данные из канала, вторая — пишет данные пакета в канал.

Пример пары пакетов для наглядности:

ChannelBuffer очень похож на DataInputStream и DataOutputStream в одном лице. Большинство функций если не такие же, то очень похожи. Заметьте, что я не забочусь о проверке того, хватает ли в буфере байт для чтения, как будто я работаю с блокирующим IO. Об этом далее…

Работа с клиентом

Работа с клиентом в основном определяется классом PlayerHandler:

Worker может посылать игроку данные просто функцией channel.write(packet), где channel — канал игрока, который передаётся ему при подключении, а packet — объект класса Packet. За кодирование пакетов будет отвечать уже Encoder.

Decoder и Encoder

Собственно, сама важная часть системы — они отвечают за формирование пакетов Packet из потока пользователя и за отправку таких же пакетов в поток.

Encoder очень прост, он отправляет пакеты игроку:

Decoder уже гораздо сложнее. Дело в том, что в буфере, пришедшем от клиента, может просто не оказаться достаточного количества байт для чтения всего пакета. В этом случае, нам поможет класс ReplayingDecoder. Нам всего лишь нужно реализовать его функцию decode и читать в ней данные из потока, не заботясь не о чём:

Спрашивается, как это работает? Очень просто, перед вызовом функции decode декодер помечает текущий индекс чтения, если при чтении из буфера в нём не хватит данных, будет сгенерировано исключение. При этом буфер вернётся в начальное положение и decode будет повторён, когда больше данных будет получено от пользователя. В случае успешного чтения (возвращён не null), декодер попытается вызвать функции decode ещё раз, уже на оставшихся в буфере данных, если в нём есть ещё хотя бы один байт.

Не медленно ли всё это работает, если он генерирует исключение? Медленнее, чем, например, проверка количества данных в буфере и оценка, хватит ли их для чтения пакета. Но он использует кэшированное исключение, поэтому не тратится время на заполнения stacktrace и даже создание нового объекта исключения. Подробнее об и некоторых других, повышающих эффективность, функцийя ReplayingDecoder можно почитать здесь

Вы так же можете поэкспериментировать с FrameDecoder’ом, если, например, Вы можете заранее определить размер пакета по его ID.

Кажется, это всё

Результаты получились отличными. Во-первых, сервер больше не сыпет тысячей потоков — 4 потока Netty + 4 потока обработки данных прекрасно справляются с 250+ клиентами (тестирование продолжается). Во-вторых, нагрузка на процессор стала значительно меньшей и перестала линейно расти от числа подключений. В-третьих, время отклика в некоторых случаях стало меньше.

Надеюсь кому-нибудь это будет полезно. Старалась передать как можно больше важных данных, могла переборщить. Примеров ведь много не бывает? Спрашивайте Ваши ответы и не судите строго — первый раз пишу на хабр.

Постскриптум: ещё несколько полезных вещей

У Netty есть ещё несколько интересных особенностей, которые заслуживают отдельного упоминания:

Во-первых, остановка сервера:

Где channel — канал, который возвратила функция bind в начале. future.awaitUninterruptibly() дождётся, пока канал закроется и выполнение кода продолжится.

Самое интересное: ChannelFuture. Когда мы отправляем на канал пакет, функцией channel.write(packet), она возвращает ChannelFuture — это особый объект, который отслеживает состояние выполняемого действия. Через него можно проверить, выполнилось ли действие.

Например, мы хотим послать клиенту пакет отключения и закрыть за ним канал. Если мы сделаем

то с вероятностью 99%, мы получим ChannelClosedException и пакет до клиента не дойдёт. Но можно сделать так:

То всё будет супер, кроме того, что это может заблокировать поток выполнения, пока пакет не отправится пользователю. Поэтому на ChannelFuture можно повесит listener — объект, который будет уведомлён о том, что событие совершилось и выполнит какие-либо действия. Для закрытия соединения есть уже готовый listener ChannelFutureListener.CLOSE. Пример использования:

Эффект тот же, блокировок нет. Разобраться в том, как создать свой листенер не сложно — там всего одна функция. Откройте любой готовый класс, здесь я не буду приводить пример.

Ещё важная информация

Как правильно было замечено в комментариях, следует предупредить о том, что в обработчиках (handler-ах, которые висят на pipeline) лучше не стоит использовать блокирующие операции или ожидание. В противном случае, Вы рискуете навсегда потерять поток обработки или просто сильно затормозить обработку событий остальных клиентов.

Вообще, все действия, выполняемые в ChannelHandler’ах должны быть как можно более простыми и неблокирующими. Ни в коем случае не обрабатывайте данные прямо в них — кладите пакеты в очередь и обрабатывайте их в другом потоке.

Источник

Разработка производительного игрового сервера на Netty + Java

spigot netty что это. Смотреть фото spigot netty что это. Смотреть картинку spigot netty что это. Картинка про spigot netty что это. Фото spigot netty что это

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

Начнем с начала.

Перед нами стоит задача сделать игровой сервер.

Работу с БД и прочими вещами сейчас рассматривать не будем. Сосредоточимся на сетевой части.

Чем в этом деле нам может помочь Netty?

Netty это сетевая библиотека, которая возьмет на себя непосредственно работу с сокетами. Подключение, отключение клиентов. Прием, отправка и фрагментация пакетов. Т.е. всю низкоуровневую работу с сокетами netty возьмет на себя.

Как netty нам поможет?

Netty реализует очень удобную архитектуру. Например она позволяет подключить несколько обработчиков входящих данных. Т.е. в первом обработчике мы разделяем входящий поток данных на пакеты, а во втором уже обрабатываем эти пакеты. При этом можно гибко управлять настройками самой библиотеки, выделять ей необходимое число потоков или памяти и т.д…
Общая архитектура при использовании Netty может выглядеть так:

spigot netty что это. Смотреть фото spigot netty что это. Смотреть картинку spigot netty что это. Картинка про spigot netty что это. Фото spigot netty что это

У нас получается 3 обработчика:
1. Connection handler — это обработчик который отвечает за подключения/отключения клиентов. Здесь будет происходить проверка возможности подключения клиентов (черные, белые списки, IP фильтры и т.д.) а так же корректное отключение клиентов с закрытием всех используемых ресурсов.

2. Frame handler — это обработчик разделяющий поток данных на отдельные пакеты.
Для удобства работы примем, что пакет состоит из двух частей. 1-заголовок, в котором описана длинна пакета, и 2-непосредственно данные пакета.

3. Packet handler — это уже обработчик игровых сообщений. Здесь мы будем получать данные из пакета и дальше их обрабатывать.

Разберем каждую часть в коде.

Connection handler
Frame handler.

Здесь используем реплей декодер с двумя состояниями. В одном читаем длину пакета, в другом сами данные.

Packet handler

Как видно, обработчик получился очень простой и быстрый. Packet это мой класс в котором содержится вся необходимая информация для обработки его игровой логикой. Он очень простой и его реализация не составит труда.

Это самый главный обработчик. В принципе можно практически всю логику описать в нем. Нюанс здесь в том, что в нем нельзя использовать блокирующие элементы и длительные по времени операции, например подключение к базе данных. Это как минимум затормозит всю работу. Поэтому мы архитектурно разделим наш сервер на 2 части. Первая это чисто TCP сервер, основная задача которого как можно быстрее принять пакет от клиента и как можно быстрее отослать пакет клиенту. Вторая это непосредственно обработчик игровой логики. В принципе, по такой схеме можно сделать не только игровой сервер. Ведь логика обработки пакетов может быть любой.
Прелесть такой архитектуры еще и в том, что TCP сервер и обработчики можно разнести по разным машинам (например с помощью Akka акторов) получив кластер для расчетов игровых данных. Таким образом получаем следующую схему работы сервера. TCP часть на Netty старается как можно быстрее принять пакеты от клиента и отправить их обработчику игровой логики, при этом в обработчике создается очередь из них.

Схематично весь процесс выглядит так.

spigot netty что это. Смотреть фото spigot netty что это. Смотреть картинку spigot netty что это. Картинка про spigot netty что это. Фото spigot netty что это

Таким образом получаем довольно гибкую структуру. Пока нагрузки маленькие можно держать все на одном физическом сервере. При возрастании нагрузки можно TCP сервер на Netty выделить в отдельную машину. У которой хватит производительности для обслуживания нескольких физических серверов с игровой логикой.

Обработка сообщений происходит следующим образом. У нас есть Session это объект который хранит информацию связанную с подключенным клиентом, в нем так же хранятся 2 очереди, пришедших пакетов и готовых к отправке. Packet это объект хранящий информацию о сообщении полученном от клиента. Netty при получении пакета, добавляет его в очередь сессии на обработку и затем отправляет саму сессию на обработку игровой логике. Обработчик игровой логики берет сессию из очереди, потом берет пакет из очереди сессии и обрабатывает его согласно своей логике. И так в несколько потоков. Получается что пакеты обрабатываются последовательно по мере получения. И один клиент не будет тормозить остальных. Ух… вот завернул-то )) Если что, спрашивайте в каментах, поясню.

Вот картинка которая возможно понятнее будет.
spigot netty что это. Смотреть фото spigot netty что это. Смотреть картинку spigot netty что это. Картинка про spigot netty что это. Фото spigot netty что это

Обработчик игровой логики.

Тут тоже ничего сложного нет. Создает пул потоков. Добавляем в очередь сессии на обработку и в обработчике реализуем свою игровую логику. Здесь просто надо соблюсти баланс между скоростью TCP сервера и скоростью обработчиков игровой логики. Чтобы очередь не заполнялась быстрее чем обрабатывалась. Netty очень быстрая библиотека. Так что все зависит от реализации вашей игровой гейм логики.

В качестве протокола я использую protobuf. Очень быстрая и удобная бинарная сериализация. Сделана и используется гуглом, что говорит о проверенности библиотеки на больших проектах )

С такой архитектурой, на моем нетбуке AMD 1.4 ГГц (lenovo edge 13), обрабатывается порядка 18-20к сообщений в секунду. Что в общем неплохо.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *