欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

etcd 服务注册和发现简介

最编程 2024-05-03 12:28:59
...
var ( cli *clientv3.Client Schema = "ns" Host = "127.0.0.1" Port = 3000 //端口 ServiceName = "api_log_service" //服务名称 EtcdAddr = "127.0.0.1:2379" //etcd地址 ) type ApiLogServer struct{} func (api *ApiLogServer) GetApiLogByUid(ctx context.Context, req *proto.ApiLogRequest) (*proto.ApiLogResponse, error) { resp := &proto.ApiLogResponse{ Msg: "ok", Data: "Hello", } return resp, nil } //将服务地址注册到etcd中 func register(etcdAddr, serviceName, serverAddr string, ttl int64) error { var err error if cli == nil { cli, err = clientv3.New(clientv3.Config{ Endpoints: strings.Split(etcdAddr, ";"), DialTimeout: 50 * time.Second, }) if err != nil { fmt.Printf("connection server err : %s\n", err) return err } } //与etcd建立长连接,并保证连接不断(心跳检测) ticker := time.NewTicker(time.Second * time.Duration(ttl)) go func() { key := "/" + Schema + "/" + serviceName + "/" + serverAddr for { resp, err := cli.Get(context.Background(), key) if err != nil { fmt.Printf("get server address err : %s", err) } else if resp.Count == 0 { //尚未注册 err = keepAlive(serviceName, serverAddr, ttl) if err != nil { fmt.Printf("keepAlive err : %s", err) } } <-ticker.C } }() return nil } //保持服务器与etcd的长连接 func keepAlive(serviceName, serverAddr string, ttl int64) error { //创建租约 leaseResp, err := cli.Grant(context.Background(), ttl) if err != nil { fmt.Printf("create grant err : %s\n", err) return err } //将服务地址注册到etcd中 key := "/" + Schema + "/" + serviceName + "/" + serverAddr _, err = cli.Put(context.Background(), key, serverAddr, clientv3.WithLease(leaseResp.ID)) if err != nil { fmt.Printf("register service err : %s", err) return err } //建立长连接 ch, err := cli.KeepAlive(context.Background(), leaseResp.ID) if err != nil { fmt.Printf("KeepAlive err : %s\n", err) return err } //清空keepAlive返回的channel go func() { for { <-ch } }() return nil } //取消注册 func unRegister(serviceName, serverAddr string) { if cli != nil { key := "/" + Schema + "/" + serviceName + "/" + serverAddr cli.Delete(context.Background(), key) } } func RunApiLog() { //监听网络 listener, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", Port)) if err != nil { fmt.Println("Listen network err :", err) return } defer listener.Close() //创建grpc srv := grpc.NewServer() defer srv.GracefulStop() //注册到grpc服务中 proto.RegisterApiLogServiceServer(srv, &ApiLogServer{}) //将服务地址注册到etcd中 serverAddr := fmt.Sprintf("%s:%d", Host, Port) fmt.Printf("rpc server address: %s\n", serverAddr) register(EtcdAddr, ServiceName, serverAddr, 10) //关闭信号处理 ch := make(chan os.Signal, 1) signal.Notify(ch, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL, syscall.SIGHUP, syscall.SIGQUIT) go func() { s := <-ch unRegister(ServiceName, serverAddr) if i, ok := s.(syscall.Signal); ok { os.Exit(int(i)) } else { os.Exit(0) } }() //监听服务 err = srv.Serve(listener) if err != nil { fmt.Println("rpc server err : ", err) return } } 复制代码

推荐阅读