ZMQ 多线程 C 客户端

ZMQ Multithread C client

我想要多线程 zmq 客户端的 C 示例,我已经在使用多线程服务器,但我有要求让每个客户端从多线程而不是从单个线程发送请求。

我看过:

http://zguide.zeromq.org/c:asyncsrv
https://github.com/booksbyus/zguide/blob/master/examples/C/

但我没有看到使用 ZMQ_DEALER 套接字的多线程与多线程服务器(ZMQ_ROUTER 套接字)通信的客户端示例

所以我正在寻找 DEALERROUTER 模式。我希望客户端( DEALER )是多线程的:

目前我的客户端类似于hello world C:

zctx_t ctx = zctx_new ();
void *client = zsocket_new (ctx, ZMQ_REQ);
assert (client);
zsocket_connect (client, config.SERVER_ENDPOINT);

// SKIPPED: I get the data (hm->body.p) to be send through zmq...

// We send a request, then we work to get a reply

zstr_sendf(client, "%.*s", (int) hm->body.len,hm->body.p);

char *reply = zstr_recv (client);
if (  reply ) {
      zsys_info ("server replied (%s)", reply);
      free (reply);
} 

请帮助我使我的 C 客户端成为多线程 zmq 客户端。

更新 1(更多详细信息):

  1. 我有一个需要集成的第三方应用程序(我们称之为 3pa )。 3pa 平均每秒发送 ~ 4 HTTP POST 请求(每个请求的大小~ 60 KB)到 HTTP 侦听器(我正在使用 mongoose)。
  2. 3pa 仅在发送超时后收到 "HTTP/1.1 200 OK\r\n" "reply" 后发送下一个 HTTP POST要求。所以3pa似乎是单线程的。
  3. 如果我无法快速响应 200 OK3pa 将继续在内存中排队,直到崩溃。
  4. 当我收到来自 3pa 的请求时,我需要使用 ZMQ 通过 3G 移动分组网络将其发送到后端服务器。由于 3G 移动数据包网络延迟和带宽,每个请求需要大约 1-3 秒才能发送,并且 ZMQ 重播 new ZFrame("OK") 需要大约 1-3 秒才能启动、传输和交付(接收于3pa 侧)。

所以,如果我们进行初等微积分,3pa由于 3G 移动分组网络的性能,队列容量将很快被填满。

从OP/Update1中提供的一些细节来看,
让我们关注问题的根本原因,
在谈论增加线程数的想法之前.


真正重要的是什么?

鉴于 3pa 已作为 BlackBox 引入,具有经验丰富的阻塞设计(由等待指示永远,直到交付 200 OK,并在超时事件中逃逸)
最好的第一步是按原样操作 3pa,而不是 hosted/colocated 在一些更好的 NIX-peering/colocation 中心,而不是在延迟昂贵的 3G- 的当前 "peripheral" 最后一英里部分移动数据包无线电接入网络,这将 avoid/prevent 容量驱动的 DoS 引入的数据包重新传输,以防任何优先呼叫流量抢占 3G 信道并拥塞 运行 并且绝对会减少往返延迟的成本,目前在 2~6+ 秒以上的某个地方支付。

下一步可能,如果 3pa 搬迁到 NIX-proximity 本身不足以拯救游戏,将创建一个单一用途的 http-proxy,它将接收那些 60KB+ http-requests(然后将中继到适当的目标)并且会立即将 200 OK 响应下游注入 3pa 的手中,以便将它从它的内部阻塞循环中解锁并允许它发送另一个出队的 HTTP POST.

脏?是和不是。它解决了糟糕的 3pa 设计的弱点,并允许在给定的情况下运行它。


最后一个注意事项 - 在真实场景中尽量避免 REQ/REP 模式。

尽管 ZeroMQ 可扩展正式通信模式构建块是多方通信方案的智能示例,但不要期望它们不受 LoS、丢失消息和其他现实世界问题的影响。 REQ/REP 模式能够在脱轨的内部 FSA 状态下自行死锁,从中没有(字面上为零)工具来保存/恢复孪生 FSA -来自无法挽救的相互死锁状态的状态机。

在此类设计中使用其他一些可扩展的正式通信模式,并准备好在出现问题时提供额外的信号发送方式,以满足挽救状态的潜在需求。 ZeroMQ 有很多工具可以更聪明地做到这一点,而不是仅仅依赖于一个简单的原型,闭上眼睛并相信一切都将永远无错误地工作的小说(这不是我们生活的现实,对吧: o)).

真实世界的客户端操作许多 zmq-socket 实例,一些用于信号,一些用于传输服务,一些用于远程访问客户端的内部 CLI 界面,一些用于分布式日志收集器,一些用于自诊断和托管系统健康检查。简单的、主要是非阻塞设计的客户端可能包含几千个 SLOC,所以不要期望任何此类解决方案仅包含来自图书馆 wiki 页面或一些闪亮的博客文章的几个 SLOC 的副本。

One might also like to read other ZeroMQ posts, with also a link to the fabulous Pieter HINTJENS' book, that has been my must-read recommendation for those interested since I started to love the ZeroMQ way of thinking and design priorities. Worth the time and efforts, believe me or not, distributed processing has other, more important rules, than just asking for more threads for otherwise poor and un-feasible design.

Being able to change a poor design into a better one, one can still operate a single-threaded, well designed, application that can move xKB-messages and keep the end-to-end latencies under a few tens of milliseconds, even with a remote server doing a complex AI/ML-processing of the "fat"-data payloads.

Worth a try, isn't it?