go get -u github.com/gin-gonic/gin
先安装依赖
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
文件夹
创建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"
}
进入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/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的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
包
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), //设置注册中心
)
//...
}