Exemple #1
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
}
Exemple #2
0
func (top *Topology) InitZkConn() {
	var err error
	// 连接到zk
	// 30s的timeout
	top.ZkConn, err = zkhelper.ConnectToZk(top.zkAddr, 30) // 参考: Codis的默认配置
	if err != nil {
		log.PanicErrorf(err, "init failed")
	}
}
Exemple #3
0
// Router负责监听zk中服务列表的变化
func (bk *Router) WatchServices() {
	var evtbus chan interface{} = make(chan interface{}, 2)

	// 1. 保证Service目录存在,否则会报错
	servicesPath := bk.topo.ProductServicesPath()
	_, e1 := bk.topo.CreateDir(servicesPath)
	if e1 != nil {
		log.PanicErrorf(e1, "Zk Path Create Failed: %s", servicesPath)
	}

	go func() {
		for true {
			// 无限监听
			services, err := bk.topo.WatchChildren(servicesPath, evtbus)

			if err == nil {
				bk.serviceLock.Lock()
				// 保证数据更新是有效的
				oldServices := bk.services
				bk.services = make(map[string]*BackService, len(services))
				for _, service := range services {
					log.Println("Found Service: ", Magenta(service))

					back, ok := oldServices[service]
					if ok {
						bk.services[service] = back
						delete(oldServices, service)
					} else {

						bk.addBackService(service)
					}
				}
				if len(oldServices) > 0 {
					for _, conn := range oldServices {
						// 标记下线(现在应该不会有新的请求,最多只会处理一些收尾的工作
						conn.Stop()
					}

				}

				bk.serviceLock.Unlock()

				// 等待事件
				<-evtbus
			} else {
				log.ErrorErrorf(err, "zk watch error: %s, error: %v\n",
					servicesPath, err)
				time.Sleep(time.Duration(5) * time.Second)
			}
		}
	}()

	// 读取zk, 等待
	log.Println("ProductName: ", Magenta(bk.topo.ProductName))
}
func RpcMain(binaryName string, serviceDesc string, configCheck ConfigCheck,
	serverFactory ServerFactorory, buildDate string, gitVersion string) {

	// 1. 准备解析参数
	usage = fmt.Sprintf(usage, binaryName, binaryName)

	version := fmt.Sprintf("Version: %s\nBuildDate: %s\nDesc: %s\nAuthor: [email protected]", gitVersion, buildDate, serviceDesc)
	args, err := docopt.Parse(usage, nil, true, version, true)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if s, ok := args["-V"].(bool); ok && s {
		fmt.Println(Green(version))
		os.Exit(1)
	}

	// 这就是为什么 Codis 傻乎乎起一个 http server的目的
	if s, ok := args["--profile-addr"].(string); ok && len(s) > 0 {
		go func() {
			log.Printf(Red("Profile Address: %s"), s)
			log.Println(http.ListenAndServe(s, nil))
		}()
	}

	// 2. 解析Log相关的配置
	log.SetLevel(log.LEVEL_INFO)

	var maxKeepDays int = 3
	if s, ok := args["--log-keep-days"].(string); ok && s != "" {
		v, err := strconv.ParseInt(s, 10, 32)
		if err != nil {
			log.PanicErrorf(err, "invalid max log file keep days = %s", s)
		}
		maxKeepDays = int(v)
	}

	// set output log file
	if s, ok := args["-L"].(string); ok && s != "" {
		f, err := log.NewRollingFile(s, maxKeepDays)
		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)
	log.SetFlags(log.Flags() | log.Lshortfile)

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

	// 没有就没有
	workDir, _ := args["--work-dir"].(string)
	codeUrlVersion, _ := args["--code-url-version"].(string)
	if len(workDir) == 0 {
		workDir, _ = os.Getwd()
	}

	log.Printf("WorkDir: %s, CodeUrl: %s, Wd: %s", workDir, codeUrlVersion)

	// 3. 解析Config
	configFile := args["-c"].(string)
	conf, err := LoadConf(configFile)
	if err != nil {
		log.PanicErrorf(err, "load config failed")
	}

	// 额外的配置信息
	conf.WorkDir = workDir
	conf.CodeUrlVersion = codeUrlVersion

	if configCheck != nil {
		configCheck(conf)
	} else {
		log.Panic("No Config Check Given")
	}
	// 每次启动的时候都打印版本信息
	log.Infof(Green("-----------------\n%s\n--------------------------------------------------------------------"), version)

	// 启动服务
	server := serverFactory(conf)
	server.Run()
}
Exemple #5
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{}

	// 读取product
	conf.ProductName, _ = c.ReadString("product", "test")
	if len(conf.ProductName) == 0 {
		log.Panicf("invalid config: product entry is missing in %s", configFile)
	}

	// 读取zk
	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)

	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.ZkSessionTimeout = loadConfInt("zk_session_timeout", 30)
	conf.Verbose = loadConfInt("verbose", 0) == 1

	conf.Service, _ = c.ReadString("service", "")
	conf.Service = strings.TrimSpace(conf.Service)

	conf.FrontHost, _ = c.ReadString("front_host", "")
	conf.FrontHost = strings.TrimSpace(conf.FrontHost)

	conf.FrontPort, _ = c.ReadString("front_port", "")
	conf.FrontPort = strings.TrimSpace(conf.FrontPort)

	conf.FrontSock, _ = c.ReadString("front_sock", "")
	conf.FrontSock = strings.TrimSpace(conf.FrontSock)
	// 配置文件中使用的是相对路径,在注册到zk时,需要还原成为绝对路径
	if len(conf.FrontSock) > 0 {
		dir, _ := os.Getwd()
		conf.FrontSock = path.Clean(path.Join(dir, conf.FrontSock))
	}

	conf.IpPrefix, _ = c.ReadString("ip_prefix", "")
	conf.IpPrefix = strings.TrimSpace(conf.IpPrefix)

	// 注意先后顺序:
	// FrontHost, FrontPort, IpPrefix之后才能计算FrontendAddr
	conf.FrontendAddr = conf.getFrontendAddr(conf.FrontHost, conf.IpPrefix, conf.FrontPort)

	conf.BackAddr, _ = c.ReadString("back_address", "")
	conf.BackAddr = strings.TrimSpace(conf.BackAddr)

	conf.ProxyAddr, _ = c.ReadString("proxy_address", "")
	conf.ProxyAddr = strings.TrimSpace(conf.ProxyAddr)

	conf.FalconClient, _ = c.ReadString("falcon_client", "")

	profile, _ := c.ReadInt("profile", 0)
	conf.Profile = profile == 1
	return conf, nil
}