func (p *ThriftRpcServer) Run() { // // 1. 创建到zk的连接 p.Topo = NewTopology(p.ProductName, p.ZkAddr) // 127.0.0.1:5555 --> 127_0_0_1:5555 lbServiceName := GetServiceIdentity(p.FrontendAddr) exitSignal := make(chan os.Signal, 1) signal.Notify(exitSignal, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL) // syscall.SIGKILL // kill -9 pid // kill -s SIGKILL pid 还是留给运维吧 StartTicker(p.config.FalconClient, p.ServiceName) // 初始状态为不上线 var state atomic2.Bool state.Set(false) stateChan := make(chan bool) // 注册服务 evtExit := make(chan interface{}) endpoint := RegisterService(p.ServiceName, p.FrontendAddr, lbServiceName, p.Topo, evtExit, p.config.WorkDir, p.config.CodeUrlVersion, &state, stateChan) // 3. 读取"前端"的配置 var transport thrift.TServerTransport var err error isUnixDomain := false // 127.0.0.1:9999(以:区分不同的类型) if !strings.Contains(p.FrontendAddr, ":") { if rpc_utils.FileExist(p.FrontendAddr) { os.Remove(p.FrontendAddr) } transport, err = rpc_utils.NewTServerUnixDomain(p.FrontendAddr) isUnixDomain = true } else { transport, err = thrift.NewTServerSocket(p.FrontendAddr) } if err != nil { log.ErrorErrorf(err, Red("Server Socket Create Failed: %v"), err) panic(fmt.Sprintf("Invalid FrontendAddr: %s", p.FrontendAddr)) } err = transport.Listen() if err != nil { log.ErrorErrorf(err, Red("Server Socket Open Failed: %v"), err) panic(fmt.Sprintf("Server Socket Open Failed: %s", p.FrontendAddr)) } ch := make(chan thrift.TTransport, 4096) defer close(ch) // 强制退出? TODO: Graceful退出 go func() { <-exitSignal evtExit <- true log.Info(Magenta("Receive Exit Signals....")) endpoint.DeleteServiceEndpoint(p.Topo) // 等待 start := time.Now().Unix() for true { // 如果5s内没有接受到新的请求了,则退出 now := time.Now().Unix() if now-p.lastRequestTime.Get() > 5 { log.Info(Red("Graceful Exit...")) break } else { log.Printf(Cyan("Sleeping %d seconds\n"), now-start) time.Sleep(time.Second) } } transport.Interrupt() transport.Close() }() go func() { var address string for c := range ch { // 为每个Connection建立一个Session socket, ok := c.(rpc_utils.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, 1000) } }() // 准备上线服务 state.Set(true) stateChan <- true // Accept什么时候出错,出错之后如何处理呢? for { c, err := transport.Accept() if err != nil { break } else { ch <- c } } }
// // 两参数是必须的: ProductName, zkAddress, frontAddr可以用来测试 // func (p *ProxyServer) Run() { var transport thrift.TServerTransport var err error log.Printf(Magenta("Start Proxy at Address: %s"), p.proxyAddr) // 读取后端服务的配置 isUnixDomain := false if !strings.Contains(p.proxyAddr, ":") { if rpc_utils.FileExist(p.proxyAddr) { os.Remove(p.proxyAddr) } transport, err = rpc_utils.NewTServerUnixDomain(p.proxyAddr) isUnixDomain = true } else { transport, err = thrift.NewTServerSocket(p.proxyAddr) } if err != nil { log.ErrorErrorf(err, "Server Socket Create Failed: %v, Front: %s", err, p.proxyAddr) } // 开始监听 // transport.Open() transport.Listen() ch := make(chan thrift.TTransport, 4096) defer close(ch) defer func() { log.Infof(Red("==> Exit rpc_proxy")) if err := recover(); err != nil { log.Infof("Error rpc_proxy: %s", err) } }() go func() { var address string for c := range ch { // 为每个Connection建立一个Session socket, ok := c.(rpc_utils.SocketAddr) if isUnixDomain { address = p.proxyAddr } else if ok { address = socket.Addr().String() } else { address = "unknow" } x := NewSession(c, address, p.verbose) // Session独立处理自己的请求 go x.Serve(p.router, 1000) } }() // Accept什么时候出错,出错之后如何处理呢? for { c, err := transport.Accept() if err != nil { log.ErrorErrorf(err, "Accept Error: %v", err) break } else { ch <- c } } }
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{}) // 初始状态为不上线 var state atomic2.Bool state.Set(false) stateChan := make(chan bool) serviceEndpoint := RegisterService(p.serviceName, p.frontendAddr, p.lbServiceName, p.topo, evtExit, p.config.WorkDir, p.config.CodeUrlVersion, &state, stateChan) // 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 rpc_utils.FileExist(p.frontendAddr) { os.Remove(p.frontendAddr) } transport, err = rpc_utils.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) // 等待后端服务起来 waitTicker := time.NewTicker(time.Second) // 等待上线采用的策略: // 1. 检测到有效的Worker注册之后,再等5s即可像zk注册; 避免了Worker没有连接上来,就有请求过来 // 2. 一旦注册之后,就不再使用该策略;避免服务故障时,lb频繁更新zk, 导致proxy等频繁读取zk START_WAIT: for true { select { case <-waitTicker.C: if p.backendService.Active() <= 0 { log.Infof("Sleep Waiting for back Service to Start") time.Sleep(time.Second) } else { break START_WAIT } case <-exitSignal: // 直接退出 transport.Interrupt() transport.Close() return } } log.Infof("Stop Waiting") // 停止: waitTicker, 再等等就继续了 waitTicker.Stop() time.Sleep(time.Second * 5) log.Infof("Begin to Reg To Zk...") state.Set(true) stateChan <- true // 强制退出? 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.(rpc_utils.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 } } }