断开的对等体上的ZeroMQ循环故障转移

时间:2018-05-31 04:57:44

标签: go zeromq distributed-system

我正在使用ZeroMQ的多重连接功能,将单个 DEALER 连接到2 ROUTERS

            +----> .Connect() --> ROUTER 1
           /
DEALER ---+------> .Connect() --> ROUTER 2

在我的测试中,我通过DEALER发送了10个消息。我为每个ROUTER - s收到了5条消息的均匀分布。

我的问题是,如果由于某种原因ROUTER 1消失,DEALER仍将继续为其排队消息,我认为ROUTER 1最终会回来。我最终只在ROUTER 2上发了5条消息。

我需要发生的是DEALER忽略断开连接或失败的对等体。这可能吗?

我尝试过设置 ZMQ_SNDHWM 和其他许多人,但似乎没有任何效果。

我能看到的唯一选择是自己进行故障转移,使用单独的套接字,心跳和ACK数据包等。看起来这样的基本模式应该已经由ZeroMQ实现。

修改:测试代码

package main

import (
    "github.com/pebbe/zmq4"
    "time"
    "log"
    "fmt"
)

func receiveAll(sok *zmq4.Socket) (received int) {
    poller := zmq4.NewPoller()
    poller.Add(sok, zmq4.POLLIN)

    for {
        sockets, err := poller.Poll(100 * time.Millisecond)
        if err != nil {
            log.Print(err)
        }
        if len(sockets) > 0 {
            for _, s := range sockets {
                msg, _ := s.Socket.RecvMessageBytes(0)
                if string(msg[1]) != "Hello World" {
                    log.Fatalf("Unexpected message: %s\n", msg)
                }
                received ++
            }
        } else {
            return
        }
    }
}

func main() {

    dealer, _ := zmq4.NewSocket(zmq4.DEALER)
    router1, _ := zmq4.NewSocket(zmq4.ROUTER)
    router2, _ := zmq4.NewSocket(zmq4.ROUTER)

    router1.Bind("tcp://0.0.0.0:6667")
    router2.Bind("tcp://0.0.0.0:6668")

    dealer.Connect("tcp://0.0.0.0:6667")
    dealer.Connect("tcp://0.0.0.0:6668")

    router1.SetSubscribe("")
    router2.SetSubscribe("")
    dealer.SetSubscribe("")

    for i := 0; i < 10; i++ {
        dealer.SendBytes([]byte("Hello World"), 0)
    }

    time.Sleep(300 * time.Millisecond)

    count1 := receiveAll(router1)
    count2 := receiveAll(router2)

    fmt.Printf("Blue sky scenario: count1=%d count2=%d\n", count1, count2)

    // Shut down a peer
    router1.Close()
    time.Sleep(300 * time.Millisecond)

    for i := 0; i < 10; i++ {
        dealer.SendBytes([]byte("Hello World"), 0)
    }

    time.Sleep(300 * time.Millisecond)

    count := receiveAll(router2)

    fmt.Printf("Peer 1 offline: count=%d\n", count)

}

1 个答案:

答案 0 :(得分:0)

  

我需要做的是 DEALER 忽略断开连接或失败的对等体。 这可能吗?

哦,当然可以。需要使用以下用例特定设置调整默认(非活动)值:

  • .setsockopt( ZMQ.IMMEDIATE , 1 )用于不缓冲对等体的消息实例,这些消息实例似乎不是&#34;有效的&#34;
  • .setsockopt( ZMQ.HEARTBEAT_IVL , <ms> )用于发送心跳
  • a .setsockopt( ZMQ.HEARTBEAT_TTL , <ms> ),了解生存时间设置
  • a .setsockopt( ZMQ.HEARTBEAT_TIMEOUT , <ms>)了解超时阈值
  • .setsockopt( ZMQ.HANDSHAKE_IVL , <ms> ),用于管理(重新)建立超时。

有关详细信息,请检查语言绑定以及它实际使用的本机API版本。自native-API v 3.x以来,大多数这些设置都可用,最新的native-API v 4.2.2文档将帮助您调整值和配置策略。