Полное руководство по Netty

Автор: Дзен и искусство компьютерного программирования

1. Введение

: Netty — это платформа асинхронных сетевых приложений, управляемая событиями, которая обеспечивает поддержку расширенных уровней приложений в наборе протоколов TCP/IP (таких как HTTP, FTP, WebSocket и т. д.). Цель его разработки — предоставить простую для понимания и быстро развиваемую среду сетевых приложений. Netty — это проект с открытым исходным кодом, размещенный на Github по адресу: https://github.com/netty/netty .

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

Прочитав эту книгу, читатели смогут освоить:

  1. Функциональные особенности Netty;
  2. Событийно-ориентированная модель на основе NIO и Epoll;
  3. Шаблон архитектуры конвейера;
  4. Функции и использование компонентов Java NIO Selector, Channel и Buffer;
  5. Высокопроизводительный механизм реализации Netty (включая модель потоков Reactor, управление пулом памяти, технологию нулевого копирования, оптимизированные настройки параметров и т. д.).
  6. Навыки проектирования системы (например, шаблон проектирования микроядра, шаблон проектирования RESTful API).

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

2. Понятия, термины, понятия

2.1 Обзор Netty

2.1.1 Асинхронная неблокирующая библиотека ввода-вывода

Netty — это асинхронная неблокирующая библиотека ввода-вывода. Он обеспечивает расширенную поддержку дизайна и приложений для набора протоколов TCP/IP. В основном он отвечает за следующие аспекты:

  1. Предоставляет среду асинхронных сетевых приложений, управляемых событиями, для разработки высокопроизводительных сетевых приложений с высоким уровнем параллелизма.
  2. Обеспечивает реализацию классов и интерфейсов, таких как SocketChannel, ServerSocketChannel, Selector, ByteBuffer и т. д., в компонентах Java NIO, благодаря чему программный интерфейс ввода-вывода JDK соответствует требованиям Netty.
  3. Предоставляет разработчикам технологию нулевого копирования.
  4. Предоставляет разработчикам возможности управления сокетами TCP/UDP, файлами, подключениями к базам данных и другими ресурсами.
  5. Обеспечивает масштабируемость и высокую производительность для приложений реального времени с большими объемами данных.

Вообще говоря, Netty — это базовая среда для создания настоящей программы «асинхронного ввода-вывода». Он может безопасно и эффективно обрабатывать сложные запросы связи и ввода-вывода в многопоточной среде без использования блокировок или условий гонки. Архитектура Netty отличается высокой гибкостью, масштабируемостью и может легко удовлетворить потребности различных сценариев сетевой передачи.

2.1.2 Структура модуля Netty

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

Netty Core : основной модуль Netty, включая сетевые вызовы, кодеки, буферы, события и определения интерфейса обработчика. Этот модуль использует сторонние библиотеки, такие как ReflectASM, Guava и т. д.

Netty Codec : модуль кодека Netty, включая поддержку кодеков двоичных и текстовых данных, таких как Protobuf, Thrift, JSON, XML и т. д.

Netty Transport : транспортный модуль Netty, включающий универсальный TCP/UDP-клиент, сервер, а также поддержку SSL/TLS и HTTP-прокси.

HTTP-клиент Netty : асинхронный клиентский модуль HTTP Netty реализует протоколы HTTP/1.x, HTTP/2 и поддерживает синхронные, асинхронные и управляемые событиями API.

Netty WebSocket : клиентский и серверный модуль WebSocket для Netty.

Netty AIO : модуль реализации асинхронного ввода-вывода Netty может использовать AIO для доступа к базовым ресурсам, таким как файловые системы, сетевые карты, клавиатуры и мыши, эффективно повышая производительность.

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

Netty Tools : модуль инструментов Netty, включающий инструменты отладки, инструменты мониторинга, инструменты безопасности и т. д.

2.2 Терминология

2.2.1 Канал

