2010-09-22 3 views
19

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

Я работал с 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.

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

+0

Я скажу ... dbus! – karlphillip

ответ

5

Сокеты домена UNIX не должны «задерживаться» в статусе TIME_WAIT, так как это время ожидания используется в случае, если есть паразитные пакеты из соединения, все еще блуждающего по Интернету. Озабоченность не применяется на местном уровне.

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

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

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

4

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

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

  • вы можете poll() гнездо, но вы не можете очереди сообщений.

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

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

  • Глядя на man msgrcv Я не вижу аналога сокета MSG_PEEK. Редко требуется, но порой очень удобно.

  • Большую часть времени пользователи предпочитают использовать символические имена конфигурации, а не идентификатор цифровой клавиши. Отсутствие символических ключей IMO - довольно серьезный надзор со стороны дизайнеров интерфейса SysV.

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

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

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

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

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

+2

Хотя в Linux дескриптор очереди сообщений posix на самом деле является файловым дескриптором и поддерживает select/poll. Я не уверен в очередях сообщений sysv. – nos

+0

@ nos: ссылка? вы не смешиваете его с AIX? POSIX не описывает это, и [старая ссылка на Linux, которую я знаю] (http://www.steve.org.uk/Reference/Unix/faq_3.html#SEC31) также говорит «нет». – Dummy00001

+2

man mq_overview: «В Linux дескриптор очереди сообщений на самом деле является файловым дескриптором, и его можно контролировать с помощью select (2), poll (2) или epoll (7). Это не переносимо». , как уже упоминалось, это posix-очереди сообщений, я не уверен, что sysv message quees работают таким образом, если они это изменили за последние годы. – nos

3

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

Смежные вопросы