Beispiel #1
0
func (s *Server) waitOnline() {
	for {
		info, err := s.topo.GetProxyInfo(s.info.Id)
		if err != nil {
			log.PanicErrorf(err, "get proxy info failed")
		}
		switch info.State {
		case models.PROXY_STATE_MARK_OFFLINE:
			s.handleMarkOffline()
		case models.PROXY_STATE_ONLINE:
			s.info.State = info.State
			log.Infof("we are online: %s", s.info.Id)
			_, err := s.topo.WatchNode(path.Join(models.GetProxyPath(s.topo.ProductName), s.info.Id), s.evtbus)
			if err != nil {
				log.PanicErrorf(err, "watch node failed")
			}
			return
		}
		select {
		case e := <-s.evtbus:
			switch e.(type) {
			case *killEvent:
				s.handleMarkOffline()
			}
		default: //otherwise ignore it
		}
		log.Warnf("wait to be online: %s", s.info.Id)
		time.Sleep(3 * time.Second)
	}
}
Beispiel #2
0
func (s *Server) processAction(e interface{}) {
	if strings.Index(getEventPath(e), models.GetProxyPath(s.topo.ProductName)) == 0 {
		info, err := s.topo.GetProxyInfo(s.info.Id)
		if err != nil {
			log.PanicErrorf(err, "get proxy info failed: %s", s.info.Id)
		}
		switch info.State {
		case models.PROXY_STATE_MARK_OFFLINE:
			log.Infof("mark offline, proxy got offline event: %s", s.info.Id)
			s.markOffline()
		case models.PROXY_STATE_ONLINE:
			s.rewatchProxy()
		default:
			log.Panicf("unknown proxy state %v", info)
		}
		return
	}

	//re-watch
	nodes := s.rewatchNodes()

	seqs, err := models.ExtraSeqList(nodes)
	if err != nil {
		log.PanicErrorf(err, "get seq list failed")
	}

	if len(seqs) == 0 || !s.topo.IsChildrenChangedEvent(e) {
		return
	}

	//get last pos
	index := -1
	for i, seq := range seqs {
		if s.lastActionSeq < seq {
			index = i
			//break
			//only handle latest action
		}
	}

	if index < 0 {
		return
	}

	actions := seqs[index:]
	for _, seq := range actions {
		exist, err := s.topo.Exist(path.Join(s.topo.GetActionResponsePath(seq), s.info.Id))
		if err != nil {
			log.PanicErrorf(err, "get action failed")
		}
		if exist {
			continue
		}
		if s.checkAndDoTopoChange(seq) {
			s.responseAction(int64(seq))
		}
	}

	s.lastActionSeq = seqs[len(seqs)-1]
}
Beispiel #3
0
func LoadCodisEnv(cfg *cfg.Cfg) Env {
	if cfg == nil {
		log.Panicf("config is nil")
	}

	productName, err := cfg.ReadString("product", "test")
	if err != nil {
		log.PanicErrorf(err, "read product name failed")
	}

	zkAddr, err := cfg.ReadString("zk", "localhost:2181")
	if err != nil {
		log.PanicErrorf(err, "read zk address failed")
	}

	hostname, _ := os.Hostname()
	dashboardAddr, err := cfg.ReadString("dashboard_addr", hostname+":18087")
	if err != nil {
		log.PanicErrorf(err, "read dashboard address failed")
	}

	provider, err := cfg.ReadString("coordinator", "zookeeper")
	if err != nil {
		log.PanicErrorf(err, "read coordinator failed")
	}

	return &CodisEnv{
		zkAddr:        zkAddr,
		dashboardAddr: dashboardAddr,
		productName:   productName,
		provider:      provider,
	}
}
Beispiel #4
0
func (s *Server) register() {
	if _, err := s.topo.CreateProxyInfo(&s.info); err != nil {
		log.PanicErrorf(err, "create proxy node failed")
	}
	if _, err := s.topo.CreateProxyFenceNode(&s.info); err != nil {
		log.PanicErrorf(err, "create fence node failed")
	}
}
Beispiel #5
0
func (s *Server) processAction(e interface{}) {
	if strings.Index(getEventPath(e), models.GetProxyPath(s.topo.ProductName)) == 0 {
		info, err := s.topo.GetProxyInfo(s.info.Id)
		if err != nil {
			log.PanicErrorf(err, "get proxy info failed: %s", s.info.Id)
		}
		if info.State == models.PROXY_STATE_MARK_OFFLINE {
			s.handleMarkOffline()
		}
		return
	}

	//re-watch
	nodes, err := s.topo.WatchChildren(models.GetWatchActionPath(s.topo.ProductName), s.evtbus)
	if err != nil {
		log.PanicErrorf(err, "rewatch children failed")
	}

	seqs, err := models.ExtraSeqList(nodes)
	if err != nil {
		log.PanicErrorf(err, "get seq list failed")
	}

	if len(seqs) == 0 || !s.topo.IsChildrenChangedEvent(e) {
		return
	}

	//get last pos
	index := -1
	for i, seq := range seqs {
		if s.lastActionSeq < seq {
			index = i
			break
		}
	}

	if index < 0 {
		return
	}

	actions := seqs[index:]
	for _, seq := range actions {
		exist, err := s.topo.Exist(path.Join(s.topo.GetActionResponsePath(seq), s.info.Id))
		if err != nil {
			log.PanicErrorf(err, "get action failed")
		}
		if exist {
			continue
		}
		if s.checkAndDoTopoChange(seq) {
			s.responseAction(int64(seq))
		}
	}

	s.lastActionSeq = seqs[len(seqs)-1]
}
Beispiel #6
0
func (s *Server) register() {
	if _, err := s.topo.CreateProxyInfo(&s.info); err != nil {
		log.PanicErrorf(err, "create proxy node failed")
	}
	if _, err := s.topo.CreateProxyFenceNode(&s.info); err != nil && err != zk.ErrNodeExists {
		log.PanicErrorf(err, "create fence node failed")
	}
	log.Warn("********** Attention **********")
	log.Warn("You should use `kill {pid}` rather than `kill -9 {pid}` to stop me,")
	log.Warn("or the node resisted on zk will not be cleaned when I'm quiting and you must remove it manually")
	log.Warn("*******************************")
}
Beispiel #7
0
func New(addr string, debugVarAddr string, conf *Config) *Server {
	log.Infof("create proxy with config: %+v", conf)

	proxyHost := strings.Split(addr, ":")[0]
	debugHost := strings.Split(debugVarAddr, ":")[0]

	hostname, err := os.Hostname()
	if err != nil {
		log.PanicErrorf(err, "get host name failed")
	}
	if proxyHost == "0.0.0.0" || strings.HasPrefix(proxyHost, "127.0.0.") || proxyHost == "" {
		proxyHost = hostname
	}
	if debugHost == "0.0.0.0" || strings.HasPrefix(debugHost, "127.0.0.") || debugHost == "" {
		debugHost = hostname
	}

	s := &Server{conf: conf, lastActionSeq: -1, groups: make(map[int]int)}
	s.topo = NewTopo(conf.productName, conf.zkAddr, conf.fact, conf.provider, conf.zkSessionTimeout)
	s.info.Id = conf.proxyId
	s.info.State = models.PROXY_STATE_OFFLINE
	s.info.Addr = proxyHost + ":" + strings.Split(addr, ":")[1]
	s.info.DebugVarAddr = debugHost + ":" + strings.Split(debugVarAddr, ":")[1]
	s.info.Pid = os.Getpid()
	s.info.StartAt = time.Now().String()
	s.kill = make(chan interface{})

	log.Infof("proxy info = %+v", s.info)

	if l, err := net.Listen(conf.proto, addr); err != nil {
		log.PanicErrorf(err, "open listener failed")
	} else {
		s.listener = l
	}
	s.router = router.NewWithAuth(conf.passwd)
	s.evtbus = make(chan interface{}, 1024)
	s.sessionPool = &sync.Pool{
		New: func() interface{} {
			return nil
		},
	}

	s.register()

	s.wait.Add(1)
	go func() {
		defer s.wait.Done()
		s.serve()
	}()
	return s
}
Beispiel #8
0
func (s *Server) checkAndDoTopoChange(seq int) bool {
	act, err := s.topo.GetActionWithSeq(int64(seq))
	if err != nil { //todo: error is not "not exist"
		log.PanicErrorf(err, "action failed, seq = %d", seq)
	}

	if !needResponse(act.Receivers, s.info) { //no need to response
		return false
	}

	log.Warnf("action %v receivers %v", seq, act.Receivers)

	switch act.Type {
	case models.ACTION_TYPE_SLOT_MIGRATE, models.ACTION_TYPE_SLOT_CHANGED,
		models.ACTION_TYPE_SLOT_PREMIGRATE:
		slot := &models.Slot{}
		s.getActionObject(seq, slot)
		s.fillSlot(slot.Id)
	case models.ACTION_TYPE_SERVER_GROUP_CHANGED:
		serverGroup := &models.ServerGroup{}
		s.getActionObject(seq, serverGroup)
		s.onGroupChange(serverGroup.Id)
	case models.ACTION_TYPE_SERVER_GROUP_REMOVE:
	//do not care
	case models.ACTION_TYPE_MULTI_SLOT_CHANGED:
		param := &models.SlotMultiSetParam{}
		s.getActionObject(seq, param)
		s.onSlotRangeChange(param)
	default:
		log.Panicf("unknown action %+v", act)
	}
	return true
}
Beispiel #9
0
func (top *Topology) InitZkConn() {
	var err error
	top.zkConn, err = top.fact(top.zkAddr)
	if err != nil {
		log.PanicErrorf(err, "init failed")
	}
}
Beispiel #10
0
func LoadConf(configFile string) (*Config, error) {
	c, err := utils.InitConfigFromFile(configFile)
	if err != nil {
		log.PanicErrorf(err, "load config '%s' failed", configFile)
	}

	conf := &Config{}
	conf.productName, _ = c.ReadString("product", "test")
	if len(conf.productName) == 0 {
		log.Panicf("invalid config: product entry is missing in %s", configFile)
	}
	conf.zkAddr, _ = c.ReadString("zk", "")
	if len(conf.zkAddr) == 0 {
		log.Panicf("invalid config: need zk entry is missing in %s", configFile)
	}
	conf.zkAddr = strings.TrimSpace(conf.zkAddr)

	conf.proxyId, _ = c.ReadString("proxy_id", "")
	if len(conf.proxyId) == 0 {
		log.Panicf("invalid config: need proxy_id entry is missing in %s", configFile)
	}

	conf.netTimeout, _ = c.ReadInt("net_timeout", 5)
	conf.proto, _ = c.ReadString("proto", "tcp")
	conf.provider, _ = c.ReadString("coordinator", "zookeeper")
	return conf, nil
}
Beispiel #11
0
func (s *Server) rewatchNodes() []string {
	nodes, err := s.topo.WatchChildren(models.GetWatchActionPath(s.topo.ProductName), s.evtbus)
	if err != nil {
		log.PanicErrorf(err, "watch children failed")
	}
	return nodes
}
Beispiel #12
0
func (s *Server) waitOnline() bool {
	for {
		info, err := s.topo.GetProxyInfo(s.info.Id)
		if err != nil {
			log.PanicErrorf(err, "get proxy info failed: %s", s.info.Id)
		}
		switch info.State {
		case models.PROXY_STATE_MARK_OFFLINE:
			log.Infof("mark offline, proxy got offline event: %s", s.info.Id)
			s.markOffline()
			return false
		case models.PROXY_STATE_ONLINE:
			s.info.State = info.State
			log.Infof("we are online: %s", s.info.Id)
			s.rewatchProxy()
			return true
		}
		select {
		case <-s.kill:
			log.Infof("mark offline, proxy is killed: %s", s.info.Id)
			s.markOffline()
			return false
		default:
		}
		log.Infof("wait to be online: %s", s.info.Id)
		time.Sleep(3 * time.Second)
	}
}
Beispiel #13
0
func GetExecutorPath() string {
	filedirectory := filepath.Dir(os.Args[0])
	execPath, err := filepath.Abs(filedirectory)
	if err != nil {
		log.PanicErrorf(err, "get executor path failed")
	}
	return execPath
}
Beispiel #14
0
func (s *Server) getActionObject(seq int, target interface{}) {
	act := &models.Action{Target: target}
	err := s.topo.GetActionWithSeqObject(int64(seq), act)
	if err != nil {
		log.PanicErrorf(err, "get action object failed, seq = %d", seq)
	}
	log.Infof("action %+v", act)
}
Beispiel #15
0
func (s *Server) RegisterAndWait() {
	_, err := s.topo.CreateProxyInfo(&s.info)
	if err != nil {
		log.PanicErrorf(err, "create proxy node failed")
	}
	_, err = s.topo.CreateProxyFenceNode(&s.info)
	if err != nil {
		log.WarnErrorf(err, "create fence node failed")
	}
	s.registerSignal()
	s.waitOnline()
}
Beispiel #16
0
func (c *safeConn) Get(path string) (data []byte, stat zk.Stat, err error) {
	for i := 0; i <= retryMaxOnOps; i++ {
		c.builder.lock.RLock()
		data, stat, err = c.Conn.Get(path)
		c.builder.lock.RUnlock()
		if err == nil || !isConnectionError(err) {
			return
		}
		c.builder.resetConnection()
	}
	log.PanicErrorf(err, "zk error after retries")
	return
}
Beispiel #17
0
func (c *safeConn) Delete(path string, version int32) (err error) {
	for i := 0; i <= retryMaxOnOps; i++ {
		c.builder.lock.RLock()
		err = c.Conn.Delete(path, version)
		c.builder.lock.RUnlock()
		if err == nil || !isConnectionError(err) {
			return
		}
		c.builder.resetConnection()
	}
	log.PanicErrorf(err, "zk error after retries")
	return
}
Beispiel #18
0
func (c *safeConn) Create(path string, value []byte, flags int32, aclv []zk.ACL) (pathCreated string, err error) {
	for i := 0; i <= retryMaxOnOps; i++ {
		c.builder.lock.RLock()
		pathCreated, err = c.Conn.Create(path, value, flags, aclv)
		c.builder.lock.RUnlock()
		if err == nil || !isConnectionError(err) {
			return
		}
		c.builder.resetConnection()
	}
	log.PanicErrorf(err, "zk error after retries")
	return
}
Beispiel #19
0
func (c *safeConn) ExistsW(path string) (exist bool, stat zk.Stat, watch <-chan zk.Event, err error) {
	for i := 0; i <= retryMaxOnOps; i++ {
		c.builder.lock.RLock()
		exist, stat, watch, err = c.Conn.ExistsW(path)
		c.builder.lock.RUnlock()
		if err == nil || !isConnectionError(err) {
			return
		}
		c.builder.resetConnection()
	}
	log.PanicErrorf(err, "zk error after retries")
	return
}
Beispiel #20
0
func (c *safeConn) Children(path string) (children []string, stat zk.Stat, err error) {
	for i := 0; i <= retryMaxOnOps; i++ {
		c.builder.lock.RLock()
		children, stat, err = c.Conn.Children(path)
		c.builder.lock.RUnlock()
		if err == nil || !isConnectionError(err) {
			return
		}
		c.builder.resetConnection()
	}
	log.PanicErrorf(err, "zk error after retries")
	return
}
Beispiel #21
0
func (c *safeConn) SetACL(path string, aclv []zk.ACL, version int32) (stat zk.Stat, err error) {
	for i := 0; i <= retryMaxOnOps; i++ {
		c.builder.lock.RLock()
		stat, err = c.Conn.SetACL(path, aclv, version)
		c.builder.lock.RUnlock()
		if err == nil || !isConnectionError(err) {
			return
		}
		c.builder.resetConnection()
	}
	log.PanicErrorf(err, "zk error after retries")
	return
}
Beispiel #22
0
func (s *Server) fillSlot(i int) {
	slotInfo, slotGroup, err := s.topo.GetSlotByIndex(i)
	if err != nil {
		log.PanicErrorf(err, "get slot by index failed", i)
	}

	var from string
	var addr = groupMaster(*slotGroup)
	if slotInfo.State.Status == models.SLOT_STATUS_MIGRATE {
		fromGroup, err := s.topo.GetGroup(slotInfo.State.MigrateStatus.From)
		if err != nil {
			log.PanicErrorf(err, "get migrate from failed")
		}
		from = groupMaster(*fromGroup)
		if from == addr {
			log.Panicf("set slot %04d migrate from %s to %s", i, from, addr)
		}
	}

	s.groups[i] = slotInfo.GroupId
	s.router.FillSlot(i, addr, from,
		slotInfo.State.Status == models.SLOT_STATUS_PRE_MIGRATE)
}
Beispiel #23
0
func LoadConf(configFile string) (*Config, error) {
	c := cfg.NewCfg(configFile)
	if err := c.Load(); err != nil {
		log.PanicErrorf(err, "load config '%s' failed", configFile)
	}

	conf := &Config{}
	conf.productName, _ = c.ReadString("product", "test")
	if len(conf.productName) == 0 {
		log.Panicf("invalid config: product entry is missing in %s", configFile)
	}
	conf.dashboardAddr, _ = c.ReadString("dashboard_addr", "")
	if conf.dashboardAddr == "" {
		log.Panicf("invalid config: dashboard_addr is missing in %s", configFile)
	}
	conf.zkAddr, _ = c.ReadString("zk", "")
	if len(conf.zkAddr) == 0 {
		log.Panicf("invalid config: need zk entry is missing in %s", configFile)
	}
	conf.zkAddr = strings.TrimSpace(conf.zkAddr)
	conf.passwd, _ = c.ReadString("password", "")

	conf.proxyId, _ = c.ReadString("proxy_id", "")
	if len(conf.proxyId) == 0 {
		log.Panicf("invalid config: need proxy_id entry is missing in %s", configFile)
	}

	conf.proto, _ = c.ReadString("proto", "tcp")
	conf.provider, _ = c.ReadString("coordinator", "zookeeper")

	loadConfInt := func(entry string, defval int) int {
		v, _ := c.ReadInt(entry, defval)
		if v < 0 {
			log.Panicf("invalid config: read %s = %d", entry, v)
		}
		return v
	}

	conf.pingPeriod = loadConfInt("backend_ping_period", 5)
	conf.maxTimeout = loadConfInt("session_max_timeout", 1800)
	conf.maxBufSize = loadConfInt("session_max_bufsize", 131072)
	conf.maxPipeline = loadConfInt("session_max_pipeline", 1024)
	conf.zkSessionTimeout = loadConfInt("zk_session_timeout", 30000)
	if conf.zkSessionTimeout <= 100 {
		conf.zkSessionTimeout *= 1000
		log.Warn("zkSessionTimeout is to small, it is ms not second")
	}
	return conf, nil
}
Beispiel #24
0
func LoadCodisEnv(cfg *cfg.Cfg) Env {
	if cfg == nil {
		log.Panicf("config is nil")
	}

	productName, err := cfg.ReadString("product", "test")
	if err != nil {
		log.PanicErrorf(err, "config: 'product' not found")
	}

	zkAddr, err := cfg.ReadString("zk", "localhost:2181")
	if err != nil {
		log.PanicErrorf(err, "config: 'zk' not found")
	}

	hostname, _ := os.Hostname()
	dashboardAddr, err := cfg.ReadString("dashboard_addr", hostname+":18087")
	if err != nil {
		log.PanicErrorf(err, "config: 'dashboard_addr' not found")
	}

	provider, err := cfg.ReadString("coordinator", "zookeeper")
	if err != nil {
		log.PanicErrorf(err, "config: 'coordinator' not found")
	}

	passwd, _ := cfg.ReadString("password", "")

	return &CodisEnv{
		zkAddr:        zkAddr,
		passwd:        passwd,
		dashboardAddr: dashboardAddr,
		productName:   productName,
		provider:      provider,
	}
}
Beispiel #25
0
func LoadConf(configFile string) (*Config, error) {
	c, err := utils.InitConfigFromFile(configFile)
	if err != nil {
		log.PanicErrorf(err, "load config '%s' failed", configFile)
	}

	conf := &Config{}
	conf.productName, _ = c.ReadString("product", "test")
	if len(conf.productName) == 0 {
		log.Panicf("invalid config: product entry is missing in %s", configFile)
	}
	conf.zkAddr, _ = c.ReadString("zk", "")
	if len(conf.zkAddr) == 0 {
		log.Panicf("invalid config: need zk entry is missing in %s", configFile)
	}
	conf.zkAddr = strings.TrimSpace(conf.zkAddr)
	conf.passwd, _ = c.ReadString("requirepass", "")

	conf.proxyId, _ = c.ReadString("proxy_id", "")
	if len(conf.proxyId) == 0 {
		log.Panicf("invalid config: need proxy_id entry is missing in %s", configFile)
	}

	conf.proto, _ = c.ReadString("proto", "tcp")
	conf.provider, _ = c.ReadString("coordinator", "zookeeper")

	loadConfInt := func(entry string, defInt int) int {
		v, _ := c.ReadInt(entry, defInt)
		if v < 0 {
			log.Panicf("invalid config: read %s = %d", entry, v)
		}
		return v
	}

	conf.pingPeriod = loadConfInt("backend_ping_period", 5)
	conf.maxTimeout = loadConfInt("session_max_timeout", 1800)
	conf.maxBufSize = loadConfInt("session_max_bufsize", 1024*32)
	conf.maxPipeline = loadConfInt("session_max_pipeline", 128)
	return conf, nil
}
Beispiel #26
0
func main() {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	signal.Notify(c, syscall.SIGTERM)
	go func() {
		<-c
		if createdDashboardNode {
			releaseDashboardNode()
		}
		log.Panicf("ctrl-c or SIGTERM found, exit")
	}()

	args, err := docopt.Parse(usage, nil, true, utils.Version, true)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// set output log file
	if s, ok := args["-L"].(string); ok && s != "" {
		f, err := os.OpenFile(s, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
		if err != nil {
			log.PanicErrorf(err, "open log file failed: %s", s)
		} else {
			defer f.Close()
			log.StdLog = log.New(f, "")
		}
	}
	log.SetLevel(log.LEVEL_INFO)
	log.SetFlags(log.Flags() | log.Lshortfile)

	// set log level
	if s, ok := args["--log-level"].(string); ok && s != "" {
		setLogLevel(s)
	}

	// set config file
	var configFile string
	if args["-c"] != nil {
		configFile = args["-c"].(string)
	} else {
		configFile = "config.ini"
	}
	config := cfg.NewCfg(configFile)

	if err := config.Load(); err != nil {
		log.PanicErrorf(err, "load config file error")
	}

	// load global vars
	globalEnv = LoadCodisEnv(config)

	cmd := args["<command>"].(string)
	cmdArgs := args["<args>"].([]string)

	go http.ListenAndServe(":10086", nil)
	err = runCommand(cmd, cmdArgs)
	if err != nil {
		log.PanicErrorf(err, "run sub-command failed")
	}
}
Beispiel #27
0
func (s *Server) fillSlot(i int, force bool) {
	if !s.isValidSlot(i) {
		return
	}
	slot := s.slots[i]
	if !force && slot.backend.bc != nil {
		log.Panicf("slot %04d already filled, slot: %+v", i, slot)
	}

	slotInfo, slotGroup, err := s.topo.GetSlotByIndex(i)
	if err != nil {
		log.PanicErrorf(err, "get slot by index failed", i)
	}

	var from string
	var addr = group.NewGroup(*slotGroup).Master()
	if slotInfo.State.Status == models.SLOT_STATUS_MIGRATE {
		fromGroup, err := s.topo.GetGroup(slotInfo.State.MigrateStatus.From)
		if err != nil {
			log.PanicErrorf(err, "get migrate from failed")
		}
		from = group.NewGroup(*fromGroup).Master()
		if from == addr {
			log.Panicf("set slot %04d migrate from %s to %s", i, from, addr)
		}
	}

	slot.blockAndWait()

	s.putBackendConn(slot.backend.bc)
	s.putBackendConn(slot.migrate.bc)
	slot.reset()

	slot.Info, slot.Group = slotInfo, slotGroup
	if len(addr) != 0 {
		xx := strings.Split(addr, ":")
		if len(xx) >= 1 {
			slot.backend.host = []byte(xx[0])
		}
		if len(xx) >= 2 {
			slot.backend.port = []byte(xx[1])
		}
		slot.backend.addr = addr
		slot.backend.bc = s.getBackendConn(addr)
	}
	if len(from) != 0 {
		slot.migrate.from = from
		slot.migrate.bc = s.getBackendConn(from)
	}

	if slotInfo.State.Status != models.SLOT_STATUS_PRE_MIGRATE {
		slot.unblock()
	}

	if slot.migrate.bc != nil {
		log.Infof("fill slot %04d, force %v, backend.addr = %s, migrate.from = %s",
			i, force, slot.backend.addr, slot.migrate.from)
	} else {
		log.Infof("fill slot %04d, force %v, backend.addr = %s",
			i, force, slot.backend.addr)
	}
}
Beispiel #28
0
func NewServer(addr string, debugVarAddr string, conf *Config) (*Server, error) {
	log.Infof("start proxy with config: %+v", conf)
	s := &Server{
		evtbus:        make(chan interface{}, 1000),
		conf:          conf,
		topo:          topology.NewTopo(conf.productName, conf.zkAddr, conf.fact, conf.provider),
		pool:          make(map[string]*SharedBackendConn),
		lastActionSeq: -1,
	}
	for i := 0; i < MaxSlotNum; i++ {
		s.slots[i] = &Slot{Id: i}
	}

	proxyHost := strings.Split(addr, ":")[0]
	debugHost := strings.Split(debugVarAddr, ":")[0]

	hostname, err := os.Hostname()
	if err != nil {
		log.PanicErrorf(err, "get host name failed")
	}
	if proxyHost == "0.0.0.0" || strings.HasPrefix(proxyHost, "127.0.0.") {
		proxyHost = hostname
	}
	if debugHost == "0.0.0.0" || strings.HasPrefix(debugHost, "127.0.0.") {
		debugHost = hostname
	}

	s.info.Id = conf.proxyId
	s.info.State = models.PROXY_STATE_OFFLINE
	s.info.Addr = proxyHost + ":" + strings.Split(addr, ":")[1]
	s.info.DebugVarAddr = debugHost + ":" + strings.Split(debugVarAddr, ":")[1]
	s.info.Pid = os.Getpid()
	s.info.StartAt = time.Now().String()

	log.Infof("proxy info = %+v", s.info)

	if l, err := net.Listen(conf.proto, addr); err != nil {
		return nil, errors.Trace(err)
	} else {
		s.Listener = l
	}

	stats.Publish("evtbus", stats.StringFunc(func() string {
		return strconv.Itoa(len(s.evtbus))
	}))

	stats.PublishJSONFunc("router", func() string {
		var m = make(map[string]interface{})
		m["ops"] = cmdstats.requests.Get()
		m["cmds"] = getAllOpStats()
		m["info"] = s.info
		m["build"] = map[string]interface{}{
			"version": utils.Version,
			"compile": utils.Compile,
		}
		b, _ := json.Marshal(m)
		return string(b)
	})

	s.RegisterAndWait()

	_, err = s.topo.WatchChildren(models.GetWatchActionPath(conf.productName), s.evtbus)
	if err != nil {
		log.PanicErrorf(err, "watch children failed")
	}

	for i := 0; i < MaxSlotNum; i++ {
		s.fillSlot(i, false)
	}

	go s.handleTopoEvent()

	log.Info("proxy start ok")

	return s, nil
}
Beispiel #29
0
func (s *Server) rewatchProxy() {
	_, err := s.topo.WatchNode(path.Join(models.GetProxyPath(s.topo.ProductName), s.info.Id), s.evtbus)
	if err != nil {
		log.PanicErrorf(err, "watch node failed")
	}
}
Beispiel #30
0
func main() {
	fmt.Print(banner)

	args, err := docopt.Parse(usage, nil, true, "codis proxy v0.1", true)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// set config file
	if args["-c"] != nil {
		configFile = args["-c"].(string)
	}

	var maxFileFrag = 10
	var maxFragSize int64 = bytesize.GB * 1
	if s, ok := args["--log-filesize"].(string); ok && s != "" {
		v, err := bytesize.Parse(s)
		if err != nil {
			log.PanicErrorf(err, "invalid max log file size = %s", s)
		}
		maxFragSize = v
	}

	// set output log file
	if s, ok := args["-L"].(string); ok && s != "" {
		f, err := log.NewRollingFile(s, maxFileFrag, maxFragSize)
		if err != nil {
			log.PanicErrorf(err, "open rolling log file failed: %s", s)
		} else {
			defer f.Close()
			log.StdLog = log.New(f, "")
		}
	}
	log.SetLevel(log.LEVEL_INFO)

	// set log level
	if s, ok := args["--log-level"].(string); ok && s != "" {
		setLogLevel(s)
	}

	// set cpu
	if args["--cpu"] != nil {
		cpus, err = strconv.Atoi(args["--cpu"].(string))
		if err != nil {
			log.PanicErrorf(err, "parse cpu number failed")
		}
	}

	// set addr
	if args["--addr"] != nil {
		addr = args["--addr"].(string)
	}

	// set http addr
	if args["--http-addr"] != nil {
		httpAddr = args["--http-addr"].(string)
	}

	checkUlimit(1024)
	runtime.GOMAXPROCS(cpus)

	http.HandleFunc("/setloglevel", handleSetLogLevel)
	go http.ListenAndServe(httpAddr, nil)

	log.Info("running on ", addr)
	conf, err := router.LoadConf(configFile)
	if err != nil {
		log.PanicErrorf(err, "load config failed")
	}
	s, err := router.NewServer(addr, httpAddr, conf)
	if err != nil {
		log.PanicErrorf(err, "create new server failed")
	}
	if err := s.Serve(); err != nil {
		log.PanicErrorf(err, "serve failed")
	}
	panic("exit")
}