В Netty Channel представляет собой абстракцию сетевого интерфейса базовой операционной системы. Он содержит двусторонний буфер для отправки и получения данных. Он отвечает за буферизацию данных потока байтов и выполнение специальной обработки (например, сжатие, шифрование, и т. д.), когда это необходимо. Целью разработки интерфейса канала является следующее:

  1. Отделите базовую реализацию и скройте различия между различными протоколами передачи.
  2. Вы можете зарегистрировать несколько прослушивателей событий в экземпляре канала, с помощью которых вы сможете получать такую ​​​​информацию, как изменения состояния канала и завершение чтения и записи данных.
  3. Поддерживает асинхронные неблокирующие операции ввода-вывода, позволяющие избежать переключения потоков и повысить пропускную способность.

Интерфейс Channel состоит из двух основных методов: read() и write(). Когда поток инициирует операцию записи, Netty немедленно вернется, не дожидаясь завершения фактической записи, а затем уведомит пользователя о результате записи. Аналогично, когда поток инициирует операцию чтения, Netty не будет ждать, пока будут прочитаны фактические данные, а вернет их пользователю сразу после чтения доступных байтов. Этот асинхронный, неблокирующий дизайн может эффективно улучшить возможности параллельной обработки приложений.

2.2.2 Буфер

Буфер — это контейнер байтов, предоставляемый Netty и используемый для хранения потоков байтов, которые будут отправлены или получены. Помимо байтовых массивов, также можно использовать другие формы контейнеров, такие как Heapbuffer, Direct buffer и т. д. Эти контейнеры абстрактны, и пользователи не могут получить к ним прямой доступ. Netty предоставляет два типа буферов, как показано на рисунке ниже:

Heapbuffer — это буфер, выделенный непосредственно в куче. Его преимуществом является то, что он занимает фиксированное пространство и он очень эффективен. Его недостатком является то, что он требует сборки мусора и может легко вызвать фрагментацию памяти. Поэтому рекомендуется использовать его только локально.

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

Буфер Netty очень удобен в использовании: если вы объявите соответствующие переменные, а затем запишете данные в буфер, их можно будет передать в удаленный канал. Если данные необходимо прочитать, прочитайте их из канала в буфер. Разные эффекты могут быть достигнуты с помощью разных реализаций Buffer. Например, heap Buffer может реализовывать кэширование, а прямой Buffer может реализовывать нулевое копирование.

2.2.3 Обработчик

Обработчик является одним из основных компонентов Netty и используется для обработки всех событий ввода-вывода. Логика приложения Netty должна быть реализована через Handler. Handler — это интерфейс, предоставляемый Netty. Цель его разработки следующая:

  1. Разбейте сложную бизнес-логику на несколько независимых обработчиков, чтобы уменьшить связанность.
  2. Благодаря гибкой комбинации обработчиков можно гибко построить канал сетевой обработки приложения.
  3. Поддерживает делегирование обработки запросов различным реализациям обработчика через единый интерфейс.

Netty предоставляет четыре типа обработчиков:

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

  2. ChannelInboundHandler: этот обработчик обрабатывает входящие данные, полученные из удаленного канала.

  3. ChannelOutboundHandler: этот обработчик обрабатывает процесс записи исходящих данных из удаленного канала.

  4. ChannelDuplexHandler: это специальный обработчик, который обрабатывает как входящие, так и исходящие данные.

Жизненный цикл Handler показан на рисунке ниже:

Каждый разработчик Handler может наследовать соответствующий HandlerAdapter для получения реализации метода по умолчанию. Но обычно разработчики пишут свои собственные классы реализации Handler, а затем вызывают их через HandlerChain.

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

2.2.4 Цикл событий

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

EventLoop имеет два важных метода: run() и start(). Метод run() является точкой входа для запуска цикла обработки событий, который выполняется в текущем потоке до тех пор, пока EventLoop не завершится. Метод start() запускает EventLoop в новом потоке и автоматически запускает селектор.

Концепция дизайна Netty заключается в привязке канала к EventLoop. Следовательно, все операции ввода-вывода канала должны обрабатываться связанным EventLoop и не могут пересекать границы потоков. Следовательно, чтобы удовлетворить этому требованию, Netty использует поточно-безопасную конструкцию, и все операции должны выполняться в одном потоке. Другими словами, все операции с участием Selector могут выполняться только в одном потоке.

Guess you like

Origin blog.csdn.net/universsky2015/article/details/133504615