Asynchronous Golang ZeroMQ:REQ/REP无意义非阻塞

Asynchronous Golang ZeroMQ:REQ/REP无意义非阻塞,asynchronous,go,zeromq,Asynchronous,Go,Zeromq,在Python上,ZeroMQ.recv()/.send()操作是阻塞的,这非常适合REQ/REP在Golang中,我必须将zmq.DONTWAIT传递给.recv()和.send()操作,以使其工作 但问题是,流程需要锁定,所以: server.recv() client.send() client.recv() server.send() 在3到4之间,奇怪开始了,因为它们是异步的 当客户端发送了一条消息,而服务器还没有收到该消息,但客户端试图接收响应时,锁定步骤不再是锁定步骤 与zmq.D

在Python上,ZeroMQ
.recv()/.send()
操作是阻塞的,这非常适合
REQ/REP
在Golang中,我必须将
zmq.DONTWAIT
传递给
.recv()
.send()
操作,以使其工作

但问题是,流程需要锁定,所以:

  • server.recv()
  • client.send()
  • client.recv()
  • server.send()
  • 在3到4之间,奇怪开始了,因为它们是异步的

    当客户端发送了一条消息,而服务器还没有收到该消息,但客户端试图接收响应时,锁定步骤不再是锁定步骤

    与zmq.DONTWAIT相比,是否存在某种类型的zmq.DOBLOCK

    还是我这里出了什么问题


    编辑:

    我在C中为zeromq使用此go绑定:

    如您所见,这里的
    .recv()
    需要一个输入
    标志
    ,这是第二个参考上的两个标志之一:

    记录:

    将通过的旗帜:

    这是我目前的代码,它让我觉得有点难看:

    package connection
    
    import (
      "zmq4"
      "fmt"
      "time"
    )
    
    
    const ERRTMPUNAV="resource temporarily unavailable"
    
    
    func checkError(e error){
      if e != nil {
        panic(e)
      }
    }
    
    
    func CreateRepNode(address string,onMessage chan<- string,send <-chan string,closeConn <-chan bool){
      stop:=false
      socket,err:=zmq4.NewSocket(zmq4.REP)
      checkError(err)
      err=socket.Bind(address)
      checkError(err)
      go func(socket *zmq4.Socket){
        for {
          msg,err:=socket.Recv(zmq4.DONTWAIT)
          fmt.Println("server message"+msg)
          if stop==true {
            return
          }
          if err != nil {
            rateLimit := time.Tick(100 * time.Millisecond)
        <-rateLimit
        continue
          }
          checkError(err)
          onMessage<-msg
          rep:=<-send
          _,err=socket.Send(rep,zmq4.DONTWAIT)
        }
      }(socket)
      <-closeConn
      stop=true
    }
    
    
    func CreateReqNode(address string,onMessage chan<- string,send <-chan string,closeConn <-chan bool){
      stop:=false
      socket,err:=zmq4.NewSocket(zmq4.REQ)
      checkError(err)
      err=socket.Connect(address)
      checkError(err)
      go func(){
        for {
          msg:=<-send
          if stop==true {
            return
          }
          _,err:=socket.Send(msg,zmq4.DONTWAIT)
          for {
            msg,err=socket.Recv(zmq4.DONTWAIT)
            fmt.Println("client got message "+msg)
            if err!=nil {
              if err.Error()==ERRTMPUNAV {
                w:=time.Tick(100*time.Millisecond)
                <-w
                continue
              }
            }
            break
          }
          onMessage<-msg
        }
      }()
    
      <-closeConn
      stop=true
    }
    
    包连接
    进口(
    “zmq4”
    “fmt”
    “时间”
    )
    const ERRTMPUNAV=“资源暂时不可用”
    函数检查错误(e错误){
    如果e!=nil{
    恐慌(e)
    }
    }
    
    func CreateRepNode(地址字符串,onMessage chanZeroMQ琐碎的基本原型是一组构建块,而不是满足任何需求的生产级解决方案

    Go-lang是一种功能强大的现代语言,它使用协同程序和其他智能工具来实现受控并发,因此请原谅我提出以下建议:

    • 尽可能避免阻塞设计(非阻塞设计让人完全控制所有事情的发生…不会在任何无限/不可控的等待循环中“挂起”,在已经形成的死锁中更糟)

    • 避免依赖SLOC示例对于单一、基本类型的正式通信模式,应针对可能出现问题的所有情况(传输网络中的信号丢失、消息丢失、DDoS级别的资源过载等),制定一个健壮的生存能力处理策略


    重新设计提示-根本不要使用REQ/REP。是的,永远不要。。。 ZeroMQ可扩展的正式通信模式
    REQ/REP
    对于学习ZeroMQ很好,但在实际生产级部署中却是致命的

    接下来考虑内部无条件模式,类似于
    (虽然标记为实验性的,但对于某些用例它工作得很好),
    XREQ/XREP
    推/拉
    或一些定制的复合信令/传输多套接字模式

    最好的下一步是什么? 有了更多的参数,一个简单的信号平面/消息平面图和到Pieter HINTJENS必读书籍的直接链接


    这本书值得你付出时间和努力。如果你认真研究分布式系统设计,你会爱上它,因为Pieter对零共享、零阻塞、(几乎)零拷贝等的热情。

    它应该是默认阻塞的,因为zeromq是默认阻塞的。请分享一个代码示例。@Mario Santini确实更新了最初的帖子;-)我认为您的问题不在于zeromq异步工作人员。您可以通过0而不是zmq4.dont。现在它是异步的,因为您传递了DONTWAIT标志。这是我的问题的一部分,如果有什么东西要将其设置为阻止(例如0)。非常感谢您的回答!帮了很多忙!