一个基于 gin+ grpc + etcd 等框架开发的小栗子
一、标准的项目结构
首先我们看一个标准的项目结构是什么样子的,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 等框架开发的小栗子的更多相关文章
- 【转】发布一个基于NGUI编写的UI框架
发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...
- 发现了一个关于 gin 1.3.0 框架的 bug
gin 1.3.0 框架 http 响应数据错乱问题排查 问题概述 客户端同时发起多个http请求,gin接受到请求后,其中一个接口响应内容为空,另外一个接口响应内容包含接口1,接口2的响应内容,导致 ...
- 基于mpvue的框架开发微信小程序(搭建环境)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_103 美团很早就开源了mpvue这个项目,如此看来,美团可不仅仅是一家团购网站,真正的技术驱动型企业,使得我们多了一种用来开发微信 ...
- mpvue 应用 Vant Weapp框架开发微信小程序
今天在使用mpvue开发微信小程序的过程中需要实现一个底部上拉选择列表的功能,因为之前做过H5微信公众号的开发,使用的就是有赞的Vant-ui,所以第一时间就想到了有赞的Vant Weapp UI框架 ...
- 一个定时任务管理器,基于Go语言和beego框架开发
链接 https://github.com/lisijie/webcron 安装说明 系统需要安装Go和MySQL. 获取源码 $ go get github.com/lisijie/webcron ...
- ShutIt:一个基于 Python 的 shell 自动化框架
ShutIt是一个易于使用的基于shell的自动化框架.它对基于python的expect库(pexpect)进行了包装.你可以把它看作是“没有痛点的expect”.它可以通过pip进行安装. Hel ...
- 一个基于cocos2d-x 3.0和Box2d的demo小程序
p图demo小应用.想怎么p就怎么p 本文參考于http://blog.csdn.net/xiaominghimi/article/details/6776096和http://www.cnblogs ...
- 部署wepy框架开发微信小程序
我用的是yarn,如果你使用的是npm,也可以 首先需要安装wepy命令行工具 npm install wepy-cli -g 然后在选定的位置使用脚手架工具创建wepy项目 wepy init st ...
- 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring使用AspectJ开发AOP基于XML和基于Annotation
AspectJ 是一个基于 Java 语言的 AOP 框架,它扩展了 Java 语言.Spring 2.0 以后,新增了对 AspectJ 方式的支持,新版本的 Spring 框架,建议使用 Aspe ...
- 避免重复造轮子的UI自动化测试框架开发
一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...
随机推荐
- 《MySQL必知必会》知识汇总二
六.用通配符进行过滤 本章介绍什么是通配符.如何使用通配符以及怎样使用LIKE操作符进行通配搜索 LIKE操作符 百分号(%)通配符 select prod_id,prod_name from pro ...
- 【PostgreSQL】PG通过SQL语句读取二进制bytea类型并进行二进制和十六进制转换
1.将二进制编码为十六进制 select encode("AUUID_0",'hex'),"AUUID_0" from wxf_test."ABANK ...
- 【Java SE进阶】Day10 缓冲流、转换流、序列化流 、打印流
一.缓冲流 1.概述 比普通流更强大的IO流,可以增加读写的效率 组成 缓冲输入流:BufferedInputStream.BufferedReader 缓冲输出流:BufferedOutputStr ...
- 万字干货|Synchronized关键字详解
作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA底层.面试.职业成长相关资料等更多精彩文章在公众号「小牛呼噜噜」 前言 大家好,我是呼噜噜,在之前的文章中 ...
- JavaScript入门⑧-事件总结大全
JavaScript入门系列目录 JavaScript入门①-基础知识筑基 JavaScript入门②-函数(1)基础{浅出} JavaScript入门③-函数(2)原理{深入}执行上下文 JavaS ...
- 使用JavaScript制作一个页面的电子时钟
题目:做一个电子时钟,显示当前的年月日,时分秒,要求自动变化. 案例分析: 1.使用一个div盒子来展示时钟的内容: 2.将盒子在JavaScrip里面获取div盒子: 3.我们需要一个定时器setI ...
- 「Docker学习系列教程」9-Docker容器数据卷介绍
通过前面8篇文章的学习,我们已经学会了docker的安装.docker常用的命令已经docker镜像修改后提交的远程镜像仓库及提交到公司的私服仓库中.接下来,我们再来学学Docker另外一个重要的东西 ...
- m3u8文件后缀jpg,png等处理方法及视频合并
处理 # 解析伪装成png的ts def resolve_ts(src_path, dst_path): ''' 如果m3u8返回的ts文件地址为 https://p1.eckwai.com/ufil ...
- 我的基于 JamStack 的新博客
概述 今天心血来潮,介绍一下我的新博客站点 -- https://EWhisper.cn. 我是做基础平台 PaaS 运维和架构的,挺喜欢把工作中学到的新知识写下来.记笔记,突然有一天就抱着「资源共享 ...
- 原生js实现rsa加密
原生js实现rsa加密 示例 createNewUserKey().then(function(keyPairs) { encrypt("this is origin text", ...