V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
feng32
V2EX  ›  程序员

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

  •  
  •   feng32 · 2015-12-23 22:34:29 +08:00 · 2904 次点击
    这是一个创建于 3258 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

    4 条回复    2021-04-07 18:01:36 +08:00
    wayslog
        1
    wayslog  
       2015-12-23 22:53:58 +08:00   ❤️ 2
    参考 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
        2
    znoodl  
       2015-12-23 23:15:24 +08:00 via iPhone
    有点乱。。。
    楼上给的东西很充足
    q1084733229
        3
    q1084733229  
       2015-12-24 10:06:49 +08:00
    我有香港服务器
    DinoStray
        4
    DinoStray  
       2021-04-07 18:01:36 +08:00
    zguide/examples/C++/asyncsrv.cpp 应该满足你的需求, 用 router + dealer 实现. zguide 是 zmq 二号作者写的一本书, 在第三章介绍了这个模式
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1104 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 19:00 · PVG 03:00 · LAX 11:00 · JFK 14:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.