在Python上,ZeroMQ .recv()/.send()
操作正在阻止,这对于 REQ/REP
非常适合。
在Golang,我必须将 zmq.DONTWAIT
传递给.recv()
和.send()
操作才能使其正常运行。
但问题是,流程需要锁定步骤,所以:
server.recv()
client.send()
client.recv()
server.send()
在3到4之间,怪异开始了,因为它们是异步的。
当客户端发送消息且服务器尚未收到消息但客户端尝试接收响应时,锁定步骤不再是锁定步骤。
与 zmq.DOBLOCK
相比,是否存在某种 zmq.DONTWAIT
?
或者我在这里弄错了什么?
EDIT:
我在C中使用此绑定绑定zeromq:https://godoc.org/github.com/pebbe/zmq4#Type
正如您在此处所看到的, .recv()
需要输入flag
,这是第二个参考中的两者之一:
Recv:https://godoc.org/github.com/pebbe/zmq4#Socket.Recv
要传递的标志:https://github.com/pebbe/zmq4/blob/master/zmq4.go#L403
这是我制作解决方法的当前代码,感觉有点难看:
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
}
答案 0 :(得分:2)
ZeroMQ琐碎的基本原型比任何需要的生产级解决方案更像是一组构建块。
Go-lang是一种非常强大的现代语言,带有协同程序和其他智能工具,可以控制并发,所以请原谅我提出以下建议列表:避免阻止设计无论何时都可以(非阻塞设计让一个人完全控制所有事物,因为它们来了...... 没有“悬挂”在任何地方无限/无法控制等待循环,已经发展的僵局中更糟糕的情况)
避免依赖SLOC示例使用单一的基本类型的形式通信模式,我们应该为所有人开发强大的生存性处理策略可能出现问题的情况(传输网络中的信号丢失,消息丢失,DDoS级别的资源超载,......)
REQ/REP
。是的,永远不会...... ZeroMQ可扩展正式通信模式REQ/REP
适用于学习ZeroMQ,但在实际生产等级部署中是致命的。 For details, read here
接下来考虑一下内部无条件模式,类似 PAIR
(虽然标记为 experimental ,但对于某些用例来说效果很好), {{ 1}} , XREQ/XREP
或某些复合信令/传输多插槽自定义设计的自有模式。
What I can do for your further questions right now is to direct you to see a bigger picture on this subject包含更多参数,一个简单的信号平面/消息平面插图以及与Pieter HINTJENS必读书籍的直接链接。
这本书值得一时间和努力。如果一个人对分布式系统设计非常认真,那么你会非常喜欢Pieter对Zero-sharing,Zero-blocking,(几乎)Zero-copy等人的热情。