Это 4-й день моего участия в августовском испытании обновлений.Подробности о событии:Испытание августовского обновления
Введение
Чем же Netty так хороша, и какие усовершенствования она сделала на основе самого NIO JDK? Какова его архитектура и рабочий процесс? Пожалуйста, ознакомьтесь с сегодняшней серией статей о Netty: Обзор архитектуры Netty.
схема сетевой архитектуры
Основная роль netty заключается в предоставлении простой инфраструктуры NIO, которую можно комбинировать с различными протоколами верхнего уровня, чтобы в конечном итоге получить высокопроизводительные серверы. Ниже представлена схема архитектуры, представленная на официальном сайте netty:
Как видно из рисунка выше, ядро netty в основном разделено на три части, а именно расширяемую модель событий, унифицированный API и мощный байтовый буфер. Эти три характеристики — волшебное оружие нетти.
Далее будут подробно описаны характеристики netty с этих аспектов, чтобы читатели могли понять превосходство netty.
Богатая организация данных буфера
Начиная с нижней структуры данных Buffer, netty предоставляет пакет io.netty.buffer, который определяет различные типы ByteBuf и производные от них типы.
Основой netty Buffer является абстрактный класс ByteBuf. Другие классы Buffer в основном являются производными от этого класса. Этот класс также определяет общий тон Netty Buffer.
Цель переписывания Netty ByteBuf состоит в том, чтобы сделать ByteBuf нижнего уровня быстрее и более подходящим для расширения, чем тот, который поставляется с JDK. В частности, ByteBuf netty работает быстрее, чем ByteBuffer в JDK, и в то же время его легче расширять, и вы можете настроить Buf в соответствии со своими потребностями. Кроме того, netty имеет несколько встроенных составных типов буферов, поэтому можно добиться прозрачного нулевого копирования. Для динамических типов буферов он может быть расширен по запросу, как StringBuffer, который очень прост в использовании.
нулевая копия
Что такое нулевая копия? Нулевое копирование означает, что копия не делается, когда требуется копия. Мы знаем, что данные будут инкапсулированы в пакеты для передачи в процессе использования базового протокола для передачи. Когда передаваемые данные слишком велики, чтобы поместиться в один пакет, данные необходимо разделить.После получения данных пункт назначения должен собрать полученные данные.В общем, операция сборки предназначена для данных.Копировать, копировать разделение объект в длинное пространство данных.
Например, как показано в следующем примере, базовая комбинация TCP-пакетов называется HTTP-пакетом верхнего уровня, но не копируется:
Как именно вы его копируете? В предыдущей статье мы знаем, что netty предоставляет метод класса инструментов Unpooled, в этом классе инструментов есть много методов в начале накрутки, приведем несколько примеров:
public static ByteBuf wrappedBuffer(byte[]... arrays) {
return wrappedBuffer(arrays.length, arrays);
}
public static ByteBuf wrappedBuffer(ByteBuf... buffers) {
return wrappedBuffer(buffers.length, buffers);
}
public static ByteBuf wrappedBuffer(ByteBuffer... buffers) {
return wrappedBuffer(buffers.length, buffers);
}
Вышеупомянутые три метода соответственно инкапсулируют массив байтов, инкапсулируют ByteBuf и инкапсулируют ByteBuffer, Все эти методы являются нулевым копированием. Вы можете выбрать в соответствии с реальной ситуацией в реальном проекте.
Единый API
Вообще говоря, в традиционном API ввода-вывода JDK используемый API отличается в зависимости от типа передачи или протокола. Нам нужно разработать разные приложения для разных методов передачи, которые нельзя унифицировать. В результате плавной миграции не происходит, и при расширении программы требуется дополнительная обработка.
Каков метод передачи? Это относится к тому, как реализовать ввод-вывод, такой как традиционный блокирующий ввод-вывод, мы можем назвать его OIO, новый ввод-вывод Java можно назвать NIO, асинхронный ввод-вывод можно назвать AIO и так далее.
И традиционный IO и NIO в JDK разделены.Если вы используете традиционный IO в начале, когда количество ваших клиентов вырастет до определенного уровня и вы будете готовы перейти на NIO, вы обнаружите, что переключение очень сложно , т.к. они фрагментарны.
Чтобы решить эту проблему, netty предоставляет унифицированный класс Channel для предоставления унифицированного API.
Сначала взгляните на методы, определенные в Channel:
Из приведенного выше рисунка видно, что канал можно использовать для оценки текущего состояния канала, настройки его параметров и выполнения на нем операций ввода-вывода, а ChannelPipeline, связанный с каналом, используется для обработки запросов ввода-вывода. и события, связанные с каналом.
Использование канала может обеспечить хорошую поддержку TCP/IP NIO, TCP/IP OIO, UDP/IP OIO и локальной передачи.
Переключение режима передачи требует лишь замены с небольшими затратами.
Конечно, если вас не устраивает существующая реализация, вы также можете сделать собственные расширения для основного API.
управляемый событиями
Netty – это событийно-ориентированная платформа. Основой событийно-ориентированной среды является модель событий. Netty определяет очень эффективную событийную модель для ввода-вывода. Вы можете реализовать свои собственные типы событий, не нарушая существующий код. Пользовательские типы событий в netty отличаются от других типов событий строгой иерархией типов, поэтому они легко расширяемы.
Управление событиями в netty является результатом совместного действия ChannelEvent, ChannelHandler и ChannelPipeline. Среди них ChannelEvent представляет произошедшее событие, ChannelHandler определяет, как обрабатывать событие, а ChannelPipeline подобен перехватчику, который позволяет пользователям самостоятельно управлять определенным ChannelHandler, чтобы достичь результата управления обработкой события.
Давайте посмотрим на простой пользовательский обработчик:
public class MyHandler extends SimpleChannelInboundHandler<Object> {
@Override
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
// 对消息进行处理
ByteBuf in = (ByteBuf) msg;
try {
log.info("收到消息:{}",in.toString(io.netty.util.CharsetUtil.US_ASCII));
}finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
//异常处理
cause.printStackTrace();
ctx.close();
}
}
В приведенном выше примере мы определили, как обрабатывать полученные сообщения и исключения. В последующих статьях мы подробно расскажем о взаимодействии между ChannelEvent, ChannelHandler и ChannelPipeline.
Другие замечательные функции
В дополнение к трем основным функциям, упомянутым выше, у netty есть несколько других преимуществ, которые облегчают развитие программистов.
Например, поддержка SSL/TLS, реализация протокола HTTP, реализация WebSockets и Google Protocol Buffers и т. д. показывают, что netty обладает мощными возможностями приложения в различных аспектах и сценариях.
Суммировать
Netty состоит из трех основных компонентов: буфера, канала и модели событий.Поняв, как эти три основных компонента работают друг с другом, нетрудно понять расширенные функции, построенные на netty.
Примеры этой статьи могут относиться к:learn-netty4
Эта статья была включена вWoohoo.Floyd Press.com/03-Netty-AR…
Самая популярная интерпретация, самая глубокая галантерея, самые краткие уроки и множество трюков, о которых вы не знаете, ждут вас!
Добро пожаловать, чтобы обратить внимание на мой официальный аккаунт: «Программируйте эти вещи», разбирайтесь в технологиях, лучше поймите себя!