func (p *ThriftLoadBalanceServer) Run() { // // 1. 创建到zk的连接 // 127.0.0.1:5555 --> 127_0_0_1:5555 exitSignal := make(chan os.Signal, 1) signal.Notify(exitSignal, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) // syscall.SIGKILL // kill -9 pid // kill -s SIGKILL pid 还是留给运维吧 // // 注册服务 evtExit := make(chan interface{}) serviceEndpoint := RegisterService(p.serviceName, p.frontendAddr, p.lbServiceName, p.topo, evtExit, p.config.WorkDir, p.config.CodeUrlVersion) // var suideTime time.Time // isAlive := true // 3. 读取后端服务的配置 var transport thrift.TServerTransport var err error isUnixDomain := false // 127.0.0.1:9999(以:区分不同的类型) if !strings.Contains(p.frontendAddr, ":") { if FileExist(p.frontendAddr) { os.Remove(p.frontendAddr) } transport, err = NewTServerUnixDomain(p.frontendAddr) isUnixDomain = true } else { transport, err = thrift.NewTServerSocket(p.frontendAddr) } if err != nil { log.ErrorErrorf(err, "Server Socket Create Failed: %v", err) panic(fmt.Sprintf("Invalid FrontendAddress: %s", p.frontendAddr)) } err = transport.Listen() if err != nil { log.ErrorErrorf(err, "Server Socket Create Failed: %v", err) panic(fmt.Sprintf("Binding Error FrontendAddress: %s", p.frontendAddr)) } ch := make(chan thrift.TTransport, 4096) defer close(ch) // 强制退出? TODO: Graceful退出 go func() { <-exitSignal // 通知RegisterService终止循环 evtExit <- true log.Info(Green("Receive Exit Signals....")) serviceEndpoint.DeleteServiceEndpoint(p.topo) start := time.Now().Unix() for true { // 如果5s内没有接受到新的请求了,则退出 now := time.Now().Unix() if now-p.lastRequestTime.Get() > 5 { log.Printf(Red("[%s]Graceful Exit..."), p.serviceName) break } else { log.Printf(Cyan("[%s]Sleeping %d seconds before Exit...\n"), p.serviceName, now-start) time.Sleep(time.Second) } } transport.Interrupt() transport.Close() }() go func() { var address string for c := range ch { // 为每个Connection建立一个Session socket, ok := c.(SocketAddr) if ok { if isUnixDomain { address = p.frontendAddr } else { address = socket.Addr().String() } } else { address = "unknow" } x := NewNonBlockSession(c, address, p.verbose, &p.lastRequestTime) // Session独立处理自己的请求 go x.Serve(p.backendService, 1000) } }() // Accept什么时候出错,出错之后如何处理呢? for { c, err := transport.Accept() if err != nil { close(ch) break } else { ch <- c } } }
func (s *BackServiceLB) run() { go func() { // 定时汇报当前的状态 for true { log.Printf(Green("[Report]: %s --> %d workers, coroutine: %d"), s.serviceName, s.Active(), runtime.NumGoroutine()) time.Sleep(time.Second * 10) } }() var transport thrift.TServerTransport var err error // 3. 读取后端服务的配置 isUnixDomain := false // 127.0.0.1:9999(以:区分不同的类型) if !strings.Contains(s.backendAddr, ":") { if FileExist(s.backendAddr) { os.Remove(s.backendAddr) } transport, err = NewTServerUnixDomain(s.backendAddr) isUnixDomain = true } else { transport, err = thrift.NewTServerSocket(s.backendAddr) } if err != nil { log.ErrorErrorf(err, "[%s]Server Socket Create Failed: %v", s.serviceName, err) panic("BackendAddr Invalid") } err = transport.Listen() if err != nil { log.ErrorErrorf(err, "[%s]Server Socket Open Failed: %v", s.serviceName, err) panic("Server Socket Open Failed") } // 和transport.open做的事情一样,如果Open没错,则Listen也不会有问题 log.Printf(Green("[%s]LB Backend Services listens at: %s"), s.serviceName, s.backendAddr) s.ch = make(chan thrift.TTransport, 4096) // 强制退出? TODO: Graceful退出 go func() { <-s.exitEvt log.Info(Red("Receive Exit Signals....")) transport.Interrupt() transport.Close() }() go func() { var backendAddr string for trans := range s.ch { // 为每个Connection建立一个Session socket, ok := trans.(SocketAddr) if ok { if isUnixDomain { backendAddr = s.backendAddr } else { backendAddr = socket.Addr().String() } conn := NewBackendConnLB(trans, s.serviceName, backendAddr, s, s.verbose) // 因为连接刚刚建立,可靠性还是挺高的,因此直接加入到列表中 s.activeConnsLock.Lock() conn.Index = len(s.activeConns) s.activeConns = append(s.activeConns, conn) s.activeConnsLock.Unlock() log.Printf(Green("%s --> %d workers"), s.serviceName, conn.Index) } else { panic("Invalid Socket Type") } } }() // Accept什么时候出错,出错之后如何处理呢? go func() { for { c, err := transport.Accept() if err != nil { return } else { s.ch <- c } } }() }