Spigot netty что это
Разработка производительного игрового сервера на Netty + Java
Как и обещал, привожу описание производительного игрового сервера на Netty, который использую в своих проектах.
Все описанное ниже не является истинной в последней инстанции, а всего лишь опыт применения технологий в реальных проектах.
Начнем с начала.
Перед нами стоит задача сделать игровой сервер.
Работу с БД и прочими вещами сейчас рассматривать не будем. Сосредоточимся на сетевой части.
Чем в этом деле нам может помочь Netty?
Netty это сетевая библиотека, которая возьмет на себя непосредственно работу с сокетами. Подключение, отключение клиентов. Прием, отправка и фрагментация пакетов. Т.е. всю низкоуровневую работу с сокетами netty возьмет на себя.
Как netty нам поможет?
Netty реализует очень удобную архитектуру. Например она позволяет подключить несколько обработчиков входящих данных. Т.е. в первом обработчике мы разделяем входящий поток данных на пакеты, а во втором уже обрабатываем эти пакеты. При этом можно гибко управлять настройками самой библиотеки, выделять ей необходимое число потоков или памяти и т.д…
Общая архитектура при использовании 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 старается как можно быстрее принять пакеты от клиента и отправить их обработчику игровой логики, при этом в обработчике создается очередь из них.
Схематично весь процесс выглядит так.
Таким образом получаем довольно гибкую структуру. Пока нагрузки маленькие можно держать все на одном физическом сервере. При возрастании нагрузки можно TCP сервер на Netty выделить в отдельную машину. У которой хватит производительности для обслуживания нескольких физических серверов с игровой логикой.
Обработка сообщений происходит следующим образом. У нас есть Session это объект который хранит информацию связанную с подключенным клиентом, в нем так же хранятся 2 очереди, пришедших пакетов и готовых к отправке. Packet это объект хранящий информацию о сообщении полученном от клиента. Netty при получении пакета, добавляет его в очередь сессии на обработку и затем отправляет саму сессию на обработку игровой логике. Обработчик игровой логики берет сессию из очереди, потом берет пакет из очереди сессии и обрабатывает его согласно своей логике. И так в несколько потоков. Получается что пакеты обрабатываются последовательно по мере получения. И один клиент не будет тормозить остальных. Ух… вот завернул-то )) Если что, спрашивайте в каментах, поясню.
Вот картинка которая возможно понятнее будет.
Обработчик игровой логики.
Тут тоже ничего сложного нет. Создает пул потоков. Добавляем в очередь сессии на обработку и в обработчике реализуем свою игровую логику. Здесь просто надо соблюсти баланс между скоростью TCP сервера и скоростью обработчиков игровой логики. Чтобы очередь не заполнялась быстрее чем обрабатывалась. Netty очень быстрая библиотека. Так что все зависит от реализации вашей игровой гейм логики.
В качестве протокола я использую protobuf. Очень быстрая и удобная бинарная сериализация. Сделана и используется гуглом, что говорит о проверенности библиотеки на больших проектах )
С такой архитектурой, на моем нетбуке AMD 1.4 ГГц (lenovo edge 13), обрабатывается порядка 18-20к сообщений в секунду. Что в общем неплохо.
Введение в 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. Заключение
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: Запуск Socket сервера
Как было отмечено ранее, стабильная ветка Netty обладает отличным JavaDoc, а более новая четвертая ветка практически не задокументирована. Хочется еще отметить, что в JavaDoc’е Netty используется специальный JavaDoc доклет ApiViz, который позволяет отображать связи компонент прямо в документации ввиде графиков. В связи с этим обзор архитектуры будет вестись по 3ей версии. Именно по ней будет изучена терминология проекта, а уже с какими-то знаниями о компонентах системы мы посмотрим на отличия в реализации той или иной фичи в новой четвертой версии Netty.
В качестве отправной точки, будем использовать учебный проект Echo сервера, идущий вместе с исходниками Netty.
ServerBootstrap#bind запускает сервер, а точнее вешает сервер на определенный адрес. Рассмотрим на данном примере, как запускается NIO Socet Server.
И если socket открыт удачно, то канал сигнализирует событие об открытии нового канала.
Стоит рассказать, что в событийной модели Netty присутствуют два вида сообщений:
Все сообщения циркулируют по pipeline. Можно рассматривать pipeline, как цепочку обработчиков событий. Любой обработчик может остановить на себе обработку сообщения. Посыл сообщений происходит соответственно через pipeline.
Канал может быть создан другим каналом. Тот будет для нового канала родительским. Для каналов клиентской стороны родительским каналом будет канал серверной стороны. Входящее сообщение об открытии канала посылается и родительскому каналу, если он есть (метод fireChildChannelStateChanged ), и обработчикам данного канала.
Boss-канал, открывающий соединение, на данном этапе кроме открытия сокета и порождения события об этом, ничего не делает и не может делать, так как не обладает нужной для этого информацией. Как же происходит слежение за сообщениями данного канала? Очевидно, что у данного канала должны быть свои обработчики, которые будут ожидать события открытия соединения и в этот момент выполнять всю необходимую для нас работу.
В методах pipeline’а отправки сообщения происходит некоторое проксирование сообщений, т.к. разные реализации каналов могут работать по разному с разными сообщениями. Очевидно, что проксирование сообщений специфично для разных видов реализаций каналов, поэтому фабрика каналов, помимо типа самих каналов определяет конкретную реализацию проксирующего класса. Проксирующий класс определяет какие сообщения поддерживает канал и возможно даже обрабатывает какие-то из них, которые служат только для внутреннего использования. Такие объекты в Netty именуются Sink объектами. В данном случае обработка события привязки сервера к адресу обрабатывается внутри NioServerSocketPipelineSink :
В первую очередь вызывается привязка адреса к Java сокету. Далее ChannelFuture переводится в состояние успешного выполнения операции и посылается уже входящее сообщение pipeline’у канала о привязке сервера к адресу. Далее получается пул потоков, который мы передали фабрике каналов и с помощью него запускается boss-поток, который будет следить за соединениями по данному каналу. Теперь наш сервер может принимать соединения и обрабатывать их нашим pipeline’ом.
Т.е. на данном этапе Binder обработчик связал сокет с адресом и осталось оповестить ServerBootstrap о статусе конфигурирования канала и вернуть наружу ссылку на сам канал. Но тут есть две проблемы:
Как только Binder сконфигурировал открытый канал, он помещает ChannelFuture объект, который мы ранее рассмотрели в методе bind самого канала, в эту очередь:
В этот момент поток выполнения ServerBootstrap оживает и получает это сообщение из очереди и если статус ChannelFuture говорит, что все прошло хорошо, то наружу возвращает ссылка на открытый канал.
Вот так просто и изящно создаются socket соединения в Netty 3.5.
Posted by Code insiders 12:39 04.08.2012 Netty
[Гайд] Создание сервера с использованием Spigot
Что такое Spigot?
Spigot — это глобальная серверная модификация, созданная на основе ядра CraftBukkit. Она призвана заменить «старшего брата» стабильностью и производительностью. Сегодня мы будем рассматривать создание сервера с нуля, поскольку стабильность — не единственное отличие Spigot от CraftBukkit.
Как установить Spigot?
Первым делом нам потребуется скачать одну из сборок Spigot. Общий репозиторий находится здесь. В меню справа можно найти все ранее выпущенные сборки:
Нажимая на дату добавления сборки, Вы попадаете на страницу, где можно её скачать. Принадлежность сборки к определённой версии можно установить, посмотрев на версию, указанную после заголовка «Артефакты сборки». Для загрузки выбранной сборки нажмите на «spigot.jar».
После загрузки переместите файл «spigot.jar» в отдельную папку (Например: «Server») и создайте текстовый документ с расширением *.bat (Например: RUN.bat). Далее откройте созданный ранее файл в любом текстовом редакторе и напишите внутри него следующее:
После этого можно запускать только что созданный файл. Затем, когда процесс будет завершён, Вам потребуется открыть файл «eula.txt» и изменить строчку «eula=false» на «eula=true». Запустите *.bat файл ещё раз. После этого перед Вами появится консоль сервера и начнётся создание игрового мира.
Настройка конфигурационных файлов.
После создания сервера появится файл настроек игры, под названием «server.properties». О том, как его настроить, можно узнать, прочитав данную статью на WIKI.
Установка плагинов.
Для установки плагина, его требуется переместить в папку «plugins» в корне Вашего сервера. Все плагины, созданные для глобальной серверной модификации под названием «CraftBukkit», походят и для Spigot. В большинстве случаев после перезагрузки сервера в папке «plugins» создаётся папка с названием установленного плагина. В этой папке как правило есть конфигурационные файлы плагина, имеющие расширение *.yml.
Плагины можно русифицировать самостоятельно, редактируя конфигурационные файлы, либо найти готовый перевод на форуме проекта RUBukkit и в других источниках.