コード例 #1
0
ファイル: main.go プロジェクト: felixhao/goredis-failover
func main() {
	flag.Parse()
	// init config
	if err := initConfig(); err != nil {
		log.Error("init config error(%v)", err)
		return
	}
	// init log
	log.LoadConfiguration(conf.Log)
	defer log.Close()
	// init zk
	zkConn = zkDial()
	if zkConn == nil {
		log.Error("zk dial error")
		return
	}
	go watchPath()
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT, syscall.SIGSTOP)
	for {
		s := <-c
		log.Info("twemproxy agent get a signal %s", s.String())
		switch s {
		case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGSTOP, syscall.SIGINT:
			return
		case syscall.SIGHUP:
		default:
			return
		}
	}
}
コード例 #2
0
ファイル: client.go プロジェクト: felixhao/gosnowflake
// pingAndRetry ping the rpc connect and re connect when has an error.
func (c *Client) pingAndRetry(stop <-chan bool, client *rpc.Client, addr string) {
	defer func() {
		if err := client.Close(); err != nil {
			log.Error("client.Close() error(%v)", err)
		}
	}()
	var (
		failed bool
		status int
		err    error
		tmp    *rpc.Client
	)
	for {
		select {
		case <-stop:
			log.Info("addr: \"%s\" pingAndRetry goroutine exit", addr)
			return
		default:
		}
		if !failed {
			if err = client.Call(RPCPing, 0, &status); err != nil {
				log.Error("client.Call(%s) error(%v)", RPCPing, err)
				failed = true
				continue
			} else {
				failed = false
				time.Sleep(rpcClientPingSleep)
				continue
			}
		}
		if tmp, err = rpc.Dial("tcp", addr); err != nil {
			log.Error("rpc.Dial(tcp, %s) error(%v)", addr, err)
			time.Sleep(rpcClientRetrySleep)
			continue
		}
		client = tmp
		failed = false
		log.Info("client reconnect %s ok", addr)
	}
}
コード例 #3
0
ファイル: main.go プロジェクト: felixhao/goredis-failover
// zk get a zookeeper conn.
func zkDial() *zk.Conn {
	conn, session, err := zk.Connect(conf.ZK, zkTimeout)
	if err != nil {
		log.Error("zk.Connect(\"%v\", %d) error(%v)", conf.ZK, zkTimeout, err)
		return nil
	}
	go func() {
		for {
			event := <-session
			log.Info("zookeeper get a event: %s", event.State.String())
		}
	}()
	return conn
}
コード例 #4
0
ファイル: client.go プロジェクト: felixhao/gosnowflake
// Init init the gosnowflake client.
func Init(zservers []string, zpath string, ztimeout time.Duration) (err error) {
	mutex.Lock()
	defer mutex.Unlock()
	if zkConn != nil {
		return
	}
	zkPath = zpath
	zkServers = zservers
	zkTimeout = ztimeout
	conn, session, err := zk.Connect(zkServers, zkTimeout)
	if err != nil {
		log.Error("zk.Connect(\"%v\", %d) error(%v)", zkServers, zkTimeout, err)
		return
	}
	zkConn = conn
	go func() {
		for {
			event := <-session
			log.Info("zk connect get a event: %s", event.Type.String())
		}
	}()
	return
}
コード例 #5
0
ファイル: client.go プロジェクト: felixhao/gosnowflake
// watchWorkerId watch the zk node change.
func (c *Client) watchWorkerId(workerId int64, workerIdStr string) {
	workerIdPath := path.Join(zkPath, workerIdStr)
	log.Debug("workerIdPath: %s", workerIdPath)
	for {
		rpcs, _, watch, err := zkConn.ChildrenW(workerIdPath)
		if err != nil {
			log.Error("zkConn.ChildrenW(%s) error(%v)", workerIdPath, err)
			time.Sleep(zkNodeDelaySleep)
			continue
		}
		if len(rpcs) == 0 {
			log.Error("zkConn.ChildrenW(%s) no nodes", workerIdPath)
			time.Sleep(zkNodeDelaySleep)
			continue
		}
		// leader selection
		sort.Strings(rpcs)
		newLeader := rpcs[0]
		if c.leader == newLeader {
			log.Info("workerId: %s add a new standby gosnowflake node", workerIdStr)
		} else {
			log.Info("workerId: %s oldLeader: \"%s\", newLeader: \"%s\" not equals, continue leader selection", workerIdStr, c.leader, newLeader)
			// get new leader info
			workerNodePath := path.Join(zkPath, workerIdStr, newLeader)
			bs, _, err := zkConn.Get(workerNodePath)
			if err != nil {
				log.Error("zkConn.Get(%s) error(%v)", workerNodePath, err)
				time.Sleep(zkNodeDelaySleep)
				continue
			}
			peer := &Peer{}
			if err = json.Unmarshal(bs, peer); err != nil {
				log.Error("json.Unmarshal(%s, peer) error(%v)", string(bs), err)
				time.Sleep(zkNodeDelaySleep)
				continue
			}
			// init rpc
			tmpClients := make([]*rpc.Client, len(peer.RPC))
			tmpStop := make(chan bool, 1)
			for i, addr := range peer.RPC {
				clt, err := rpc.Dial("tcp", addr)
				if err != nil {
					log.Error("rpc.Dial(tcp, \"%s\") error(%v)", addr, err)
					continue
				}
				tmpClients[i] = clt
				go c.pingAndRetry(tmpStop, clt, addr)
			}
			// old rpc clients
			oldClients := c.clients
			oldStop := c.stop
			// atomic replace variable
			c.leader = newLeader
			c.clients = tmpClients
			c.stop = tmpStop
			// if exist, free resource
			if oldClients != nil {
				closeRpc(oldClients, oldStop)
			}
		}
		// new zk event
		event := <-watch
		log.Error("zk node(\"%s\") changed %s", workerIdPath, event.Type.String())
	}
}