一、标准的项目结构

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

二、服务注册与发现流程

三、示例代码

项目地址: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 的代码执行顺序不熟悉的,可以了解一下!

一个基于 gin+ grpc + etcd 等框架开发的小栗子的更多相关文章

  1. 【转】发布一个基于NGUI编写的UI框架

    发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...

  2. 发现了一个关于 gin 1.3.0 框架的 bug

    gin 1.3.0 框架 http 响应数据错乱问题排查 问题概述 客户端同时发起多个http请求,gin接受到请求后,其中一个接口响应内容为空,另外一个接口响应内容包含接口1,接口2的响应内容,导致 ...

  3. 基于mpvue的框架开发微信小程序(搭建环境)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_103 美团很早就开源了mpvue这个项目,如此看来,美团可不仅仅是一家团购网站,真正的技术驱动型企业,使得我们多了一种用来开发微信 ...

  4. mpvue 应用 Vant Weapp框架开发微信小程序

    今天在使用mpvue开发微信小程序的过程中需要实现一个底部上拉选择列表的功能,因为之前做过H5微信公众号的开发,使用的就是有赞的Vant-ui,所以第一时间就想到了有赞的Vant Weapp UI框架 ...

  5. 一个定时任务管理器,基于Go语言和beego框架开发

    链接 https://github.com/lisijie/webcron 安装说明 系统需要安装Go和MySQL. 获取源码 $ go get github.com/lisijie/webcron ...

  6. ShutIt:一个基于 Python 的 shell 自动化框架

    ShutIt是一个易于使用的基于shell的自动化框架.它对基于python的expect库(pexpect)进行了包装.你可以把它看作是“没有痛点的expect”.它可以通过pip进行安装. Hel ...

  7. 一个基于cocos2d-x 3.0和Box2d的demo小程序

    p图demo小应用.想怎么p就怎么p 本文參考于http://blog.csdn.net/xiaominghimi/article/details/6776096和http://www.cnblogs ...

  8. 部署wepy框架开发微信小程序

    我用的是yarn,如果你使用的是npm,也可以 首先需要安装wepy命令行工具 npm install wepy-cli -g 然后在选定的位置使用脚手架工具创建wepy项目 wepy init st ...

  9. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring使用AspectJ开发AOP基于XML和基于Annotation

    AspectJ 是一个基于 Java 语言的 AOP 框架,它扩展了 Java 语言.Spring 2.0 以后,新增了对 AspectJ 方式的支持,新版本的 Spring 框架,建议使用 Aspe ...

  10. 避免重复造轮子的UI自动化测试框架开发

    一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...

随机推荐

  1. TransmittableThreadLocal和@Async优雅的记录操作日志

    此文主要讲解: 如何实现操作记录 如何将TransmittableThreadLocal和@Async搭配使用 TransmittableThreadLocal阿里的一个开源组件,为了在使用线程池等会 ...

  2. Python全栈工程师之从网页搭建入门到Flask全栈项目实战(5) - Flask中的ORM使用

    1.理解ORM ORM是MTV模型里面的Model模型 ORM(Object Relational Mapping),对象关系映射 举例:学生选课 学生和课程这两个实体,一个学生可以选择多门课程,一个 ...

  3. 配置文件 数据库存储引擎 严格模式 MySQL字段基本数据类型

    目录 字符编码与配置文件 \s查看MySQL相关信息 修改配置文件my-default.ini 解决5.6版本字符编码问题 配置文件什么时候加载? 偷懒操作:输入mysql直接登录root账户 数据库 ...

  4. JavaSE流程学习图

  5. OpenJudge 1.8.11 图像旋转

    11:图像旋转 总时间限制: 1000ms 内存限制: 65536kB 描述 输入一个n行m列的黑白图像,将它顺时针旋转90度后输出. 输入 第一行包含两个整数n和m,表示图像包含像素点的行数和列数. ...

  6. 金融科技 DevOps 的最佳实践

    随着软件技术的发展,越来越多的企业已经开始意识到 DevOps 文化的重要价值.DevOps 能够消除改变公司业务开展方式,并以更快的速度实现交付,同时创建迭代反馈循环以实现持续改进.而对于金融科技( ...

  7. python 水仙花数、菱形、99乘法表、直角三角形

    空心菱形 i = 1 while i <= 3: # 控制行数 j = 1 k = 1 while j <= 3-i: # 控制空格数量 print(" ", end= ...

  8. Mybatis-9.28

    Mybatis-9.28 环境: JDK1.8 Mysql 5.7 maven 3.6.1 IDEA 回顾: JDBC Mysql Java基础 Maven Junit SSM框架:配置文件的. 最好 ...

  9. 如何用 Python 隐藏你的 API 密钥

    你好,我是悦创. 博客首发:https://bornforthis.cn/posts/19.html 有时您需要在代码中存储敏感信息,例如密码或 API 密钥,而在 Python 中最简洁的方法是使用 ...

  10. Java 进阶P-4.8+P-4.9

    Object类 Object类的函数 toString() equals() Java Object 类是所有类的父类,也就是说 Java 的所有类都继承了 Object,子类可以使用 Object ...