Введение

Средства межпроцессного взаимодействия в разработке программного обеспечения

В информатике очереди сообщений и почтовые ящики — это компоненты программного обеспечения, обычно используемые для межпроцессного взаимодействия (IPC) или для взаимодействия между потоками в рамках одного процесса. Они используют очередь для обмена сообщениями – передачи управления или содержимого. Системы групповой коммуникации предоставляют схожую функциональность. Парадигма очереди сообщений является близкой родственницей шаблона «издатель-подписчик» и обычно является частью более крупной системы промежуточного программного обеспечения, ориентированной на сообщения. Большинство систем обмена сообщениями поддерживают как модель «издатель-подписчик», так и модель очереди сообщений в своем API, например, Java Message Service (JMS).

Полномочия и право собственности

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

Передача

Многие реализации очередей сообщений функционируют внутри операционной системы или приложения. Такие очереди существуют исключительно для нужд данной системы. Другие реализации обеспечивают передачу сообщений между различными компьютерными системами, потенциально соединяя несколько приложений и операционных систем. Эти системы обмена сообщениями обычно предоставляют механизмы отказоустойчивости, чтобы гарантировать, что сообщения не будут "потеряны" в случае сбоя системы. Примеры коммерческих реализаций такого программного обеспечения для обмена сообщениями (также известного как промежуточное программное обеспечение, ориентированное на сообщения) включают IBM MQ (ранее MQ Series) и Oracle Advanced Queuing (AQ). Существует стандарт Java под названием Java Message Service, который имеет несколько проприетарных и свободно распространяемых программных реализаций. Операционные системы реального времени (RTOS), такие как VxWorks и QNX, рекомендуют использовать очереди сообщений в качестве основного механизма межпроцессного или межпоточного взаимодействия. Это может привести к интеграции передачи сообщений и планирования задач процессора. Ранние примеры коммерческих RTOS, которые поддерживали использование очередей сообщений для межпоточного взаимодействия, также включают VRTX и pSOS+, обе из которых появились в начале 1980-х годов. Язык программирования Erlang использует процессы для обеспечения параллелизма; эти процессы общаются асинхронно посредством очереди сообщений.

Владение

Программное обеспечение для очередей сообщений может быть проприетарным, с открытым исходным кодом или представлять собой их комбинацию. Оно может быть развернуто как локально, на собственных серверах, так и на внешних облачных серверах (сервис очередей сообщений). Проприетарные решения имеют самую долгую историю и включают продукты, появившиеся с момента зарождения технологий очередей сообщений, такие как IBM MQ, а также решения, привязанные к конкретным операционным системам, например, Microsoft Message Queuing (MSMQ). Облачные провайдеры также предлагают свои проприетарные решения, такие как Amazon Simple Queue Service (SQS), StormMQ, Solace и IBM MQ. К решениям с открытым исходным кодом относятся системы обмена сообщениями Apache ActiveMQ, Apache Kafka, Apache Qpid, Apache RocketMQ, Enduro/X, JBoss Messaging, JORAM, RabbitMQ, Sun Open Message Queue и Tarantool. Примеры поставщиков промежуточного программного обеспечения для обмена сообщениями, использующих аппаратную реализацию, включают Solace, Apigee и IBM MQ.

Синхронный и асинхронный

Многие из наиболее известных протоколов связи, используемых в настоящее время, работают синхронно. Протокол HTTP, используемый в World Wide Web и в веб-сервисах, является очевидным примером, когда пользователь отправляет запрос на веб-страницу и затем ждет ответа. Однако существуют сценарии, в которых синхронное поведение не подходит. Например, AJAX (асинхронный JavaScript и XML) может использоваться для асинхронной отправки текстовых, JSON или XML-сообщений для обновления части веб-страницы более актуальной информацией. Google использует этот подход в своей функции Google Suggest, которая отправляет частично введенные запросы пользователя на серверы Google и возвращает список возможных полных запросов, которые могут заинтересовать пользователя в процессе ввода. Этот список асинхронно обновляется по мере ввода текста пользователем. Другие примеры асинхронной работы встречаются в системах уведомления о событиях и в системах публикации/подписки. Приложению может потребоваться уведомить другое о наступлении события, но не нужно ждать ответа. В системах публикации/подписки приложение "публикует" информацию для чтения любому количеству клиентов. В обоих вышеуказанных примерах нецелесообразно, чтобы отправитель информации должен был ждать, если, например, один из получателей вышел из строя. Приложения не обязаны быть исключительно синхронными или асинхронными. Интерактивное приложение может немедленно реагировать на определенные части запроса (например, сообщать клиенту о принятии запроса на продажу и подтверждать резервирование товара), но может помещать другие части (например, завершение расчета стоимости, передачу данных в центральную систему бухгалтерского учета и обращение к различным другим сервисам) в очередь для выполнения позднее. Во всех подобных ситуациях наличие подсистемы, выполняющей постановку сообщений в очередь (или, альтернативно, системы широковещательной рассылки сообщений), может помочь улучшить поведение всей системы.

Реализация в UNIX

В UNIX существует две распространенные реализации очередей сообщений. Одна является частью API SYS V, а другая – частью POSIX.

SYS V

UNIX SYS V реализует передачу сообщений, поддерживая массив связанных списков в качестве очередей сообщений. Каждая очередь сообщений идентифицируется своим индексом в массиве и имеет уникальный дескриптор. Один и тот же индекс может иметь несколько дескрипторов. UNIX предоставляет стандартные функции для доступа к механизму передачи сообщений. `msgget` – этот системный вызов принимает ключ в качестве аргумента и возвращает дескриптор очереди, соответствующей этому ключу, если она существует. Если очередь не существует, и установлен флаг `IPC_CREAT`, создается новая очередь сообщений с указанным ключом и возвращается ее дескриптор. `msgrcv` – используется для получения сообщения из заданной очереди, идентифицируемой ее дескриптором. Процесс, вызывающий функцию, должен иметь права на чтение этой очереди. Существуют два режима работы: блокирующий прием ставит процесс в состояние ожидания, если в очереди нет сообщений запрошенного типа. Он ожидает, пока в очередь не будет помещено новое сообщение, после чего возобновляет работу и проверяет наличие сообщения. Неблокирующий прием немедленно возвращает управление вызывающему процессу, сообщая об ошибке. `msgctl` – используется для изменения параметров очереди сообщений, таких как владелец. Наиболее важной функцией является удаление очереди сообщений путем передачи флага `IPC_RMID`. Очередь сообщений может быть удалена только ее создателем, владельцем или суперпользователем.

POSIX

API очереди сообщений POSIX.1 2001 является более поздним из двух API очереди сообщений UNIX. Он отличается от API SYS V, но предоставляет схожую функциональность. Обзор очередей сообщений POSIX представлен на странице руководства man mq_overview(7).

Графические пользовательские интерфейсы

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