首页 > 解决方案 > 我可以使用 ZeroMQ 套接字来更改两个使用 REST 的微服务之间的通信机制吗?

问题描述

我们如何才能将基于 HTTP API 的通信干净地转换为使用 ZMQ 库的消息通信?

在此处输入图像描述

标签: restmicroserviceszeromqmessaging

解决方案


如果您确实想这样做,可以使用 ZeroMQ 工具设计一种调解器。

ZeroMQ 有一组多级抽象,其中 AccessPoints 通常具有它们之间执行的某种“行为”(一种分布式行为)。

您指定的目标旨在不使用此类行为,而是对数据流进行某种透明的(几乎)线级处理。

出于这个目的,让我首先将您的注意力引向这个概念:
- ZeroMQ Hierarchy 在不到 5 秒的时间内
和一个可能的工具旁边,可以帮助完成给定的任务:
-ZMQ_STREAM可扩展的正式通信原型(用于 AccessPoint)

使用传输时,类型的套接字ZMQ_STREAM用于从非 ØMQ 对等方发送和接收 TCP 数据tcp://。套接字可以ZMQ_STREAM充当客户端和/或服务器,异步发送和/或接收 TCP 数据。

接收 TCP 数据时,ZMQ_STREAM套接字应在将消息传递给应用程序之前,在消息前面添加一个包含原始对等方身份的消息部分。收到的消息在所有连接的对等点之间公平排队。

发送 TCP 数据时,ZMQ_STREAM套接字应删除消息的第一部分并使用它来确定消息应路由到的对等方的身份,不可路由的消息将导致错误EHOSTUNREACHEAGAIN错误。

要打开与服务器的连接,请使用zmq_connect调用,然后使用ZMQ_IDENTITY zmq_getsockopt调用获取套接字标识。

要关闭特定连接,请发送身份帧,后跟零长度消息(请参阅示例部分)。

建立连接后,应用程序将收到一条长度为零的消息。同样,当对端断开连接(或连接丢失)时,应用程序将收到一条长度为零的消息。

您必须先发送一个身份帧,然后再发送一个数据帧。该ZMQ_SNDMORE标志对于标识帧是必需的,但在数据帧上被忽略。

例子:

                                             /* Create Context-Engine */
void *ctx = zmq_ctx_new ();                     assert (ctx);

                                             /* Create ZMQ_STREAM socket */
void *socket = zmq_socket (ctx, ZMQ_STREAM);    assert (socket);

int rc = zmq_bind (socket, "tcp://*:8080");     assert (rc == 0);

                                             /* Data structure to hold the ZMQ_STREAM ID */
uint8_t id [256];
size_t id_size = 256;

                                             /* Data structure to hold the ZMQ_STREAM received data */
uint8_t raw [256];
size_t raw_size = 256;

while (1) {
                                             /* Get HTTP request; ID frame and then request */
 id_size = zmq_recv (socket, id, 256, 0);       assert (id_size > 0);

 do {
 raw_size = zmq_recv (socket, raw, 256, 0);     assert (raw_size >= 0);
 } while (raw_size == 256);

                                             /* Prepares the response */
 char http_response [] =
                          "HTTP/1.0 200 OK\r\n"
                          "Content-Type: text/plain\r\n"
                          "\r\n"
                          "Hello, World!";

                                             /* Sends the ID frame followed by the response */
 zmq_send (socket, id, id_size, ZMQ_SNDMORE);
 zmq_send (socket, http_response, strlen (http_response), 0);

                                            /* Closes the connection by sending the ID frame followed by a zero response */
 zmq_send (socket, id, id_size, ZMQ_SNDMORE);
 zmq_send (socket, 0, 0, 0);
}
zmq_close (socket); zmq_ctx_destroy (ctx);  /* Clean Close Sockets / Terminate Context */

推荐阅读