聊聊Gossip的一个实现

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 引言 Gossip是一种去中心化、容错并保证最终一致性的协议。它的基本思想是通过不断的和集群中的节点gossip交换信息,经过 O(log(n))个回合, gossip协议即可将信息传递到所有的节点。 这里介绍Gossip的一个实现库hashicorp/memberlist,并讲一下需要注意的事项。 2. hashicorp/memberlist memberlist是HashiCorp公司开源的Gossip库,这个库被consul(也是HashiCorp公司开源的)所引用。 它是SWIM的一个扩展实现。 下面的例子test_gossip.go中它被用来做集群节点发现 package main import ( "flag" "fmt" "github.com/hashicorp/memberlist" // "net" "os" "strconv" "time" ) var ( bindPort = flag.Int("port", 8001, "gossip port") ) func main() { flag.Parse() hostname, _ := os.Hostname() config := memberlist.DefaultLocalConfig() config.Name = hostname + "-" + strconv.Itoa(*bindPort) // config := memberlist.DefaultLocalConfig() config.BindPort = *bindPort config.AdvertisePort = *bindPort fmt.Println("config.DisableTcpPings", config.DisableTcpPings) fmt.Println("config.IndirectChecks", config.IndirectChecks) fmt.Println("config.RetransmitMult", config.RetransmitMult) fmt.Println("config.PushPullInterval", config.PushPullInterval) fmt.Println("config.ProbeInterval", config.ProbeInterval) fmt.Println("config.GossipInterval", config.GossipInterval) fmt.Println("config.GossipNodes", config.GossipNodes) fmt.Println("config.BindPort", config.BindPort) list, err := memberlist.Create(config) if err != nil { panic("Failed to create memberlist: " + err.Error()) } // Join an existing cluster by specifying at least one known member. // 配置种子节点, 这里我直接写死了 _, err = list.Join([]string{"127.0.0.1:8001", "127.0.0.1:8002"}) fmt.Println("err", err) if err != nil { panic("Failed to join cluster: " + err.Error()) } // Ask for members of the cluster for { fmt.Println("-------------start--------------") for _, member := range list.Members() { fmt.Printf("Member: %s %s\n", member.Name, member.Addr) } fmt.Println("-------------end--------------") time.Sleep(time.Second * 3) } } 可以直接在单机上进行测试,启动 ...

July 4, 2018 · 3 min