使用的包:
google grpc (google.golang.org/grpc);
net;
使用protobuf 协议;proto3 语法;
目录:
user.proto 代码如下:
syntax = "proto3"; //指定语法格式,注意 proto3 不再支持 proto2 的 required 和 optinal
package proto; //指定生成的 user.pb.go 的包名字;
//service 定义开发调用 的服务, 即UserInfoService 微服务
service UserInfoService {
//rpc 方式;定义GetUserInfo 远程调用
rpc GetUserInfo(UserRequest) returns (UserResponse){
}
}
//定义客户端请求的数据格式
//message 对应 生成的代码中的struct
message UserRequest{
// [修饰符] 类型 字段名 = 标识符
string name = 1;
}
message UserResponse{
int32 id=1;
string name=2;
int32 age =3;
repeated string title = 4; // 可变数组,即 slice 类型
}
使用protoc 生成 user.pb.go 文件:
bogon:proto zhaozhiliang$ protoc -I . --go_out=plugins=grpc:. user.proto
server.go代码如下:
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"log"
"net"
"zhaozhiliang.com/protobuf_grpc_service/proto"
)
//定义服务端 实现 约定的接口
type UserInfoService struct{}
var u = UserInfoService{}
//实现 interface
func (s *UserInfoService) GetUserInfo(ctx context.Context, req *proto.UserRequest) (resp *proto.UserResponse, err error) {
name := req.Name
if name == "liang" {
resp = &proto.UserResponse{
Id: 1568,
Name: name,
Age: 25,
Title: []string{"PHPer", "Gopher"},
}
}
err = nil
return
}
func main() {
port := ":6666"
l, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("listen error: %v\n", err)
}
fmt.Printf("listen %s\n", port)
s := grpc.NewServer()
// 将 UserInfoService 注册到 gRPC
// 注意第二个参数 UserInfoServiceServer 是接口类型的变量
// 需要取地址传参
proto.RegisterUserInfoServiceServer(s, &u)
s.Serve(l)
}
client.go 代码如下:
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"log"
"zhaozhiliang.com/protobuf_grpc_service/proto"
)
func main() {
conn, err := grpc.Dial(":6666", grpc.WithInsecure())
if err != nil {
log.Fatalf("dial error:%v\n", err)
}
defer conn.Close()
//实例化 UserInfoService 微服务的客户端
client := proto.NewUserInfoServiceClient(conn)
//调用服务
req := new (proto.UserRequest)
req.Name = "liang"
resp, err := client.GetUserInfo(context.Background(), req)
if err != nil {
log.Fatalf("resp error:%v\n", err)
}
fmt.Printf("Received: %v\n", resp)
}
运行 server.go ;运行client.go 输入如下:
Received: id:1568 name:"liang" age:25 title:"PHPer" title:"Gopher"
Process finished with exit code 0
go.mod 文件内容如下:
module zhaozhiliang.com/protobuf_grpc_service
go 1.13
require (
github.com/golang/protobuf v1.3.2
google.golang.org/grpc v1.26.0
)
注意事项 和遇到的问题 ?
自己写的包 找不到 ?
GoLand的配置里开启go mod了吗? 开启就可以了。
go get -u google.golang.org/grpc 无法拉取:?
进入该目录
cd $GOPATH/src/google.golang.org
git clone https://github.com/grpc/grpc-go grpc
架构分析:在上边 UserInfoService 微服务的实现过程中,会发现每个微服务都需要自己管理服务端监听端口,客户端连接后调用,当有很多个微服务时端口的管理会比较麻烦,相比 gRPC,go-micro实现了服务发现(Service Discovery)来方便的管理微服务