上一篇文章我们用etcd做为服务发现组件,替换了micro默认的基于mnds的服务发现,并简单通过跟踪源码了解了服务注册以及发现的原理。这篇文章,我们来认识微服务架构中另外一个很常见的东东:API Gateway。

1、API网关是什么

我们把一个应用拆分成了一个一个的微服务后,客户端如何调用就是个问题,因为服务是部署在不同的机器上面,这样客户端(比如iOS,android,web)势必将使用很多不同的URL,API网关最主要的作用实际上就是作为一个统一的入口,所有的请求都指向网关,再由网关负责协议转换,并将请求路由到后端服务上,以下是micro github主页上关于api gateway的一张图:

除了做为统一的请求入口外,API网关还具备安全防护、限流、熔断等功能。通常大厂都有自己自研的一套网关用来接入其内部服务,比如腾讯的TGW。

micro框架也实现了基于HTTP协议的网关,用户通过http协议向网关发送请求,再由网关将请求转发给后端服务。

从安全性来讲,micro实现的这个网关支持ACME和TLS。

至于网关的性能,目前还没做过测试,不得而知,因为网关并不做特别重的逻辑,主要是负责转发请求,因此猜测中小规模的APP应该是可以支持到。

2、增加网关支持

现在我们就继续开撕代码,给我们的示例程序加个网关玩玩。

先来看看micro api的基本用法,我们再命令行输入:micro api --help,可以看到以下输出:

我们用到以下几个选项:

--address:指定网关地址,默认实在8080端口

--namespace:可以通过namespace将服务归类,例如对外的公共服务和内部服务,注意这里的域名要跟代码对应起来,比如域名为com.test.api,那么代码中的服务名就要以com.test.api开头。

--handler:网关用到的http handler,不同的handler处理不同的请求,对请求的处理方式也有所不同,micro支持以下几种handler:

api handler:可以处理任意http请求,并以RPC的方式将请求转发给后端服务,url path为/service/method,例如http://localhost:8080/greeter/hello,则网关会在注册中心中寻找endpoints为Greeter.Hello的服务并转发;

rpc handler:处理http post请求,http body为json或者protobuf格式(Content-Type为application/json或者application/protobuf),url path的要求同api handler;

event handler:将请求做为消息发送到消息中间件上;

proxy handler:用于http反向代理;

具体用哪种handler需要根据自己业务的需求来定,我们就用rpc handler来实操一下。

2.1 启动网关

我们先来启动网关:

注意在启动网关时的一些参数:

MICRO_REGISTRY:用来指定注册中心,我们用etcd做注册中心,所以这个值写etcd;

MICRO_REGISTRY_ADDRESS:指定注册中心的地址,本地测试,就写本机地址(etcd默认端口是2379)

--handler:我们采用rpc handler,网关将会根据服务的EndPoint找到服务并转发请求;

--namespace:指定命名空间

--address:网关地址

2.2 修改代码

服务端的代码与之前一样,我们稍作修改,改一下服务名:

package mainimport ("context""fmt""github.com/micro/go-micro/v2""micro/proto/pb""micro/registry/etcd"
)type Greeter struct {}func (g *Greeter) Hello(ctx context.Context, req *pb.Request, rsp *pb.Response) error  {//把客户端的请求回射给客户端rsp.Msg = req.Namereturn nil
}func main() {// 新创建一个服务,服务名为greeter,服务注册中心会用这个名字来发现服务service := micro.NewService(micro.Name("svr.greeter"),micro.Registry(etcd.NewRegistry()),)// 初始化service.Init()// 注册处理器pb.RegisterGreeterHandler(service.Server(), new(Greeter))// 启动服务运行if err := service.Run(); err != nil {fmt.Println(err)}
}

我们只是在创建服务的时候将服务名改成了svr.greeter,其他没有任何变化。

然后在终端启动运行服务即可。

下面要修改客户端,客户端实际上是服务端的一个代理,从设计模式的角度来看实际上就是个代理模式,因此客户端和服务端需要实现相同的接口,在客户端可以做一些额外的操作(比如参数安全校验之类的),然后通过rpc调用服务端。

package mainimport ("context""fmt""github.com/micro/go-micro/v2""micro/proto/pb""micro/registry/etcd"
)const (apiNameSpace   = "com.jupiter.api"service        = "greeter"backendService = "svr.greeter" //真正做事情的后端服务
)/*** url path:/greeter/hello* 接收网关转发的请求,通过rpc将请求转发给后端服务* 实际上就是个后端服务的代理(客户端),实现和服务端相同的接口*/
type Greeter struct {Client pb.GreeterService
}func (g *Greeter) Hello(ctx context.Context, req *pb.Request, rsp *pb.Response) error {//通过rpc调用服务端response, e := g.Client.Hello(ctx, &pb.Request{Name: "Hello Micro"})if e != nil {return e}rsp.Msg = response.Msgreturn nil
}func main() {// 创建一个服务service := micro.NewService(micro.Name(apiNameSpace + "." + service),   //注意这里服务的名称:namespace + service,这样网关才能找的到micro.Registry(etcd.NewRegistry()))// 初始化service.Init()pb.RegisterGreeterHandler(service.Server(), &Greeter{Client: pb.NewGreeterService(backendService, service.Client()),})if err := service.Run(); err != nil {fmt.Println(err)}
}

