func main() { initEnv() log.Printf("[GUARDKEEPER]Now begin to start guardkeeper...") if *MONITOR_INTERVAL <= 0 { log.Println("[GUARDKEEPER]the param: monitorInterval is less than 0!") os.Exit(2) } for { if !common.FileExists(signPath, signFile) { log.Println("[GUARDKEEPER]sign file not found yet, path: " + signPath + ", filename: " + signFile + " please wait...") time.Sleep(time.Duration(*MONITOR_INTERVAL) * time.Second) continue } log.Println("[GUARDKEEPER]found the sign file!") break } // hostIp := common.GetHostIp() hostName := common.GetHostName() realIp := common.GetShell("ifconfig eth0 | grep \"inet addr\" | awk '{print $2}' | awk -F: '{print $2}'") // 选用--net=bridge方式的话,则进行ip替换。 // commandCore := fmt.Sprintf("s/%s\t%s/%s\t%s/g", hostIp, hostName, realIp, hostName) // common.GetShell("sed \"" + commandCore + "\" /etc/hosts > out.tmp && cat out.tmp > /etc/hosts && rm -f out.tmp") // 选用--net=none方式的话,那么/etc/hosts里面不会有ip\tport信息。此时直接往里面插就行。 common.GetShell(fmt.Sprintf("echo \"%s\t%s\" >> /etc/hosts", realIp, hostName)) log.Println("[GUARDKEEPER]now begin to execute supervisord!") log.Fatalln("[GUARDKEEPER]Error...", common.GetShell("/usr/bin/supervisord")) }
func initEnv() { // 让命令行的命令生效 flag.Parse() // 初始化一些初始变量 serviceIp = common.GetHostIp() serviceName = os.Getenv("SERVICE_NAME") common.Assert(serviceName) servicePort = os.Getenv("SERVICE_PORT") common.Assert(servicePort) // 直接以容器ID + ServiceName来命名,确保唯一。如果后续发现容器ID不唯一,那么就再加上宿主机IP // serviceId = strconv.FormatInt(time.Now().Unix(), 10) + "_" + serviceName serviceId = common.GetHostName() + "_" + serviceName signFile = "/home/work/data/$(hostname)/kickoff_sign_file" isNormal = false // 给一个channel,如果没有严重错误就永久等待 fatalExit = make(chan int) }
func main() { initEnv() // 持续监听指定端口号,采用netstat -nlp | grep ":$PORT"来实现,隔5s来一次 log.Printf("[REGISTRATOR]Now begin to listen service: %s with service port: %s.", serviceName, servicePort) if *monitorInterval <= 0 { log.Println("[REGISTRATOR]the param: monitorInterval is less than 0!") os.Exit(2) } // ticker := time.NewTicker(time.Duration(*monitorInterval) * time.Millisecond) log.Println("[REGISTRATOR]Now begin to listen the port...") for { if !common.PortExists(servicePort) { // 说明启动还未成功 log.Println("[REGISTRATOR]Not found port for registration, please wait...") time.Sleep(time.Duration(*monitorInterval) * time.Millisecond) continue } log.Println("[REGISTRATOR]found the port for registration!") isNormal = true break } // 启动成功的话,就先初始化consul客户端 log.Println("[REGISTRATOR]Now begin to process registration!") consulClient, _ = consulApi.NewClient(defaultConfig()) // 然后调用consulapi进行注册 register() updateState(common.GetHostName(), mongo.CONTAINER_STATE_ALL_UP) log.Println("[REGISTRATOR]Now finished registration!") // 启动自动监控功能,当端口不在的时候,能够取消注册 ticker := time.NewTicker(time.Duration(*monitorInterval) * time.Second) go func() { for { select { case <-ticker.C: log.Println("[REGISTRATOR]Now in a loop monitor ticket time!") if common.PortExists(servicePort) { if !isNormal { log.Println("[REGISTRATOR]Now begin to register!") isNormal = true register() // 注册信号量 updateState(common.GetHostName(), mongo.CONTAINER_STATE_ALL_UP) } } else { if isNormal { log.Println("[REGISTRATOR]Now begin to deregister!") isNormal = false deregister() // 取消信号量。如果是容器北山,就已经至少被mask掉了。 updateState(common.GetHostName(), mongo.CONTAINER_STATE_ERROR) } } } } }() log.Fatalln("[REGISTRATOR]Error...", <-fatalExit) }
func initEnv() { flag.Parse() signPath = "/home/work/data/" + common.GetHostName() + "/" signFile = "kickoff_sign_file" }