Zookeeper 應用實現-配置中心

轉載自原文地址node

1、目標

一個乞丐版自更新配置中心,更新配置後,能在各個服務器實現更新git

2、架構

3、角色

  • config-web: 配置後臺,主要用於管理配置,增改配置
  • config-agent: 監聽配置,遇到變更後,自動拉取最新文件到本地
  • config-sdk: 業務集成該sdk,用於讀取配置

3.1 config-web 配置後臺

  1. 持久存儲爲MySQL,也能夠加一層緩存Redis,設置一個惟一的業務KEY,對應的ZK裏的ZNode
    • 對於配置節點的操做,最終必須落盤,持久化存儲於MySQL
  2. 持久存儲成功後,將配置的內容寫入ZK集羣中

如下是create節點的代碼,set的同,這是簡單的操做github

package main

import (
	"fmt"
	. "go-zk/connect"

	"github.com/samuel/go-zookeeper/zk"
)

func main()  {
	conn := Connect()
	defer conn.Close()

	flags := int32(zk.FlagSequence)
	acl := zk.WorldACL(zk.PermAll)

	// create node
	path := PathConfig.ZNodePath +"/"+ "huodong-"
	data := []byte(`{"num":6.13,"strs":["a","b"]}`)
	createPath, err := conn.Create(path, data, flags, acl)
	if err != nil {
		panic(err)
	}
}

複製代碼

3.2 config-agent 監控

  1. 因爲ZK的特性,能保持集羣的一致性,以及提供了監聽機制,在節點內容被改變時能提供回調
  2. 在config-agent監聽對應的業務節點
  3. 監聽的變更時,會有通知,例如,更改節點內容時,獲取節點的內容,而後進行落盤,或者存到內存中都
package main

import (
	"fmt"
	"github.com/samuel/go-zookeeper/zk"
	. "go-zk/connect"
	"os"
	"sync"
)
type Watch struct {

}

func (this *Watch)ZkChildrenWatch(c *zk.Conn, path string)  {
	for {
		v, _, get_ch, err := c.ChildrenW(path)
		if err != nil {
			fmt.Println(err)
		}

		fmt.Printf("value of path[%s]=[%s].\n", path, v)

		for {
			select {
			case ch_event := <-get_ch:
				{
					fmt.Printf("%+v\n", ch_event)

					if ch_event.Type == zk.EventNodeCreated {
						fmt.Printf("has new node[%d] create\n", ch_event.Path)
					} else if ch_event.Type == zk.EventNodeDeleted {
						fmt.Printf("has node[%s] detete\n", ch_event.Path)
					} else if ch_event.Type == zk.EventNodeDataChanged {
						this.Callback(c, ch_event.Path)
					} else if ch_event.Type == zk.EventNodeChildrenChanged {
						fmt.Printf("children node change%+v\n", ch_event.Path)
					}
				}
			}
			break
		}
	}
}

func (this *Watch)ZkNodeWatch(c *zk.Conn, path string)  {
	for {
		v, _, get_ch, err := c.GetW(path)
		if err != nil {
			fmt.Println(err)
		}

		fmt.Printf("value of path[%s]=[%s].\n", path, v)

		for {
			select {
			case ch_event := <-get_ch:
				{
					if ch_event.Type == zk.EventNodeCreated {
						fmt.Printf("has new node[%d] create\n", ch_event.Path)
					} else if ch_event.Type == zk.EventNodeDeleted {
						fmt.Printf("has node[%s] detete\n", ch_event.Path)
					} else if ch_event.Type == zk.EventNodeDataChanged {
						this.Callback(c, ch_event.Path)
					}
				}
			}
			break
		}
	}
}

func (this *Watch)Callback(c *zk.Conn, path string) {
	data, _, err := c.Get(path)
	if err != nil {
		fmt.Println(err)
	}

	// create file
	fileName := PathConfig.LocalPath + path + ".json"
	os.Create(fileName)
	f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_TRUNC, 0600)
	defer f.Close()
	if err != nil {
		fmt.Println(err.Error())
	} else {
		_,err=f.Write([]byte(data))
		fmt.Println(err)
		return
	}

	fmt.Print("Write File OK !!!")
}

func main()  {
	conn := Connect()

	// 監聽全部子節點變化
	children, _, err := conn.Children(PathConfig.ZNodePath)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", children)

	w := Watch{}

	var wg sync.WaitGroup
	wg.Add(1)
	go func(path string) {
		w.ZkChildrenWatch(conn, path)
	}(PathConfig.ZNodePath)
	wg.Wait()



	// 監聽節點內容變化
	//var wg sync.WaitGroup
	//wg.Add(len(children))
	//
	//for _, path := range children{
	//	path = PathConfig.ZNodePath + "/" + path
	//	go func(path string) {
	//		defer wg.Done()
	//		log.Print("Zookeeper Watcher Starting, ", path)
	//		w.ZkNodeWatch(conn, path)
	//	}(path)
	//}
	//wg.Wait()

}
複製代碼

3.3 config-sdk 客戶端加載配置

讀取配置的方式不少樣,兩種思路:web

  1. 直接讀取文件,由業務方直接讀取,.json 、 .ini 、 .toml等
  2. sdk能夠與config-agent結合,若是讀取文件加載配置失敗,利用agent,從新主動拉一次文件到本地,實現文件的懶加載

4、效果展現

# This is Zookeeper config file.

title = "Zookeeper config file"

[zookeeper]
servers = ["10.00.85.70:2181", "10.00.80.191:2181", "10.00.97.239:2181"]
port = 2181
session_timeout = 500
enabled = true

[path]
znode_path = "/huodong/conf"
local_path = "/tmp/zookeeper"
複製代碼
  1. 因爲在本地測試,嫌麻煩就沒有部署到服務器了,將locah_path分別改爲"/tmp/zookeeper"、"/tmp/zookeeper1"、"/tmp/zookeeper2",起三個進程json

  2. 鏈接到zk服務器,修改節點的內容 set /huodong/conf/huodong-0000000001 '{"num":6.13,"strs":["a","b"]}'緩存

  3. 看下本地文件就會生成對應的配置文件bash

專欄:

1、zookeeper 基礎介紹服務器

2、zookeeper 集羣搭建session

3、zookeeper 應用實現-配置中心架構

相關文章
相關標籤/搜索