以上代码中关键的地方都做了注释,在强调一下:

代理服务的名称必须是namespace.service,namespace是api网关的namespace,service是在注册中心的EndPoint的服务名,这个名称一般就是.proto协议文件中定义的service的名字,例如我们的.proto定义:

// 定义微服务对外提供的接口
service Greeter {rpc Hello(Request) returns (Response) {}
}

那么service就是Greeter,完整的名称就是com.jupiter.api.greeter。

现在我们再终端启动客户端运行。

2.3 测试

现在来测试一下加了网关后的服务,我们再终端用curl请求一下:

输出了我们想要的结果!

3 小结

这篇文章我们进一步扩展了微服务示例代码,在应用中加入了API网关,统一请求入口,现在我们这个极简单的微服务已经是“麻雀虽小五脏俱全了”

Go语言微服务实战之API网关相关推荐

  1. Spring微服务实战第2章 使用Spring Boot构建微服务

    第2章 使用Spring Boot构建微服务 基于微服务的架构具有以下特点. 有约束的--微服务具有范围有限的单一职责集.微服务遵循UNIX的理念,即应用程序是服务的集合,每个服务只做一件事,并只做好 ...

  2. 微服务架构开发实战:API网关意义和常见API网关的实现方式

    API网关意义 API网关旨在用一套单一且统一的API入口点,来组合一个或多个内部API. API网关定位为应用系统服务接口的网关,区别于网络技术的网关,但是原理是一样的.API网关统一服务入口,可方 ...

  3. Spring微服务实战第9章 使用Spring Cloud Sleuth和Zipkin进行分布式跟踪

    文章目录 第9章 使用Spring Cloud Sleuth和Zipkin进行分布式跟踪 9.1 Spring Cloud Sleuth与关联ID 9.1.1 将Spring Cloud Sleuth ...

  4. go语言高并发与微服务实战_go-micro+gin+etcd微服务实战之服务注册与发现

    在构建微服务时,使用服务发现可以减少配置的复杂性,本文以go-micro为微服务框架,使用etcd作为服务发现服务,使用gin开发golang服务. 使用gin 的原因是gin能够很好的和go-mic ...

  5. Spring微服务实战第1章 欢迎迈入云世界,Spring

    第1章 欢迎迈入云世界,Spring 1.1 什么是微服务 微服务架构具有以下特征. 应用程序逻辑分解为具有明确定义了职责范围的细粒度组件,这些组件互相协调提供解决方案. 每个组件都有一个小的职责领域 ...

  6. 微服务实战之Prometheus使用分享

    tonyyan https://www.jianshu.com/p/67ec2643c963 Prometheus是什么? Prometheus 是由 SoundCloud 开源监控告警解决方案,从 ...

  7. .Net微服务实战之DevOps篇

    技术只是基础 该系列的两篇文章<.Net微服务实战之技术选型篇>和<.Net微服务实战之技术架构分层篇>都是以技术角度出发描述微服务架构的实施. 如果技术选型篇叙述的是工具,那 ...

  8. 微软Azure AspNetCore微服务实战第2期(内附PPT下载)

    2018年1月28日,虽然上海的大雪在城区已经见不到踪影,但还是很冷.不过天气再冷,也阻止不了小伙伴参加活动的热情. 感谢王振,苏老师以及微软Azure API Management的产品经理Alvi ...

  9. 《Spring Cloud微服务实战》100本赠书获得名单

    点击蓝色"程序猿DD"关注我哟 3月14日第三期送书活动已经结束 本次活动共有三千多位朋友参加 感谢大家对我们的支持. 本次活动一共赠书100本<Spring Cloud微服 ...

最新文章

  1. ironbot智能编程机器人_视频 | 多模式编程机器人,“程序猿”培养从小抓起
  2. 远程连接Linux,如何使程序断开连接后继续运行
  3. Dialog源码分析
  4. 这两天一直在捣腾lucene
  5. 面向切面编程--AOP(二)
  6. Golang——时间日期函数
  7. 发现读纸质媒介比电子媒介的乐趣大多了
  8. 一文搞懂Oracle 0 至 6 级锁(附案例详解)
  9. 新款iPhone SE发布日期曝光:小屏果粉早已按捺不住
  10. SQL Server面试集合
  11. 微信小程序template模板 ,提高效率第二篇
  12. matlab和vc联合编程
  13. java 曲线纠缠_穿过已知点画平滑曲线(3次贝塞尔曲线)
  14. Greenplum删除segment节点
  15. 图像处理与机器视觉初学者学习路线
  16. python web前端 java ui学哪个好_学IT选Java还是Python?就业发展有何区别?
  17. 安装好kali后必做的5件事
  18. 今天收到了Joost的邀请
  19. 关于Marathon-lb
  20. PADS Router 布线前Layout设置和布线

热门文章

  1. 水经注离线三维地球触摸GIS系统
  2. 鸿蒙未识绮罗香,《贫女·蓬门未识绮罗香》阅读答案与解析-秦韬玉
  3. 第5次作业+037+吴烨倩
  4. 长城欧拉,一个最伤女人“芯”的汽车品牌
  5. Linux基本常见指令
  6. 大数据之linux虚拟机的复制以及环境配置
  7. 3225的晶体一脚和三脚有什么区别
  8. HTML5与Flash对比
  9. cocos2dx3.2打包apk
  10. 2018.06.16软件更新公告