Что лучше для локальных IPC, очередей сообщений POSIX (mqueues) или доменных (локальных) сокетов Unix?

Лучше использовать очереди сообщений POSIX или доменные сокеты Unix для локальной связи IPC?

Я работал с Unix-сокетами между машинами (не доменами), и я помню, что создание и разрыв соединения приводили к тому, что сокеты задерживались некоторое время, прежде чем они наконец исчезли. Более того, если вы хотели «надежного» обмена, вам нужно было использовать TCP или разработать приложение для возврата ACK. Я не уверен, если это также относится к сокетам домена Unix, хотя.

В моем текущем проекте нам нужен локальный IPC. Моей первой реакцией было использование POSIX MQueues, так как я использовал их раньше для локальных сообщений. Однако сотрудник предлагает вместо этого использовать доменные сокеты Unix.

Одно лучше другого или дело в программировании? Или, возможно, это зависит от создаваемого приложения?

В целом, приложение, над которым мы работаем, следует модели клиент / сервер. Клиенты отправляют сообщения на сервер, чтобы «сделать что-то». Тем не менее, клиент не ждет ответа «все готово» - хотя он хочет знать, был ли получен запрос или нет.

Основная логика для отправляющей стороны:

connect to server
send request
note if the send worked or not
disconnect from server

На одном сервере могут быть сотни клиентов.

Мы работаем в системе SMP (4-8 ядер) под управлением ОС Linux.

Заранее спасибо.

 karlphillip23 сент. 2010 г., 01:32
Я скажу ... дбус!

Ответы на вопрос(3)

Решение Вопроса

TIME_WAIT-подобный статус, так как это время ожидания используется в случае, если паразитные пакеты от соединения все еще блуждают по Интернету. Концерн не применяется на местном уровне.

Доменные сокеты UNIX могут бытьSOCK_STREAM (например, TCP) илиSOCK_DGRAM (например, UDP), с дополнительной гарантией, что сокеты дейтаграмм домена UNIX надежны и не переупорядочивают дейтаграммы.

Вам все еще понадобится какой-то ACK (вы делаете даже с TCP), если вы хотите бытьопределенный что ваше другое приложение прочитало отправленное вами сообщение; в конце концов, даже еслиsend() Возможно, он потерпел крах до того, как успел обработать сообщение. (Это относится и к очередям сообщений - чтобы быть полностью уверенным, что сообщение не будет потеряно, приложение-получатель должно записать запрос в журнал, сбросить его на диск и затем отправить подтверждение).

Я согласен, что выбор, по сути, является вопросом программирования.

хотя бы для их сортировки данных и RPC-подобного интерфейса (как синхронного, так и асинхронного). Он использует доменные сокеты изначально и действительно хорошо работает после начальной кривой обучения.

возможно, это зависит от создаваемого приложения?

У очередей сообщений SysV по сравнению с сокетами датаграмм домена UNIX есть основные различия, о которых я знаю:

Вы можетеpoll() сокет, но вы не можете очередь сообщений.

Очередь сообщений является глобальной и может (и обычно требует) некоторого административного вмешательства: очистка старых зависших ресурсов SysV является одной из многих ежедневных процедур sysadmin. Хотя семантика домена UNIX намного проще, и приложения могут поддерживать его полностью внутренне без участия системного администратора.

(?) Очередь сообщений является постоянной, в ней могут храниться сообщения старых сеансов. (Не могу вспомнить этот бит точно, но IIRC, что происходило со мной не раз).

Глядя наman msgrcv Я не вижу аналога сокетовMSG_PEEK, Редко нужно, но иногда оказывается весьма кстати.

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

Как и для всех ресурсов SysV, их управление является основным PITA. Если вы разрешите системе определять идентификатор очереди сообщений, вам придется позаботиться о том, чтобы правильно делиться им с другими приложениями. (И вы также должны как-то сказать администраторам, что идентификатор должен быть удален в конце концов). Если вы разрешите настроить ключ для очереди сообщений, то у вас могут возникнуть тривиальные проблемы: идентификатор уже используется каким-либо приложением или является остатком предыдущего запуска. (Видеть, что серверы перезагружаются только потому, что у них заканчиваются ресурсы SysV, довольно часто).

В общем, я избегаю ресурсов SysV, когда это возможно: отсутствиеpoll() поддержка в наиболее распространенных обстоятельствах является нарушителем.

Тем не менее, клиент не ждет ответа «все готово» - хотя он хочет знать, был ли получен запрос или нет.

Это общая дилемма транзакционной обработки. Общий ответ (как в RDBMS) вы не можете, и после прерывания связи (сбой или что-то еще) приложение должно проверить себя, был ли запрос уже обработан или нет.

Из этого я могу сказать, что, вероятно, TCP был бы лучшим выбором. Клиент отправляет запрос и объявляет его завершенным, только когда получает положительный ответ от сервера. Сервер, если он не способен отправить ответ клиенту, должен откатить транзакцию.

 nos23 сент. 2010 г., 12:03
Хотя в Linux дескриптор очереди сообщений posix на самом деле является файловым дескриптором и поддерживает выбор / опрос. Я не уверен насчет очередей сообщений sysv.
 Dummy0000123 сент. 2010 г., 12:08
@nos: ссылка? ты не смешиваешь это с AIX? POSIX не описывает это истарая ссылка на Linux я знаю также говорит нет.
 Dummy0000123 сент. 2010 г., 12:44
@nos: спасибо. Это объясняет, почему есть два интерфейса.mq_* функции этоновый интерфейс POSIX: "Впервые выпущено в выпуске 5. Включено для согласования с POSIX Realtime Extension." И все же POSIX не определяет использованиеpoll() с "дескрипторами очереди сообщений" ... :(
 nos23 сент. 2010 г., 12:29
man mq_overview, «В Linux дескриптор очереди сообщений на самом деле является файловым дескриптором, и его можно отслеживать с помощью select (2), poll (2) или epoll (7). Это не переносимо». Как уже упоминалось, это очереди сообщений posix, я не уверен, что очереди сообщений sysv работают таким образом, если они это делают, то это изменилось за последние годы.

Ваш ответ на вопрос