一个基于 gin+ grpc + etcd 等框架开发的小栗子

一、标准的项目结构

首先我们看一个标准的项目结构是什么样子的,github 上给出的一个示例:golang-standards/project-layout

一个基于 gin+ grpc + etcd 等框架开发的小栗子

一个基于 gin+ grpc + etcd 等框架开发的小栗子

一个基于 gin+ grpc + etcd 等框架开发的小栗子

一个基于 gin+ grpc + etcd 等框架开发的小栗子

一个基于 gin+ grpc + etcd 等框架开发的小栗子

一个基于 gin+ grpc + etcd 等框架开发的小栗子

一个基于 gin+ grpc + etcd 等框架开发的小栗子

一个基于 gin+ grpc + etcd 等框架开发的小栗子

 一个基于 gin+ grpc + etcd 等框架开发的小栗子

 一个基于 gin+ grpc + etcd 等框架开发的小栗子

二、服务注册与发现流程

一个基于 gin+ grpc + etcd 等框架开发的小栗子

 三、示例代码

项目地址:gRPC-GoWeb

1、服务注册

服务注册和发现都可参考 etcd官网 的注册和发现流程,以下是项目的几个步骤的代码,详细的可下载项目查看。

 1、连接etcd注册中心

func New(etcdAddr []string) (*EtcdRegister, error) {     log.Printf("开始连接etcd注册中心... n")     cli, err := clientv3.New(clientv3.Config{         Endpoints:   etcdAddr,         DialTimeout: 5 * time.Second,     })     if err != nil {         log.Printf("连接etcd注册中心失败,失败原因是: %v n", err)         return nil, err     }     log.Printf("连接etcd注册中心成功! n")     return &EtcdRegister{         cli: cli,     }, nil }

2、服务注册

func (etcdRegister *EtcdRegister) Register(srvName string, srvAddr string, ttl int64) error {     etcdRegister.srvName = srvName     etcdRegister.srvAddr = srvAddr     log.Printf("开始创建etcd端点管理器... n")     em, err := endpoints.NewManager(etcdRegister.cli, srvName)     if err != nil {         log.Printf("创建etcd端点管理器失败,失败原因是: %v n", err)         return err     }     etcdRegister.em = em     log.Printf("创建etcd端点管理器成功! n")     log.Printf("开始创建服务租期... n")     lease, err := etcdRegister.cli.Grant(context.TODO(), ttl)     if err != nil {         log.Printf("创建服务租期失败,失败原因是: %v", err)     }     etcdRegister.ttl = ttl     etcdRegister.leaseID = lease.ID     log.Printf("创建服务租期成功! n")     log.Printf("开始注册服务,服务名: %s,服务地址: %s n", srvName, srvAddr)     em.AddEndpoint(context.TODO(), fmt.Sprintf("%v/%v", srvName, srvAddr), endpoints.Endpoint{Addr: srvAddr}, clientv3.WithLease(lease.ID))     if err != nil {         log.Printf("注册服务失败! n")         return err     }     log.Printf("注册服务成功! n")     log.Printf("开始服务定期续租! n")     leaseChan, err := etcdRegister.cli.KeepAlive(context.TODO(), etcdRegister.leaseID)     if err != nil {         log.Printf("服务定期续租失败! n")         return err     }     etcdRegister.leaseChan = leaseChan     log.Printf("服务定期续租成功! n")     return nil }

3、提供服务(需要用到Protobuf)

func init() {     pb.RegisterUserServiceServer(server.GrpcServer, &UserService{}) }

2、服务发现

1、服务发现

func (etcdDiscovery *etcdDiscovery) Discovery(srvName string) (*grpc.ClientConn, error) {     target := fmt.Sprintf("etcd:///%s", srvName)     conn, err := grpc.Dial(target, grpc.WithResolvers(etcdDiscovery.resolver), grpc.WithInsecure())     if err != nil {         log.Printf("%s服务发现失败,原因是: %v n", srvName, err)         return nil, err     }     return conn, nil }

2、调用服务方法

func UserRegister(ginCtx *gin.Context) {     etcdDiscovery := serviceDiscovery.EtcdCenter     //获取用户服务     conn, _ := etcdDiscovery.Discovery("study-user-service")     userService := pb.NewUserServiceClient(conn)     data, err := userService.SayHello(ginCtx, &pb.Request{})     if err != nil {         log.Printf("调用用户服务出错了,原因是: %v n", err)     }     ginCtx.JSON(200, gin.H{         "message": data,     }) }

备注:api-gateway 和 study-user-service 都使用了空导入的方式,所以主要看空导入的几个 init 函数,main 方法都是空的。

如果对 Go 的代码执行顺序不熟悉的,可以了解一下!

参考文献:

https://etcd.io/docs/v3.5/dev-guide/grpc_naming/

https://gin-gonic.com/zh-cn/docs/quickstart/

https://grpc.io/docs/languages/go/basics/

https://doc.oschina.net/grpc?t=60133

https://devpress.csdn.net/cloud/62f627bac6770329307fc0c9.html

发表评论

评论已关闭。

相关文章