Uso de colas de mensajes POSIX en lugar de sockets TCP: ¿cómo establecer la “conexión”?

Tengo progtwigs de cliente y servidor que ahora se comunican a través de TCP. Estoy intentando usar colas de mensajes POSIX en su lugar (en los casos en que el cliente y el servidor están en la misma máquina, por supuesto). Mi esperanza es que mejore el rendimiento (específicamente a través de una latencia reducida).

He trabajado la mayor parte del tiempo, pero no estoy seguro de una cosa: cómo establecer la “conexión“. El servidor acepta conexiones de varios clientes al mismo tiempo, por lo que estoy tentado de emular el proceso de establecimiento de la conexión TCP de esta manera:

  1. El servidor abre una cola con un nombre conocido y lo lee continuamente (puede usar select(2) como con TCP).
  2. El cliente abre tres colas: dos con nombres arbitrarios (incluidas algunas características únicas, como PID para evitar colisiones), y una con el nombre conocido que usa el servidor.
  3. El cliente publica un mensaje de “conexión” a la cola del servidor, incluidos los nombres de la cola del cliente (uno está designado para el tráfico de cliente a servidor y el otro para el contrario).
  4. El servidor abre las colas nombradas en el mensaje de conexión del cliente y comienza a leer (seleccionar) del cliente al servidor.
  5. El cliente cierra la cola del servidor con el nombre conocido. La comunicación bidireccional se realiza utilizando las dos colas nombradas por el cliente (una para cada dirección).

Probablemente pueda ver cómo este esquema es similar al método TCP común, y eso no es accidental. Sin embargo, me gustaría saber:

  1. ¿Puedes pensar en una mejor manera de hacerlo?
  2. ¿Ves algún problema potencial con mi método?
  3. ¿Tiene alguna otra idea, incluida la posibilidad de que el uso de colas de mensajes en lugar de TCP en la misma máquina realmente mejore el rendimiento (latencia)?

Tenga en cuenta que no he usado colas de mensajes POSIX anteriormente (sí que usé IBM WebSphere MQ hace un tiempo, pero eso es bastante diferente). La plataforma es Linux.

  1. ¿Puedes pensar en una mejor manera de hacerlo?

    Tal vez echar un vistazo a fifos (también conocido como tuberías). Son como sockets de red pero para la máquina local. Son unidireccionales, por lo que es posible que necesite crear dos, uno para cada dirección. Su pregunta no tiene ninguna razón de por qué está haciendo este cambio específicamente. No hay nada de malo en usar sockets para procesar el proceso de comunicación. Son bidireccionales, eficientes, cuentan con un amplio respaldo y le brindan la libertad de separar los procesos entre las máquinas más adelante.

  2. ¿Ves algún problema potencial con mi método?

    Las colas de mensajes de System V y las canalizaciones con nombre de fifo están absolutamente bien. Las canalizaciones de Fifo son como tuberías normales, por lo que puede leer () y escribir () con cambios mínimos de código. Las colas de mensajes de System V requieren poner los datos en una estructura e invocar msgsnd (). Sin embargo, cualquiera de los dos enfoques estaría bien.

  3. ¿Tiene alguna otra idea, incluida la posibilidad de que el uso de colas de mensajes en lugar de TCP en la misma máquina realmente mejore el rendimiento (latencia)?

    Mis otros pensamientos son que, como usted dijo, necesita desarrollar una técnica para que cada cliente tenga un identificador único. Un enfoque sería agregar el pid a la estructura por la que pasa o negociar una identificación única con el padre / maestro al principio. La otra cosa a tener en cuenta es que el beneficio de las colas de mensajes del Sistema V es que escucha los mensajes “selectivos”, por lo que lo ideal sería utilizar una cola del servidor para todos los clientes, con cada cliente esperando un mensaje diferente.

    No tengo idea de qué técnica le proporciona el rendimiento más óptimo en su software. Puede que realmente no valga la pena usar las colas de mensajes del Sistema V, pero solo usted puede tomar esa decisión.

Philluminati

Terminé implementándolo básicamente como lo describí, con algunas mejoras:

  • En el paso 2, usé los GUID para los nombres de cola en lugar de incorporar el PID del cliente.
  • En el paso 4, agregué el envío de un mensaje de “aceptación” del servidor al cliente.
  • Cuando cualquiera de las partes desea finalizar la comunicación, envía un mensaje de “desconexión”.

El handshaking es más simple que TCP, pero parece suficiente.

En cuanto a la latencia: es mucho mejor. Aproximadamente un 75% menos de latencia usando las colas de mensajes POSIX en lugar de TCP en la misma máquina. Mis mensajes son del orden de 100 bytes cada uno.

Comparé el rendimiento de posix MQ y un par de sockets TCP / IP.

El progtwig de demostración tiene dos hilos uno para escribir y otro para leer.

El resultado es que posix MQ es más rápido,

  • MQ 460000 tps
  • socketpair 400000 tps

Me he encontrado con un problema similar, desarrollo una aplicación en tiempo real y necesito una técnica IPC con una funcionalidad similar a la de sockets y una latencia mínima.

¿Ha comparado su solución basada en POSIX-MQ con sockets locales UNIX o sockets TCP solamente?

Gracias

¿Cómo hizo esto cuando select () no funciona en las colas de mensajes? ¿Qué es Sys V o POSIX? ¿Por qué hacer un esfuerzo adicional para crear GUID en la tabla de búsqueda de PID cuando se garantiza que PID es único y es un almacenamiento más pequeño (entero)?

/ blee /

También puede usar Message Queue para IPC en progtwigs que residen en diferentes máquinas, en tales casos, puede usar ZeroMQ ( http://www.zeromq.org ) u otras API de cola de mensajes, también le sugiero que las considere y las pruebe. ellos tambien.