Использование очередей сообщений POSIX вместо сокетов TCP - как установить «соединение»? - PullRequest
14 голосов
/ 04 января 2009

У меня есть клиентские и серверные программы, которые теперь общаются через TCP. Вместо этого я пытаюсь использовать очереди сообщений POSIX (в случаях, когда клиент и сервер находятся на одной машине, конечно). Я надеюсь, что это улучшит производительность (особенно за счет уменьшения задержки).

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

  1. Сервер открывает очередь с известным именем и непрерывно читает из нее (он может использовать select(2) как с TCP).
  2. Клиент открывает три очереди: две с произвольными именами (включая некоторую уникальность, например PID, чтобы избежать коллизий), и одну с хорошо известным именем, используемым сервером.
  3. Клиент отправляет сообщение «connect» в очередь сервера, включая имена очередей клиента (одно предназначено для трафика клиент-сервер, а другое для обратного).
  4. Сервер открывает очереди, указанные в сообщении подключения клиента, и начинает читать (выбирать) из сообщения клиент-сервер.
  5. Клиент закрывает очередь сервера с известным именем. Двусторонняя связь осуществляется с использованием двух очередей, названных клиентом (по одной для каждого направления).

Возможно, вы видите, как эта схема похожа на обычный метод TCP, и это не случайно. Тем не менее, я хотел бы знать:

  1. Можете ли вы придумать лучший способ сделать это?
  2. Видите ли вы какие-либо потенциальные проблемы с моим методом?
  3. Есть ли у вас какие-либо другие мысли, в том числе о вероятности того, что использование очередей сообщений вместо TCP на одной и той же машине действительно повысит производительность (задержку)?

Имейте в виду, что раньше я не использовал очереди сообщений POSIX (некоторое время назад я использовал IBM WebSphere MQ, но это несколько иное). Платформа Linux.

Ответы [ 6 ]

7 голосов
/ 04 января 2009
  1. Можете ли вы придумать лучший способ сделать это?

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

  2. Видите ли вы какие-либо потенциальные проблемы с моим методом?

    Очереди сообщений System V и именованные каналы fifo абсолютно нормальны. Каналы Fifo похожи на обычные каналы, поэтому вы можете читать () и писать () с минимальными изменениями кода. Очереди сообщений System V требуют помещения данных в структуру и вызова msgsnd (). Любой подход был бы хорош однако.

  3. Есть ли у вас какие-либо другие мысли, в том числе о вероятности того, что использование очередей сообщений вместо TCP на одной и той же машине действительно повысит производительность (задержку)?

    Мои другие мысли заключаются в том, что, как вы сказали, вам нужно разработать технику, чтобы у каждого клиента был уникальный идентификатор. Один из подходов заключается в добавлении pid в структуру, через которую вы проходите, или в начале для согласования уникального идентификатора с родителем / хозяином. Следует также отметить, что преимущество очередей сообщений System V заключается в том, что вы прослушиваете «выборочные» сообщения, поэтому в идеале вы можете использовать одну очередь от сервера для всех клиентов, при этом каждый клиент ожидает отдельного сообщения.

    Я понятия не имею, какая техника дает вам наиболее оптимальную пропускную способность в вашем программном обеспечении. Возможно, не стоит использовать очереди сообщений System V, но только вы можете принять это решение.

Philluminati

6 голосов
/ 28 января 2009

В итоге я реализовал его в основном так, как я описал, с некоторыми улучшениями:

  • На шаге 2 я использовал GUID для имен очередей вместо включения PID клиента.
  • На шаге 4 я добавил отправку сообщения «принять» с сервера на клиент.
  • Когда любая из сторон желает прекратить связь, она отправляет сообщение «отключить».

Подтверждение связи проще, чем TCP, но кажется достаточным.

Что касается задержки: она намного лучше. Примерно на 75% меньше задержка при использовании очередей сообщений POSIX вместо TCP на одном компьютере. Мои сообщения имеют порядок 100 байт каждое.

3 голосов
/ 03 мая 2012

Я сравнил производительность posix MQ и пары сокетов TCP / IP.

Демонстрационная программа имеет два потока, один для записи, а другой для чтения.

В результате posix MQ быстрее,

  • MQ 460000 т / с
  • socketpair 400000 tps
1 голос
/ 11 ноября 2009

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

Сравнивали ли вы свое решение на основе POSIX-MQ с локальными сокетами UNIX или только с сокетами TCP?

Спасибо

0 голосов
/ 05 апреля 2013

Вы также можете использовать очереди сообщений для IPC в программах, которые находятся на разных компьютерах, в таких случаях вы можете использовать ZeroMQ (http://www.zeromq.org) или другие API очереди сообщений, я также предлагаю вам рассмотреть их и протестировать их тоже.

0 голосов
/ 15 февраля 2009

Как вы это сделали, когда select () не работает с очередями сообщений? Что это Sys V или POSIX? Зачем предпринимать дополнительные усилия при создании GUID для таблицы поиска PID, если PID гарантированно уникален и имеет меньший объем памяти (целое число)?

/ блее /

...