安装go-micro
go get github.com/micro/go-micro/v2
安装工具集
go get github.com/micro/micro/v2
安装protobuf插件
go get github.com/golang/protobuf/{
proto,protoc-gen-go}
go get github.com/micro/protoc-gen-micro
使用micro命令创建micro微服务项目
micro new helloworld --namespace=github.com.helloworld --gopath=false
首先我们使用 make proto 命令构建.pb.go和.pb.micro.go文件
项目结构:
.
├── Dockerfile
├── generate.go
├── go.mod
├── go.sum
├── handler
│ └── helloworld.go
├── main.go
├── Makefile
├── plugin.go
├── proto
│ └── helloworld
│ ├── helloworld.pb.go
│ ├── helloworld.pb.micro.go
│ └── helloworld.proto
├── README.md
└── subscriber
└── helloworld.go
编写一个简单服务需要注意的文件已重点标记:
handler/helloworld.go: 用于编写服务的定义
main.go: 用于服务注册与启动
helloworld.pb.micro.go: 定义各种用于编写服务的接口以及客户端接口
服务端:
main.go:
package main
import (
"github.com/micro/go-micro/v2"
log "github.com/micro/go-micro/v2/logger"
"helloworld/handler"
helloworld "helloworld/proto/helloworld"
)
func main() {
//创建服务,配置服务信息
service := micro.NewService(
micro.Name("go.micro.service.helloworld"), //服务名
micro.Version("latest"), //服务版本
// micro.Address("localhost:10000"), 设置grpc服务的地址,不选则自动生成端口
)
//将服务结构进行注册
helloworld.RegisterHelloworldHandler(service.Server(), new(handler.Helloworld))
//运行服务
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
handler/helloworld.go:
如果我们需要编写服务方法只需要对Call方法进行修改,本博客仅进行测试micro生成的代码已经足够所以可以不予修改。
func (e *Helloworld) Call(ctx context.Context, req *helloworld.Request, rsp *helloworld.Response) error {
log.Info("Received Helloworld.Call request")
rsp.Msg = "Hello " + req.Name
return nil
}
客户端:
客户端我使用gin框架进行编写:
main.go
package main
import (
"context"
"fmt"
"github.com/gin-gonic/gin"
go_micro_service_helloworld "github.com/helloworldClient/proto/helloworld"
"github.com/micro/go-micro/v2"
"github.com/micro/go-micro/v2/client"
"time"
)
//用于超时处理
var opts client.CallOption = func(o *client.CallOptions) {
o.RequestTimeout = time.Second * 30
o.DialTimeout = time.Second * 30
}
func main() {
router := gin.Default()
router.GET("/", func(ctx *gin.Context) {
service := micro.NewService(micro.Name("go.micro.service.helloworld"))
microClient := go_micro_service_helloworld.NewHelloworldService("go.micro.service.helloworld",service.Client())
rep, err := microClient.Call(context.TODO(), &go_micro_service_helloworld.Request{
Name:"Brad"},opts)
if err != nil {
fmt.Println(err)
return
}
ctx.Writer.WriteString(rep.Msg)
})
router.Run("localhost:8080")
}
以上是使用默认的mdns进行服务注册与发现,所以可以发现并未出现服务端的IP和端口
1.使用micro工具创建项目目录
micro new helloworld --gopath=false
2.编辑proto文件
删除暂时不需要的,只保留call方法,根据需求对request和response进行编辑修改。
syntax = "proto3";
package go.micro.service.helloworld;
service Helloworld {
rpc Call(Request) returns (Response) {
}
}
message Request {
string name = 1;
}
message Response {
string msg = 1;
}
3.生成pb.go
make proto
4.开始编写代码
需要先导入包:
"github.com/micro/go-plugins/registry/consul/v2"
服务端:
package main
import (
"github.com/micro/go-micro/v2"
log "github.com/micro/go-micro/v2/logger"
"github.com/micro/go-micro/v2/registry"
"github.com/micro/go-plugins/registry/consul/v2"
"helloworld/handler"
helloworld "helloworld/proto/helloworld"
)
func main() {
// 配置consul服务发现与注册配置
reg := consul.NewRegistry(func(opts *registry.Options) {
opts.Addrs = []string{
"localhost:8500", //consul端口
}
})
// 配置micro服务
microService := micro.NewService(
micro.Name("go.micro.service.helloworld"),
micro.Version("latest"),
micro.Address("localhost:10000"), //grpc服务地址
micro.Registry(reg),
)
// 将处理器与micro服务绑定
helloworld.RegisterHelloworldHandler(microService.Server(), new(handler.Helloworld))
// 启动服务
if err := microService.Run(); err != nil {
log.Fatal(err)
}
}
客户端:
package main
import (
"context"
"fmt"
"github.com/gin-gonic/gin"
go_micro_service_helloworld "github.com/helloworldClient/proto/helloworld"
"github.com/micro/go-micro/v2"
"github.com/micro/go-micro/v2/client"
"github.com/micro/go-micro/v2/registry"
"github.com/micro/go-plugins/registry/consul/v2"
"time"
)
var opts client.CallOption = func(o *client.CallOptions) {
o.RequestTimeout = time.Second * 30
o.DialTimeout = time.Second * 30
}
func main() {
// 配置consul服务发现与注册配置
consulReg := consul.NewRegistry(func(opts *registry.Options) {
opts.Addrs = []string{
"localhost:8500", //consul端口
}
})
// 配置路由
router := gin.Default()
// 绑定路由
router.GET("/", func(ctx *gin.Context) {
// 初始化micro服务
microService := micro.NewService(micro.Name("go.micro.service.helloworld"),micro.Registry(consulReg))
// 将micro服务的客户端绑定到helloworld服务
helloworldService := go_micro_service_helloworld.NewHelloworldService("go.micro.service.helloworld",microService.Client())
// 调用helloworld服务
rep, err := helloworldService.Call(context.TODO(), &go_micro_service_helloworld.Request{
Name:"Brad"},opts)
if err != nil {
fmt.Println(err)
}
ctx.Writer.WriteString(rep.Msg)
})
// 启动路由
router.Run("localhost:8080")
}