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)
    if err != nil {
        panic(err)
    }
    if conn != nil {
        conn.Close()
    }
    conn = connZK
}

//獲取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)
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章