文章首发于51CTO技术栈公众号
作者 陈彩华
文章转载交流请联系 caison@aliyun.com
С развитием Интернета традиционная модель блокирующей серверной архитектуры бессильна перед большим количеством пользователей с большим числом одновременных служб, поэтому цель этой статьи — предоставить вам полезный обзор и сравнение моделей сетевых служб с раскрыть дизайн и тайну создания высокопроизводительных сетевых архитектур
1 Сервер обрабатывает сетевые запросы
Сначала посмотрим на типичный процесс обработки сервером сетевых запросов:
Видно, что основные этапы обработки включают в себя:
- 1. Получить данные запроса Клиент устанавливает соединение с сервером для выдачи запроса, и сервер принимает запрос (1-3)
- 2. Создайте ответ Когда сервер завершает получение запроса и обрабатывает запрос клиента в пользовательском пространстве, пока построение ответа не будет завершено (4)
- 3. Возврат данных Сервер отправляет построенный ответ обратно клиенту через сетевой ввод-вывод в пространстве ядра (5-7)
При разработке модели параллелизма на стороне сервера необходимо учитывать два ключевых момента:
- Как сервер управляет соединениями, получает входные данные
- Как сервер обрабатывает запрос
Вышеупомянутые два ключевых момента в конечном итоге связаны с моделью ввода-вывода и моделью потока (процесса) операционной системы.Эти две модели подробно описаны ниже.
Модель с 2 входами/выходами
2.1 Теория концепции
Прежде чем представить модель ввода-вывода операционной системы, давайте разберемся с несколькими понятиями:
- Блокирующие и неблокирующие вызовы
- Блокирующий вызов означает, что текущий поток приостанавливается до тех пор, пока не будет возвращен результат вызова. Вызывающий поток не возвращается, пока не получит результат
- Неблокирующий вызов означает, что вызов не будет блокировать текущий поток до тех пор, пока результат не будет немедленно доступен.
Самая большая разница между ними заключается в том, ждал ли вызывающий объект в течение периода с момента, когда вызываемый объект получает запрос, до момента, когда возвращается результат. Блокировка означает, что вызывающий абонент ждал и больше ничего не делал. Неблокирующий означает, что вызывающий абонент сначала занят другими делами.
-
Синхронная и асинхронная обработка
- Синхронная обработка означает, что вызываемый объект возвращает окончательный результат вызывающему объекту после того, как вызываемый объект получит окончательный результат.
- Асинхронная обработка означает, что вызываемый объект сначала возвращает ответ, затем вычисляет результат вызова, а затем уведомляет и возвращает вызывающему объекту после вычисления окончательного результата.
-
Разница между блокирующим, неблокирующим, синхронным и асинхронным Блокирующие, неблокирующие, синхронные, асинхронные на самом деле нацелены на разные объекты:Блокирующий, неблокирующий объект обсуждения является вызывающим абонентом Синхронный и асинхронный объект обсуждения — это вызываемый объект.
-
функция recvfrom функция recvfrom (получение данных через сокет), здесь это рассматривается как системный вызов
Операция ввода обычно состоит из двух отдельных фаз.
- дождитесь готовности данных
- Копировать данные из ядра в процесс
Для операций ввода в сокет первый шаг обычно включает ожидание поступления данных из сети. Когда приходит ожидающий пакет, он копируется в некоторый буфер в ядре. Второй шаг — копирование данных из буфера ядра в буфер процесса приложения.
Когда фактическое приложение завершает два вышеуказанных шага в системном вызове, метод вызова является блокирующим и неблокирующим, а операционная система обрабатывает запрос приложения в различных синхронных и асинхронных обработках. См. **"Сетевое программирование UNIX, том 1. "* *, можно разделить на 5 моделей ввода/вывода
2.2 Модель блокирующего ввода-вывода (блокирующий ввод-вывод)
ВведениеВ модели блокирующего ввода-вывода приложение не может вызывать recvfrom до тех пор, пока оно не вернется с готовой дейтаграммой.После успешного завершения recvfrom процесс приложения начинает обрабатывать дейтаграмму.
сравнениеЧеловек ловит рыбу, и когда рыба не на крючке, он сидит на берегу и ждет
преимуществоПрограмма проста, процесс/поток зависает во время блокировки и ожидания данных, и в основном не занимает ресурсы процессора
недостатокКаждое соединение должно обрабатываться независимым процессом/потоком.Когда количество одновременных запросов велико, для поддержания программы требуются большие затраты памяти и переключения потоков.Эта модель редко используется в реальном производстве.
2.3 Модель неблокирующего ввода-вывода (неблокирующий ввод-вывод)
ВведениеВ модели неблокирующего ввода-вывода, когда приложение устанавливает сокет в неблокирующий режим, оно сообщает ядру, что если запрошенная операция ввода-вывода не может быть завершена, не переводите процесс в спящий режим, а возвращайте ошибку. Приложение основано на вводе-выводе.Операционная функция /O будет постоянно опрашивать, готовы ли данные, если нет, продолжать опрашивать, пока данные не будут готовы
сравнениеИграйте со своим мобильным телефоном во время рыбалки, через некоторое время снова проверьте, не попалась ли рыба на крючок, и быстро потяните удочку, если она есть.
преимуществоОн не будет блокировать ожидающий процесс данных в ядре.Каждый инициированный запрос ввода-вывода может быть немедленно возвращен без блокировки и ожидания, а производительность в реальном времени лучше.
недостатокОпрос будет постоянно запрашивать ядро, что будет занимать много процессорного времени, а использование системных ресурсов низкое, поэтому обычно веб-серверы не используют эту модель ввода-вывода.
2.4 Модель мультиплексирования ввода-вывода (мультиплексирование ввода-вывода)
ВведениеВ модели мультиплексирования ввода-вывода будет использоваться функция select или poll или функция epoll (поддерживается ядром после Linux 2.6).Эти две функции также будут блокировать процесс, но они отличаются от блокировки ввода-вывода. эти две функции могут блокировать несколько операций ввода-вывода одновременно и могут обнаруживать функции ввода-вывода нескольких операций чтения и нескольких операций записи одновременно, до тех пор, пока данные не станут доступными для чтения или записи, функция ввода-вывода фактически вызывается. /O операционная функция
сравнениеЯ положил кучу удочек и продолжал охранять кучу удочек на берегу, пока рыба не клюнула
преимуществоМожет ожидать готовности нескольких дескрипторов одновременно на основе блокирующего объекта вместо использования нескольких потоков (один поток на дескриптор файла), что может значительно сэкономить системные ресурсы.
недостатокКогда количество подключений невелико, эффективность ниже, чем у многопоточной модели + блокирующий ввод-вывод, а задержка может быть больше, поскольку для обработки одного подключения требуется 2 системных вызова, и время, затрачиваемое на это, увеличится.
2.5 Модель ввода-вывода, управляемого сигналом (сигнально-управляемый ввод-вывод)
ВведениеВ модели ввода-вывода, управляемого сигналом, приложение использует сокеты для ввода-вывода, управляемого сигналом, и устанавливает функцию обработчика сигнала, и процесс продолжает работать без блокировки. Когда данные будут готовы, процесс получит сигнал SIGIO, и функция операции ввода-вывода может быть вызвана в функции обработки сигнала для обработки данных.
сравнениеК удочке прикреплен колокольчик, когда он звенит, вы знаете, что рыба попала на крючок, а затем можете сосредоточиться на игре с мобильным телефоном.
преимуществоПотоки не блокируются во время ожидания данных, что может улучшить использование ресурсов.
недостаток
- Сигнальный ввод-вывод может не уведомляться из-за переполнения очереди сигналов во время большого количества операций ввода-вывода.
- Однако ввод-вывод, управляемый сигналами, полезен для работы с UDP-сокетами, т. е. такая сигнализация означает, что дейтаграмма поступает или возвращается асинхронная ошибка. Однако для TCP метод ввода-вывода, управляемый сигналом, почти бесполезен, потому что есть много условий, приводящих к такого рода уведомлениям, каждое из которых будет потреблять много ресурсов для оценки, и преимущества по сравнению с предыдущие методы.
2.6 Модель асинхронного ввода-вывода (асинхронный ввод-вывод)
ВведениеВ соответствии со спецификацией POSIX приложение приказывает ядру инициировать операцию, а ядро уведомляет приложение о завершении всей операции (включая копирование данных из ядра в буферы приложения). Основное различие между этой моделью и моделью, управляемой сигналами, заключается в том, что в управляемом сигналом вводе-выводе ядро информирует приложение, когда начинать операцию ввода-вывода, в то время как в модели асинхронного ввода-вывода ядро информирует приложение. когда происходит операция ввода/вывода.
преимуществоАсинхронный ввод-вывод использует преимущества функций прямого доступа к памяти, позволяя операциям ввода-вывода перекрывать вычисления.
недостатокЧтобы реализовать настоящий асинхронный ввод-вывод, операционная система должна проделать большую работу. В настоящее время настоящий асинхронный ввод-вывод реализуется через IOCP под Windows, а в системе Linux была введена Linux 2.6. В настоящее время AIO не идеален. Поэтому режим модели мультиплексирования ввода-вывода используется для реализации сетевого программирования с высокой степенью параллелизма под Linux.основной
2.5 Обзор 5 моделей ввода/вывода
Как видно из приведенного выше рисунка, видно, что чем дальше назад, тем меньше блокировки, и теоретическая эффективность также оптимальна. Среди пяти моделей ввода/вывода первые четыре относятся к синхронному вводу/выводу, поскольку реальная операция ввода/вывода (recvfrom) блокирует процесс/поток, и только асинхронная модель ввода/вывода совместима с асинхронным вводом/выводом. O определено POSIX.
3-х ниточная модель
После описания того, как сервер управляет соединениями и получает входные данные на основе модели ввода-вывода, далее описывается, как сервер обрабатывает запросы на основе модели процесса/потока.
Стоит отметить, что конкретный выбор потока или процесса больше связан с платформой и языком программирования, например, язык C может использовать потоки и процессы (например, Nginx использует процессы, Memcached использует потоки), а язык Java вообще использует threads (такие как Netty), для удобства описания, thread используется для описания процесса ниже
3.1 Традиционная сервисная модель блокирующего ввода-вывода
Функции
- Получить входные данные, используя блокирующую модель ввода-вывода
- Для каждого соединения требуется независимый поток для завершения полной операции ввода данных, бизнес-обработки и возврата данных.
Существует проблема
- Когда количество параллелизма велико, необходимо создать большое количество потоков для обработки соединения, что требует большого количества системных ресурсов.
- После установления соединения, если у текущего потока нет данных для чтения в данный момент, поток будет заблокирован в операции чтения, что приведет к пустой трате ресурсов потока.
3.2 Реакторный режим
Для двух недостатков традиционной модели услуг блокирующего ввода-вывода наиболее распространенными решениями являются следующие:
- В соответствии с моделью мультиплексирования ввода-вывода несколько подключений совместно используют блокирующий объект, и приложению нужно ожидать только один блокирующий объект, не блокируя и не ожидая всех подключений. Когда у соединения есть новые данные для обработки, операционная система уведомляет приложение, поток возвращается из заблокированного состояния и начинает бизнес-обработку.
- Повторное использование ресурсов потоков на основе пула потоков, больше нет необходимости создавать поток для каждого соединения и назначать задачи бизнес-обработки после завершения соединения потоку для обработки.Один поток может обрабатывать бизнес нескольких соединений.
Мультиплексирование ввода-вывода в сочетании с пулом потоков — это основная идея дизайна режима Reactor.
Реакторный режим, относится к управляемой событиями модели обработки запросов на обслуживание, которые одновременно передаются сервисному процессору через один или несколько входов. Серверная программа обрабатывает входящие множественные запросы и синхронно отправляет их в потоки обработки, соответствующие запросам.Режим Reactor также называется режимом Dispatcher, то есть в нем больше событий мультиплексирования ввода-вывода и унифицированного мониторинга, и они распределяются после получение событий (диспетчеризация определенного процесса), что является одной из необходимых технологий для написания высокопроизводительных сетевых серверов
В шаблоне Reactor есть 2 ключевых компонента:
-
Реактор Reactor работает в отдельном потоке и отвечает за прослушивание и отправку событий, отправку соответствующим обработчикам для реагирования на события ввода-вывода. Это как телефонный оператор для компании, он принимает звонки от клиентов и перенаправляет линию на соответствующий контакт
-
Обработчики Обработчик выполняет фактическое событие, которое должно быть выполнено событием ввода-вывода, аналогично фактическому сотруднику в компании, с которым хочет поговорить клиент. Reactor реагирует на события ввода-вывода, отправляя соответствующие обработчики, которые выполняют неблокирующие операции.
Существует 3 типичных реализации в зависимости от количества Reactors и количества потоков обработки пула ресурсов:
- Одиночный реактор Однопоточный
- Многопоточность с одним реактором
- Многопоточность Master-Slave Reactor
Три реализации подробно описаны ниже.
3.2.1 Однопоточный реактор с одним потоком
Среди них выделите фронтМодель мультиплексирования ввода/выводаПредставленный стандартный API сетевого программирования позволяет реализовать возможность отслеживания приложением нескольких запросов на подключение через блокирующий объект.Схемы других схем аналогичны
описание плана
- Объект Reactor отслеживает события запроса клиента через выбор и распределяет их через диспетчеризацию после получения события.
- Если это событие запроса на подключение, Acceptor обрабатывает запрос на подключение посредством принятия, а затем создает объект Handler для обработки последующей бизнес-обработки после завершения подключения.
- Если это не событие установления соединения, Reactor отправит соответствующий обработчик для вызова соединения для ответа.
- Обработчик завершит полный бизнес-процесс чтения-> бизнес-обработки-> отправки
преимуществоМодель проста, нет проблем с многопоточностью, обменом процессами и конкуренцией, и все выполняется в одном потоке.
недостаток
- Проблема с производительностью: существует только один поток, и производительность многоядерного процессора не может быть полностью использована. Когда обработчик обрабатывает бизнес в соединении, весь процесс не может обрабатывать другие события соединения, что может легко привести к узким местам производительности.
- Проблема надежности: поток неожиданно убегает или входит в бесконечный цикл, что приведет к недоступности всего системного коммуникационного модуля, неспособности получать и обрабатывать внешние сообщения, что приводит к сбою узла.
сцены, которые будут использоватьсяКоличество клиентов ограничено, а бизнес-обработка выполняется очень быстро, например, Redis, временная сложность бизнес-обработки составляет O(1)
3.2.2 Многопоточность с одним реактором
описание плана
- Объект Reactor отслеживает события запроса клиента через выбор и распределяет их через диспетчеризацию после получения события.
- Если это событие запроса на подключение, Acceptor обрабатывает запрос на подключение через accept, а затем создает объект Handler для обработки последующих событий после завершения подключения.
- Если это не событие установления соединения, Reactor отправит соответствующий обработчик для вызова соединения для ответа.
- Обработчик отвечает только за реагирование на события и не выполняет конкретную бизнес-обработку.После чтения данных через чтение они будут распределены в следующий пул рабочих потоков для бизнес-обработки.
- Пул рабочих потоков будет выделять независимые потоки для выполнения реальной бизнес-обработки.Как отправить результаты ответа обработчику для обработки
- После того, как обработчик получает результат ответа, он возвращает результат ответа клиенту через команду отправки.
преимуществоМожет в полной мере использовать вычислительную мощность многоядерного процессора
недостаток
- Многопоточный обмен данными и доступ к ним более сложны
- Reactor отвечает за мониторинг и реагирование на все события, работая в одном потоке, и он легко может стать узким местом в производительности в сценариях с высокой степенью параллелизма.
3.2.3 Многопоточность Master-Slave Reactor
В многопоточной модели с одним Reactor Reactor работает в одном потоке, и он легко может стать узким местом производительности в сценариях с высокой степенью параллелизма, поэтому Reactor можно запускать в нескольких потоках.
описание плана
- Объект MainReactor основного потока Reactor отслеживает установление событий соединения через выбор, получает событие через Acceptor после получения события и обрабатывает событие установления соединения.
- После того, как Accepto обработает событие установления соединения, MainReactor назначает соединение с подпотоком Reactor SubReactor для обработки.
- SubReactor добавляет соединение в очередь соединений для прослушивания и создает обработчик для обработки различных событий соединения.
- Когда происходит новое событие, SubReactor вызовет обработчик, соответствующий соединению, чтобы ответить
- После того, как обработчик прочитает данные через чтение, они будут распределены в следующий пул рабочих потоков для бизнес-обработки.
- Пул рабочих потоков будет выделять независимые потоки для выполнения реальной бизнес-обработки.Как отправить результаты ответа обработчику для обработки
- После того, как обработчик получает результат ответа, он возвращает результат ответа клиенту через команду отправки.
преимущество
- Взаимодействие данных между родительским потоком и дочерним потоком простое, а обязанности понятны: родительскому потоку нужно только получать новые соединения, а дочерний поток выполняет последующую бизнес-обработку.
- Взаимодействие данных между родительским потоком и дочерним потоком простое.Основному потоку Reactor нужно только передать новое соединение дочернему потоку, а дочернему потоку не нужно возвращать данные.
Эта модель широко используется во многих проектах, включая многопроцессорную модель Nginx master-slave Reactor, многопоточность Memcached master-slave, поддержку многопоточной модели Netty master-slave.
3.2.4 Резюме
Эти 3 режима можно понять по аналогии: Рестораны часто нанимают администраторов для приветствия клиентов. Когда клиенты сидят, официант обслуживает исключительно стол.
- Одиночный реактор Однопоточный Администратор и официант — одно и то же лицо, обслуживающее клиентов на протяжении всего процесса.
- Многопоточность с одним реактором 1 администратор, несколько официантов, администратор отвечает только за прием
- Многопоточность Master-Slave Reactor Несколько администраторов, несколько официантов
Реакторный режим имеет следующие преимущества:
- Ответ быстрый и не должен быть заблокирован единым временем синхронизации, хотя сам Reactor все еще синхронен.
- Программирование относительно простое, что позволяет в наибольшей степени избежать сложных проблем с многопоточностью и синхронизацией, а также избежать накладных расходов на переключение многопоточности/процесса;
- Масштабируемость, вы можете легко полностью использовать ресурсы ЦП, увеличив количество экземпляров Reactor.
- Возможность повторного использования, сама модель Reactor не имеет ничего общего с конкретной логикой обработки событий и имеет высокую степень повторного использования.
3.3 Модель проактора
В режиме Reactor Reactor ожидает события или состояния, которое может быть применено, или выполнения операции (например, дескриптор файла может быть прочитан и записан, или сокет может быть прочитан и записан), а затем событие передается предварительно зарегистрированному обработчику (функции обработчика событий) или функции обратного вызова), последняя выполняет фактические операции чтения и записи, а операции чтения и записи требуют операций синхронизации приложений, поэтому Reactor представляет собой неблокирующую синхронную сетевую модель. . Если операция ввода-вывода изменяется на асинхронную, то есть она передается операционной системе для дальнейшего повышения производительности.Это асинхронная сетевая модель Proactor.
Proactor связан с асинхронным вводом-выводом,Детальный планследующее:
- ProactorInitiator создает объекты Proactor и Handler и регистрирует Proactor и Handler в ядре через AsyOptProcessor (обработчик асинхронных операций).
- AsyOptProcessor обрабатывает запросы на регистрацию и обрабатывает операции ввода-вывода.
- Уведомить Proactor после того, как AsyOptProcessor завершит операцию ввода-вывода
- Proactor вызывает разные обработчики для бизнес-обработки в соответствии с разными типами событий.
- Обработчик завершает бизнес-обработку
Разницу между Proactor и Reactor можно увидеть: Reactor уведомляет о предварительно зарегистрированных событиях, когда происходят события (чтение и запись обрабатываются в потоке приложения); Proactor завершает операции чтения и записи на основе асинхронного ввода-вывода, когда происходят события (ядро завершена), и после завершения операции ввода-вывода процессор прикладной программы вызывается обратно для обработки бизнес-процесса.
Теоретически Proactor более эффективен, чем Reactor, а асинхронный ввод-вывод в полной мере использует DMA (прямой доступ к памяти), но имеет следующие недостатки:
- сложность программирования Разработка асинхронных приложений более сложна, поскольку инициализация события и завершение события асинхронного потока операций разделены во времени и пространстве. Приложение также может стать более сложным для отладки из-за обратного управления потоком.
- использование памяти Буфер должен поддерживаться во время операции чтения или записи, что может вызвать постоянную неопределенность, и для каждой параллельной операции требуется независимый кеш.По сравнению с режимом Reactor, прежде чем сокет будет готов для чтения или записи, не требуется открытие тайник
- Поддержка ОС Реальный асинхронный ввод-вывод реализуется через IOCP под Windows, в то время как в системе Linux была введена Linux 2.6, и асинхронный ввод-вывод в настоящее время несовершенен.
Поэтому реализация высокопараллельного сетевого программирования под Linux в основном основана на модели Reactor.
Более интересно, добро пожаловать на официальный аккаунт автора [архитектура распределенной системы]
Ссылаться на
Изучение архитектуры с нуля – Ли Юньхуа, технический эксперт Alibaba
Технология: Модель сетевого ввода-вывода Linux
Модель многопоточной сетевой службы
Блокирующий, неблокирующий, синхронный, асинхронный в IO
UNIX Network Programming Volume 1: Socket Networking API (3-е издание)
Alibaba Cloud недавно начала выдавать ваучеры, которые могут получить бесплатно как новые, так и старые пользователи. Новые зарегистрированные пользователи могут получить ваучеры на 1000 юаней, а старые пользователи могут получить ваучеры на 270 юаней.Рекомендуется всем получить копию.В любом случае, это бесплатно.Может быть, вам это понадобится в будущем? Коллекция облачных ваучеров AlibabaPromotion.aliyun.com/ваша ТМ есть/облака боятся жары…
Популярные события Специальные предложения для высокопроизводительных облачных серверов, помогающие предприятиям перейти в облако. Скидка 2–5 % на хосты уровня производительности.Promotion.aliyun.com/ваш ТМ is/act/en…