2012-05-03 13 views
9

estoy trabajando en un proyecto que involucra a varios programas en C++ que cada toma de entrada y generar una salida. Los datos (decenas a cientos de bytes, probablemente JSON) esencialmente fluyen (asincrónicamente) en una dirección, y los programas deberán ubicarse en diferentes computadoras Linux alrededor de la LAN.remota de mensajes C/C++ las colas

Dado que los datos fluyen en una sola dirección, no creo que necesite un modelo transaccional como HTTP. Creo que un modelo de cola de mensajes (disparar y olvidar) tiene más sentido y debe simplificar la lógica de cada programa. Probablemente sea suficiente simplemente notar que el mensaje se agregó a la cola remota con éxito.

Lo que estoy buscando son recomendaciones sobre cómo implementar esta cola de mensajes en C o C++. Parece que las colas de mensajes POSIX y Boost están limitadas a un solo host, y RabbitMQ parece tener compatibilidad con C/C++ débil, y MQ4CPP parece no ser compatible con una función crítica para la empresa. ¿Estoy equivocado sobre esto? ¿Qué pasa con Boost ASIO o ACE o escribir código de socket yo mismo? Espero sus sugerencias.

+2

[ZeroMQ es bastante agradable] (http://www.zeromq.org). – user7116

+0

Excelentes respuestas, a todos, pero realmente me gusta la simplicidad de ZeroMQ. Si @sixlettervariables lo convirtieran en una respuesta, lo aceptaría. –

Respuesta

8

En términos de soporte de mensajería simple, ZeroMQ is hard to beat. Está disponible en muchos enlaces de idiomas y es compatible con todo, desde simple enviar y recibir hasta pub/sub, fanout o incluso una canalización de mensajes. El código también es fácil de digerir y hace que sea muy fácil cambiar de patrones.

En cuanto a sus Weather Update Server sample (en 20 algunos idiomas impares) muestra lo fácil que puede ser la creación de publicación/suscripción configuraciones:

zmq::context_t context (1); 
zmq::socket_t publisher (context, ZMQ_PUB); 
publisher.bind("tcp://*:5556"); 
publisher.bind("ipc://weather.ipc"); 

while(1) { 
    // Send message to all subscribers 
    zmq::message_t message(20); 
    snprintf ((char *) message.data(), 20 , 
     "%05d %d %d", zipcode, temperature, relhumidity); 
    publisher.send(message); 
} 

Yo he utilizado en algunos C mixta procesos de Python # y sin mucha molestia .

1

estoy usando serialización Boost y toma el envío de una solicitud similar. Se puede encontrar un ejemplo de serialización aquí:

http://code.google.com/p/cloudobserver/wiki/TutoriaslBoostSerialization

Y en esta página:

http://www.boost.org/doc/libs/1_38_0/doc/html/boost_asio/examples.html

bajo serialización encontrará ejemplos sobre cómo hacer que los servidores y clientes. Haga un servidor en un puerto en particular y puede generar múltiples clientes en múltiples computadoras que puedan comunicarse con ese puerto.

La desventaja de usar la serialización de impulso es que tiene una gran sobrecarga si tiene una estructura de datos simple para ser serializada, pero lo hace más fácil.

2

Personalmente, si entiendo la pregunta, creo que debería usar una conexión TCP de nivel inferior. Tiene toda la entrega garantizada que desea y tiene una API de Berkley Sockets bastante buena. He encontrado que si estás dispuesto a implementar un protocolo muy simple (por ejemplo, longitud de mensaje NBO de cuatro bytes, n bytes de datos), puedes ser muy simple, muy personalizable y muy simple. Si vas con esto, también (como se mencionó) obtienes una gran compatibilidad con C (lo que significa compatibilidad con C++, aunque las cosas no están en clases y métodos). El código de socket es también muy fácil, y tienen asíncrono IO con las banderas asíncronos estándar para las funciones de Linux/UNIX/POSIX IO (que es uno de los otros beneficios, si se sabe nada acerca de POSIX programación, que, básicamente, conocer el socket API) .

Uno de los mejores recursos para el aprendizaje de la API del conector son:

  • Guía del Beej Red Programación: http://beej.us/guide/bgnet/, esto es muy bueno si necesita el modelo general de la programación, además de aspectos específicos
  • páginas Man : Si solo necesita firmas de funciones, valores de retorno y argumentos, estos son todo lo que necesita. Encuentro las de Linux a ser muy bien escrito y útil (Prueba: Mira mi consola: man, man, man, man, man, make, man, ...)

Además, para hacer que los datos se puedan enviar a través de la red, si sus datos son JSON, no tiene preocupaciones. Como JSON es solo ASCII (o UTF-8), se puede enviar sin formato a través de la red con solo un encabezado de longitud. A menos que intente enviar algo complicado en formato binario, esto debería ser perfecto (si necesita algo complicado en formato binario, consulte la serialización o prepárese para un montón de Segmentation Fault).


Además, probablemente, si va por la ruta del socket, desea usar TCP. Aunque UDP le dará un aspecto unidireccional, el hecho de que hacerlo confiable es enfrentar a su solución casera contra el TCP de alta calidad proporcionado por el kernel de Linux, TCP es una opción obvia.

1

Otra recomendación es el marco distribuido OpenCL. El documento The OpenCL C++ Wrapper for API proporciona más información sobre la biblioteca. En particular, la función API cl::CommandQueue podría ser de interés para crear colas en dispositivos dentro de una configuración de red.

2

RabbitMQ es solo una implementación de AMQP. Es posible que desee investigar Apache Qpid u otras variantes que puedan ser más amigables con C/C++. Hay un libamqp para C, aunque no tengo experiencia de primera mano con él. No sé exactamente cuáles son sus requisitos, pero AMQP, implementado correctamente, es de fuerza industrial y debe ser de una magnitud mucho más rápida y más estable que cualquier cosa que vaya a construir a mano en un corto período de tiempo.

1

Otra solución de mensajería es ICE (http://www.zeroc.com/). Es multiplataforma, multiidioma. Utiliza más de un enfoque RPC.

+0

Si bien es un gran producto, [ICE tiene GPL] (http://www.zeroc.com/licensing.html). A menos que su código tenga GPL también o esté dispuesto a pagar por una licencia comercial, me mantendría alejado de ella. – Void

Cuestiones relacionadas