本文暂不介绍GRPC,只介绍通过HTTP方式进行服务间的API调用。且所有示例均采用Go Mod方式管理依赖包。
1.Go-Micro微服务框架简介
Go-Micro类似Java中的SpringCloud,虽然生态上有一些区别,但是可以类比比较。官当Github地址为 github.com/micro/go-mi…,下载安装依赖命令:
1 | go复制代码go get -u github.com/micro/go-micro |
2.创建Web服务
Golang本身提供了丰富的http包,并且Gin等Web框架实现一个Web服务,但是为了贴合Go-Micro框架的统一规范,所以需要通过使用Go-Micro的github.com/micro/go-micro/web
包来创建一个Web服务。
第一种方式:
直接通过web
包创建一个服务,参数可选,也比较简单易懂,请自行Ctrl+左键
查看源码。创建服务后可以直接像原生的http
包一样使用。
1 | go复制代码func main() { |
第二种方式:
原生的http
包在很多情况下处理并不是非常高效,只是提供了一些基础功能,所以Go-Micro提供集成第三方Web框架如:Gin。首先下载安装:
1 | go复制代码go get -u "github.com/gin-gonic/gin" |
Go-Micro整合Gin示例:
1 | go复制代码func main() { |
除了上述的方式直接指定Web服务的相关参数,我们也可以通过命令行参数启动Web服务,这样我们可以在命令行通过指定不同的服务名和端口,快速的多开同一个服务。虽然实际开发部署环境很少用这种方式,但在我们自己调试服务注册与发现时,会非常有用。
示例如下,只需要调用Init()
方法即可,可自行查看源码,源码中可查看有关的命令函参数名:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 > go复制代码func main() {
> engine := gin.Default()
> engine.GET("/hello", func(c *gin.Context) {
> c.JSON(http.StatusOK, gin.H{
> "msg": "hello,world",
> })
> })
> service := web.NewService(
> //web.Name("cas"),
> //web.Address(":80"),
> web.Handler(engine),
> )
> service.Init()
> service.Run()
> }
>
>
启动命令:
1
2
3 > go复制代码go run main.go -server_name cas -server_address :8001
>
>
3.服务注册
3.1 Consul
以Consul作为注册中心,官方下载地址:www.consul.io/downloads.h…。
Windows环境安装:
- 直接下载后将
consul.exe
解压出来; - 将其所解压到的目录文件名添加到path环境变量;
- 在 cmd 命令窗口中执行:
consul agent -dev
命令即可启动Consul服务 - Consul 自带 UI 管理界面,访问地址:
http://localhost:8500
,可以看到当前注册的服务:
Linux环境安装:
- 直接通过官网Linux版本Download处对应的地址下载:
wget https://releases.hashicorp.com/consul/1.9.0/consul_1.9.0_linux_amd64.zip
; - 解压:
unzip consul_1.9.0_linux_amd64.zip
; - 修改权限:
chmod 777 consul
; - 整理一下,将
consul
文件夹复制到/usr/local/bin/
目录下:cp consul /usr/local/bin/
; - 输入consul命令查看安装是否成功:
consul version
; - 启动consul,并通过
-client
配置外网主机可访问:consul agent -dev -client=0.0.0.0
;
当然其实最方便的就是直接通过docker拉个镜像,直接映射端口跑起来就可以了~
服务注册到Consul:
在安装好Consul并启动好服务后,下载Go-Micro提供的插件包go-plugins
:
1 | go复制代码go get -u github.com/micro/go-plugins |
该包包含了Consul和其他的众多插件(如:eureka等),基本的使用方法是使用consul.NewRegistry()
接口创建注册中心对象,然后将其集成到Go-Micro提供的Web服务配置中:
1 | go复制代码package main |
可以在Consul管理UI看到服务已经注册成功~
3.2 etcd
4 服务发现
从注册中心拿服务的方法也比较简单,简单几步即可拿到服务信息:
- 同服务注册一样,首先创建Consul注册中心对象:
consul.NewRegistry()
; - 通过Consul对象调用
GetService("cas")
方法拿到服务节点切片,参数为注册的服务名,所以在上文注册服务时指定的服务名很关键; - 通过Go-Micro提供的
selector
包拿到具体的服务节点,该包提供2种常见的负载均衡算法,RoundRobin(轮询)
和Random(随机)
。对应方法返回的是一个Next
方法,Next
方法调用后才返回具体的服务节点,可以自行查看源码; - 拿到具体的服务节点结构体对象后,则可以通过服务的IP等信息,发起HTTP的API调用。
示例代码和运行结果:
1 | go复制代码package main |
1 | go复制代码//运行打印的log内容 |
如果启动时发生依赖报错,请参考我的另一篇博文对该问题的解决:Go-Micro启动依赖报错解决方法 。如要查看轮询或随机效果,可以自己写一个for循环间隔获取节点,查看节点信息的变化情况~
5.服务调用
5.1 HTTP基本调用方式
最基础的就是通过Golang官方提供的http
包发起HTTP请求。直接在上文服务发现示例代码的基础上,在拿到服务节点信息后,发情API请求。
1 | go复制代码package main |
5.1 Go-Micro中的HTTP调用方式(推荐)
这种方式也是使用http
包,但和上述Golang官方提供的不同,这种方式使用的是Go-Micro的插件包go-plugins
,具体为:"github.com/micro/go-plugins/client/http"
包,go-plugins
包除了有http client的基本功能,还支持Selector
参数,自动选取服务,并支持json、protobuf等数据格式。
上述的基础调用方式可以明显发现调用过程其实还是比较繁琐的,而这种方法流程上简化了很多,插件对一些步骤进行了封装和自动化处理,步骤主要为将注册中心放到Selector选择器中,然后基于选择器创建httpClient,通过该客户端来发起请求,调用服务。需要注意的是,插件默认认为服务调用都是通过POST请求的方式,所以指定的接口一定要为POST:
1 | go复制代码package main |
注意:如果出现运行报错:
{"id":"go.micro.client","code":500,"detail":"none available","status":"Internal Server Error"}
,可以查看我的另一篇博文:Go-Micro客户端请求报500错误的解决方法,对该问题有详细的分析和解决。
其他需要注意的是服务调用这边只支持json形式传参,所以如Gin中请使用Bind()
的方式获取请求参数:
1 | go复制代码engine := gin.Default() |
本文转载自: 掘金