环境
操作系统 | win10 1909 |
golang | go1.14.2 windows/amd64 |
micro | v2@v2.6.0 |
protoc | protoc-3.12.0-rc-1-win64 |
consul(可选) | consul_1.7.3_windows_amd64 |
安装
-
protoc
下载对应版本的安装包https://github.com/protocolbuffers/protobuf/releases
解压后随便找个地方放,把bin目录地址加到环境变量中。
>protoc --version
libprotoc 3.12.0
-
micro和protoc相关的go插件
#设置mod模式和代理
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,https://proxy.golang.org,direct#安装
go get -u -v github.com/golang/protobuf/protoc-gen-go
go get -u -v google.golang.org/grpc
#这里若加-u选项貌似会报错,就不加了
go get -v github.com/micro/micro/v2
go get -u -v github.com/micro/go-micro/v2
go get -v github.com/micro/micro/v2/cmd/protoc-gen-micro@master
顺利安装完毕后,在$GOPATH/bin下应该会有这仨执行文件
-
consul(可选)
因为micro v2版本官方弃用consul,默认改用了mdns,生产推荐etcd。参考go-micro v2弃用了consul作为默认的服务发现
所以装不装这个都可以。
https://www.consul.io/downloads.html下载对应版本,网速限制的话可以在这里https://download.csdn.net/download/HJXINKKL/12428749下
解压后添加路径到环境变量
>consul -v
Consul v1.7.3
开始创建
-
目录结构
│ go.mod
│ go.sum
│
└─helloworld
├─message
│ greeter.pb.go
│ greeter.pb.micro.go
│ greeter.proto
│
└─services
client.go
server.go
-
初始化项目
在$GOPATH/src下
mkdir microTest
go mod init microTest
-
定义API
创建helloworld/message/greeter.proto
syntax = "proto3";
package microTest;
option go_package = "helloworld/message";
service Greeter {
rpc Hello (Request) returns (Response) {
}
}
message Request {
string name = 1;
}
message Response {
string greeting = 2;
}
microTest下执行protoc命令,就会在helloworld/message/自动生成greeter.pb.go、greeter.pb.micro.go
protoc --micro_out=. --go_out=. helloworld/message/greeter.proto
-
创建service
创建helloworld/services/server.go文件
package main
import (
"context"
"fmt"
micro "github.com/micro/go-micro/v2"
proto "microTest/helloworld/message"
)
type Greeter struct{}
func (g *Greeter) Hello(ctx context.Context, req *proto.Request, rsp *proto.Response) error {
rsp.Greeting = "Hello " + req.Name
return nil
}
func main() {
// Create a new service. Optionally include some options here.
service := micro.NewService(
micro.Name("greeter"),
)
// Init will parse the command line flags.
service.Init()
// Register handler
proto.RegisterGreeterHandler(service.Server(), new(Greeter))
// Run the server
if err := service.Run(); err != nil {
fmt.Println(err)
}
}
-
创建client
创建helloworld/services/client.go文件
package main
import (
"context"
"fmt"
micro "github.com/micro/go-micro/v2"
proto "microTest/helloworld/message"
)
func main() {
// Create a new service
service := micro.NewService(micro.Name("greeter.client"))
// Initialise the client and parse command line flags
service.Init()
// Create new greeter client
greeter := proto.NewGreeterService("greeter", service.Client())
// Call the greeter
rsp, err := greeter.Hello(context.TODO(), &proto.Request{Name: "John"})
if err != nil {
fmt.Println(err)
}
// Print response
fmt.Println(rsp.Greeting)
}
运行服务
-
启动server
go run helloworld/services/server.go
-
client请求
go run helloworld/services/client.go
此时,有可能会报错
{"id":"go.micro.client","code":408,"detail":"context deadline exceeded","status":"Request Timeout"}
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x28 pc=0xeef454]
-
定位报错原因
查看服务列表,greeter服务已经启动了
> micro list services
greeter
查看指定服务信息
micro get service greeter
service greeter
version latest
ID Address Metadata
greeter-28a0d7a1-4a26-499d-bd9f-364151021f50 10.0.0.1:57647 broker=http,protocol=grpc,registry=mdns,server=grpc,transport=grpc
Endpoint: Greeter.Hello
Request: {
message_state MessageState {
no_unkeyed_literals NoUnkeyedLiterals
do_not_compare DoNotCompare
do_not_copy DoNotCopy
message_info MessageInfo
}
int32 int32
unknown_fields []uint8
name string
}
Response: {
message_state MessageState {
no_unkeyed_literals NoUnkeyedLiterals
do_not_compare DoNotCompare
do_not_copy DoNotCopy
message_info MessageInfo
}
int32 int32
unknown_fields []uint8
greeting string
}
注意到Address地址为10.0.0.1:57647,也就是micro注册到默认网段去了,所以导致服务不可达。
-
带指定server_address参数启动server
go run helloworld/services/server.go --server_address=localhost:8888
-
再次client请求
go run helloworld/services/client.go
这次返回正常结果
Hello John
-
再次查看指定服务信息
micro get service greeter
ID Address Metadata
greeter-f875a030-436a-420d-a29a-a66249d22381 127.0.0.1:8888 protocol=grpc,registry=mdns,server=grpc,transport=grpc,broker=http
-
服务调用
仿照官网给出的例子
micro call greeter Greeter.Hello '{"name": "John"}'
不管是PowerShell还是CMD都会报 invalid character 的错误。
需要将"进行转义\",才可以正常执行,注意PowerShell和CMD的不同
使用consul做服务发现
如果非要使用consul的话,就得往client.go和server.go的import中添加
_ "github.com/micro/go-plugins/registry/consul/v2"
-
启动Consul agent的开发模式
consul agent -dev
-
启动server
go run helloworld/services/server.go --registry=consul --server_address=localhost:8888
-
client请求
go run helloworld/services/client.go --registry=consul