go 微服务之go-micro v3+gin
安装gin
go get -u github.com/gin-gonic/gin
安装go-micro v3
先安装依赖
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go
//安装asim/go-micro 这个是go micro 3.0 框架
go get github.com/asim/go-micro/cmd/protoc-gen-micro/v3
安装micro v3
//需要用到Micro 3.0 环境的micro 工具,可以快速构建项目,但是不使用这个库,用下面的
go get github.com/micro/micro/v3
// 下载go micro 3.0 库,下面库没有上面micro 工具
go get github.com/asim/go-micro/v3
搭建项目
1、创建go微服务学习
文件夹
# 先创建go.mod文件,用于管理引用的包
module go微服务学习
go 1.15
2、创建web
和services
文件夹
mkdir go微服务学习
cd go微服务学习
mkdir web services
创建web
-
进入
web
文件夹-
创建
main.go
文件package main import ( "github.com/gin-gonic/gin" "net/http" ) const addr = ":80" func Index(c *gin.Context) { c.JSON(http.StatusOK, map[string]interface{}{ "message": "index", }) } func main() { r := gin.Default() r.Handle("GET", "/", Index) if err := r.Run(addr); err != nil { fmt.Println("err") } }
然后执行
go run .
启动web服务$ go run . [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) [GIN-debug] GET /test1 --> myProject/web/handler.Index (3 handlers)
浏览器访问
http://127.0.0.1
, 得到如下响应// 20220103173321 // http://127.0.0.1/test1 { "message": "index" }
-
创建service
-
进入
services
文件夹,执行micro new test1
命令-
移除
go.mod
文件 -
生成pb文件, 下面命令可以在
Makefile
文件中查到protoc --proto_path=. --micro_out=. --go_out=:. proto/test1.proto
-
修改
handler/test1.go
文件import ( "context" log "github.com/micro/micro/v3/service/logger" // test1 "test1/proto" test1 "go微服务学习/services/test1/proto" )
-
修改
main.go
文件package main import ( "go微服务学习/services/test1/handler" pb "go微服务学习/services/test1/proto" service "github.com/asim/go-micro/v3" // "github.com/micro/micro/v3/service" "github.com/asim/go-micro/v3/logger" // "github.com/micro/micro/v3/service/logger" ) func main() { // Create service srv := service.NewService( // service.New service.Name("test1"), service.Version("latest"), ) // Register handler _ = pb.RegisterTest1Handler(srv.Server(), new(handler.Test1)) // Run service if err := srv.Run(); err != nil { logger.Fatal(err) } }
-
执行
go run .
启动名为test1的服务$ go run . 2022-01-03 18:03:08 file=v3@v3.7.0/service.go:206 level=info Starting [service] test1 2022-01-03 18:03:08 file=server/rpc_server.go:820 level=info Transport [http] Listening on [::]:4142 2022-01-03 18:03:08 file=server/rpc_server.go:840 level=info Broker [http] Connected to 127.0.0.1:4143 2022-01-03 18:03:08 file=server/rpc_server.go:654 level=info Registry [mdns] Registering node: test1-7f6989d9-e1a9-4353-b81a-707bf3b60ff5 # 使用默认的mdns作为注册中心、
-
通过web去调用微服务
-
添加
web/handler/test1Handler.go
文件package handler import ( "github.com/asim/go-micro/v3" "github.com/gin-gonic/gin" test1 "go微服务学习/services/test1/proto" "net/http" ) func Index(c *gin.Context) { c.JSON(http.StatusOK, map[string]interface{}{ "message": "index", }) } func ServiceOne(c *gin.Context) { service := micro.NewService() service.Init() // 创建微服务客户端 client := test1.NewTest1Service("test1", service.Client()) // 调用服务 rsp, err := client.Call(c, &test1.Request{ Name: c.Query("key"), }) if err != nil { c.JSON(200, gin.H{"code": 500, "msg": err.Error()}) return } c.JSON(200, gin.H{"code": 200, "msg": rsp.Msg}) }
-
修改
web/main.go
文件package main import ( //... "go微服务学习/web/handler" ) //... func main() { r := gin.Default() r.Handle("GET", "/test1", handler.ServiceOne) //... }
-
运行
go run .
重新启动web服务$ go run . [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) [GIN-debug] GET /test1 --> go微服务学习/web/handler.ServiceOne (3 handlers) [GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value. Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details. [GIN-debug] Listening and serving HTTP on :80
浏览器访问
http://127.0.0.1/test1?key=ajune
,得到如下响应// 20220103181848 // http://127.0.0.1/test1?key=ajune { "code": 200, "msg": "Hello ajune" }
使用consul作为注册中心注册服务
启动一个consul的docker容器
ajune@ubuntu:~$ docker network create consul # 创建一个consul网络
de9c7105e8a03fc5bfa0ac82344969e5b0ee3c9e369c90c3749f11ae57d8f0dc
ajune@ubuntu:~$ docker run --network consul --name consul -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul agent -server -bootstrap-expect 1 -ui -bind=0.0.0.0 -client=0.0.0.0
==> Starting Consul agent...
Version: '1.11.1'
Node ID: '4c6a5611-c56a-2468-3dfc-c5a13aa542c0'
Node name: '602afb2bd163'
Datacenter: 'dc1' (Segment: '<all>')
Server: true (Bootstrap: true)
Client Addr: [0.0.0.0] (HTTP: 8500, HTTPS: -1, gRPC: -1, DNS: 8600)
Cluster Addr: 172.21.0.2 (LAN: 8301, WAN: 8302)
Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false
启动后,使用浏览器访问http://192.168.8.100:8500
-
安装consul包
go get -u github.com/asim/go-micro/plugins/registry/consul/v3
-
修改
services/test1/main.go
package main import ( //... "github.com/asim/go-micro/v3/registry" "github.com/asim/go-micro/plugins/registry/consul/v3" //... ) const ( ServerName = "test1" ConsulAddr = "192.168.8.100:8500" ) func main() { // 新建注册 consulReg := consul.NewRegistry( registry.Addrs(ConsulAddr), ) srv := service.NewService( service.Name(ServerName), // 服务名字 service.Registry(consulReg),// 注册中心 ) //... }
-
执行
go run .
,重新启动test1服务$ go run . 2022-01-03 18:56:36 file=v3@v3.7.0/service.go:206 level=info Starting [service] test1 2022-01-03 18:56:36 file=server/rpc_server.go:820 level=info Transport [http] Listening on [::]:8818 2022-01-03 18:56:36 file=server/rpc_server.go:840 level=info Broker [http] Connected to 127.0.0.1:8819 2022-01-03 18:56:36 file=server/rpc_server.go:654 level=info Registry [consul] Registering node: test1-1aa7262e-17ac-4b4e-a3a9-0b6035771dd2 # 使用了consul作为注册中心 2022-01-03 18:59:47 file=handler/test1.go:15 level=info Received Test1.Call request 2022-01-03 18:59:48 file=handler/test1.go:15 level=info Received Test1.Call request
-
修改
web/handler/test1Handler.go
package handler import ( "github.com/asim/go-micro/plugins/registry/consul/v3" "github.com/asim/go-micro/v3/registry" //... ) func ServiceOne(c *gin.Context) { //配置注册中心 consulReg := consul.NewRegistry( registry.Addrs("192.168.8.100:8500"), ) service := micro.NewService( micro.Registry(consulReg), //设置注册中心 ) //... }
-
执行
go run .
,重启web
使用etcd作为注册中心
安装etcd
包
go get -u "github.com/asim/go-micro/plugins/registry/etcd/v3"
使用容器启动etcd服务
ajune@ubuntu:~$ docker network create etcd
ajune@ubuntu:~$ docker run --name etcd --network etcd -p 2379:2379 -p 2380:2380 --env ALLOW_NONE_AUTHENTICATION=yes --env ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379 bitnami/etcd:latest
etcd 11:11:42.58
etcd 11:11:42.58 Welcome to the Bitnami etcd container
etcd 11:11:42.58 Subscribe to project updates by watching https://github.com/bitnami/bitnami-docker-etcd
etcd 11:11:42.58 Submit issues and feature requests at https://github.com/bitnami/bitnami-docker-etcd/issues
etcd 11:11:42.59
etcd 11:11:42.59 INFO ==> ** Starting etcd setup **
etcd 11:11:42.62 INFO ==> Validating settings in ETCD_* env vars..
etcd 11:11:42.62 WARN ==> You set the environment variable ALLOW_NONE_AUTHENTICATION=yes. For safety reasons, do not use this flag in a production environment.
etcd 11:11:42.63 INFO ==> Initializing etcd
etcd 11:11:42.63 INFO ==> Generating etcd config file using env variables
etcd 11:11:42.65 INFO ==> There is no data from previous deployments
etcd 11:11:42.66 INFO ==> Stopping etcd
etcd 11:11:43.67 INFO ==> ** etcd setup finished! **
etcd 11:11:43.70 INFO ==> ** Starting etcd **
修改services/test1/main.go
package main
import (
//...
"github.com/asim/go-micro/plugins/registry/etcd/v3"
//...
)
const (
//...
EtcdAddr = "192.168.8.100:2379"
)
func main() {
// 新建注册
//consulReg := consul.NewRegistry(
// registry.Addrs(ConsulAddr),
//)
// 使用etcd作为注册
etcdReg := etcd.NewRegistry(
registry.Addrs(EtcdAddr),
)
srv := service.NewService(
service.Name(ServerName), // 服务名字
service.Registry(etcdReg), // 注册中心
)
}
修改web/handler/test1Handler.go
package handler
import (
"github.com/asim/go-micro/plugins/registry/etcd/v3"
//...
)
func ServiceOne(c *gin.Context) {
//配置注册中心
//consulReg := consul.NewRegistry(
// registry.Addrs("192.168.8.100:8500"),
//)
// 使用etcd作为注册
etcdReg := etcd.NewRegistry(
registry.Addrs("192.168.8.100:2379"),
)
service := micro.NewService(
micro.Registry(etcdReg), //设置注册中心
)
//...
}