ZooKeeper 作用
ZooKeeper是一个高可用的分布式数据管理与系统协调框架。基于对Paxos算法的实现,使该框架保证了 分布式 环境中数据的强一致性,也正是基于这样的特性,使得ZooKeeper解决很多分布式问题, dubbo 使用zookeeper的发布订阅功能
golang zookeeper的基本用法
func ensureRoot(conn *zk.Conn, path string) error { exists , _, err := conn.Exists(path) if err != nil { fmt.Println(err) return err } if !exists { _, err := conn.Create(path, []byte(""), 0, zk.WorldACL(zk.PermAll)) if err != nil && err != zk.Err node Exists { return err } } return nil } func main() { // 服务器地址列表 servers := []string{"127.0.0.1:2181"} conn, _, _ := zk.Connect(servers, time.Duration(10)*time.Second) path := "/ service /providers" createPathSlice := make([]string, 0) for _, subPath := range strings.Split(path, "/")[1:] { createPathSlice = append (createPathSlice, subPath) ensureRoot(conn, "/" + strings.Join(createPathSlice, "/")) } nodes := []string{"127.0.0.1:1","127.0.0.1:2","127.0.0.1:3"} for _, node := range nodes { _, err := conn.Create(path + "/" + node, []byte(""), zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) if err != nil { fmt.Println(err) } } go MonitorChiild(conn, path) go MonitorNodeEvent(conn) for { time.Sleep(time.Second) } } func MonitorChiild(conn *zk.Conn, path string) { // 监控路径下节点的变化 childs, _, event, _ := conn.ChildrenW(path) fmt.Println(childs) fmt.Println(<-event) } func MonitorNodeEvent(conn *zk.Conn) { // 判断节点是否存在 _, _, event,_ := conn.ExistsW("/service/providers/testpath") fmt.Println(<-event) } go run main.go 2019/09/23 13:53:11 Connected to 127.0.0.1:2181 2019/09/23 13:53:11 Authenticated: id=102812773889933398, timeout=10000 2019/09/23 13:53:11 Re-submitting `0` credentials after reconnect [127.0.0.1:1 127.0.0.1:2 127.0.0.1:3]在客户端执行如下图命令

zookeeper 客户端命令
可以看到在两个monitor函数中会打印出 {EventNodeCreated Unknown /service/providers/testpath <nil> } {EventNodeChildrenChanged Unknown /service/providers <nil> }
证明监控到路径改变事件
dubbo注册到zookeeper结构如下图

以dubbo-go example/helloworld 为例
server 端
- config.Load()
- ServiceConfig.export
- protocol .export
- 在/dubbo/com.ikurento.user.UserProvider/providers 下创建临时节点
主要是把服务的ip和端口注册到zookeeper中供消费者订阅,注册信息如下图

server端注册
client 端
1、config.Load()
2、 Refer enceConfig.Refer
3、protocol.Refer
4、注册 /dubbo/com.ikurento.user.UserProvider/consumers
5、获取server节点
1、l.client.GetChildren(zkPath) // 获取
监控每个节点是否存在 zk.ExistsW 如果有变化调用新增或者删除新的invoke
2、监控 zk.ChildrenW 监控/dubbo/com.ikurento.user.UserProvider/providers 是否添加或者删除新节点,新增或者删除新的invoke
获取路径如下图所示
