请教用 ZeroMQ 实现多任务服务器的标准方法

2015-12-23 22:34:29 +08:00
 feng32

如果要用 ZeroMQ 实现一个典型的 TCP 服务器,一个服务器同时服务多个请求,好像一般是需要使用 Router 模式吧。

Router 模式会在收到每个消息后,在消息前面添加一个 Connection Identity (长度是 5 字节的一个帧)。然后如果要把应答传回给客户端,也需要在消息前面加上这个 Connection Identiry ,否则就无法把应答正确送达发送者。

如果每个请求的处理都是同步的,写起来很简单:就先用一个变量存一下 Identity ,然后发应答的时候发回去就行了。

但是如果采用异步方式(调用其它非阻塞 API )处理请求,那么就稍微有些麻烦了。这种情况下服务器必须自己来维护一个从 Identity 到 Async Request ID 的映射。当非阻塞 API 返回的时候,需要把 Async Request ID 重新映射到 Identity ,把 Identity 加到消息头部再发送才行。

请问这种方式是实现这样的一个服务器的标准方法吗?有没有更简洁的方法?(暂时不考虑简单暴力的开多线程 / 进程,多个 Rep 同时处理 Req 的方法)

2828 次点击
所在节点    程序员
4 条回复
wayslog
2015-12-23 22:53:58 +08:00
参考 saltstack 的方式
master 通知节点是用 pub 发送, minion 来 sub 接受,通过订阅 topic 可以很方便的获取到自己想要订阅的消息。

而关于信息的回收是用在 master 端通过一个 router-dealer 的方式,通过 dealer 获取数据,并将数据转换成 Event 对象,再通过以 event.key.hash() 为后缀地址的 ipc ,通过 req-rep 的方式将 event 据发送给多个 worker 子进程。
而 minion 通过 req 来进行发送返回消息。
master 实际上做了一个 device ,链接了多个 worker 和多个 minion 。

楼主说的方式大部分都是正确的,但是并不需要来维持 identity 到 Async Request ID 的映射,因为 zeromq 会自动帮你维护这个映射。

更简洁的办法当然有,例如 zeromq 提供的原生的 zmq_poll ,就是一个典型的 zmq 方式的调用,但是嘛……现在谁写个服务还不是堆多线程多进程,逃~~
znoodl
2015-12-23 23:15:24 +08:00
有点乱。。。
楼上给的东西很充足
q1084733229
2015-12-24 10:06:49 +08:00
我有香港服务器
DinoStray
2021-04-07 18:01:36 +08:00
zguide/examples/C++/asyncsrv.cpp 应该满足你的需求, 用 router + dealer 实现. zguide 是 zmq 二号作者写的一本书, 在第三章介绍了这个模式

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/245720

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX