golang 连接zk,注册zk代码

package main

import (
    "encoding/json"
    "fmt"
    "github.com/samuel/go-zookeeper/zk"
    "strconv"
    "strings"
    "time"
    "net"
)
var zkservers string
var conn *zk.Conn
type zklistener func()

func  testlisten() {
    fmt.Println("listen test")
}

//获取本机的ip地址
func localIP() string {
    addrs, err := net.InterfaceAddrs()
    if err != nil {
        return ""
    }
    for _, address := range addrs {
        // 检查ip地址判断是否回环地址
        if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
            if ipnet.IP.To4() != nil {
                return ipnet.IP.String()
            }
        }
    }
    return ""
}

// 首先调用此方法设置zk地址
// 初始化zk server
func SetZkServers(servers string, listeners ...zklistener) {
    if zkservers != servers {
        zkservers = servers
        initConn()
        for _, listener := range listeners {
            listener()//定义当设置zk server时候需要通知的回调函数,做一些操作
        }
    }
}

func Register(path, port string) {
    ip := localIP()
    if ip == "" {
        panic("get local ip error")
    }
    zkKey := ip + ":" + port
    value := make(map[string]interface{})
    value["host"] = ip
    p, _ := strconv.Atoi(port)
    value["port"] = p
    zkVal, _ := json.Marshal(value)
    go func() {
        for {
            var exist bool
            var err error
            registerPath := path + "/" + zkKey
            exist, _, err = conn.Exists(registerPath)
            if err != nil {
                fmt.Println("Exist Err:", err)
                time.Sleep(time.Second)
                continue
            }

            if !exist {
                //flag = zk.FlagEphemeral
                //flags有4种取值:
                //0:永久,除非手动删除
                //zk.FlagEphemeral = 1:短暂,session断开则改节点也被删除,session维持时间为zk.Connect的第二个参数
                //zk.FlagSequence  = 2:会自动在节点后面添加序号
                //3:Ephemeral和Sequence,即,短暂且自动添加序号
                //zk.WorldACL(zk.PermAll)//控制访问权限模式
                var flag int32 =1
                _, err := conn.Create(registerPath, zkVal, flag, zk.WorldACL(zk.PermAll))
                if err != nil {
                    fmt.Println("Create Err:", err)
                    time.Sleep(time.Second)
                    continue
                }
            }
            time.Sleep(10 * time.Second)
        }
    }()
}

func initConn() {
    servers := strings.Split(zkservers, ",")
    //注意,第二个参数为创建之后session维持的时间,因为session消
    //失之后,才会将注册的ip地址从zk上摘除,所以不能太长,否则影响服务
    //正常功能,一般为1s.
    connZK, _, err := zk.Connect(servers, time.Second*60)//测试所以写的60s
    if err != nil {
        panic(err)
    }
    if conn != nil {
        conn.Close()
    }
    conn = connZK
}

//删除注册的节点
func Unregister(registerPath string) {
    if conn != nil {
        exist, _, err := conn.Exists(registerPath)
            if exist {
            err = conn.Delete(registerPath, 0)
            if err != nil {
                fmt.Println("Delete ZK Node:", err)
            }
        }
        //conn.Close()//如果节点是自动注册的,则使用该操作,直接Close掉conn即可。
    }
}

//获取zk结点中的配置信息,比如超时时间等
func GetConf(path string) (string, error) {
    ret, _, err1 := conn.Get(path)
    if err1 != nil {
        fmt.Println("Get Err:", err1)
        return "", err1
    }
    return string(ret), nil
}

//获取zk结点下,注册的机器的ip信息
func GetBatchConf(path string) (map[string]string, error) {
    ret := make(map[string]string)
    keys, _, err1 := conn.Children(path)
    if err1 != nil {
        return ret, err1
    }
    for _, key := range keys {
        newPath := path + "/" + key
        val, _, err := conn.Get(newPath)
        if err != nil {
            continue
        }
        ret[key] = string(val)
    }
    return ret, nil
}



func main() {
    SetZkServers("zk服务起地址信息ip:端口,例如:10.0.0.18:3333", testlisten)
    Register("/testzk","5555")//注册的路径和端口
    conf,_ := GetConf("/testzk")
    batchConf, _ :=GetBatchConf("/testzk")
    fmt.Println("conf:", conf)
    fmt.Println("batchConf:", batchConf)
    time.Sleep(time.Minute * 60 * 24 * 365 * 100)
}

 

你可能感兴趣的:(golang)