微服务架构攀登之路(四)之使用gRPC构建微服务
做一个处理用户信息的微服务
客户端通过用户名,可以从服务端查询用户的基本信息
gRPC proto user.proto 定义客户端请求、服务端响应的数据格式 user.pb.go 自动生成的,为数据交互提供的函数 server.go 微服务服务端 client.go 微服务客户端
1. 编写proto文件
// 版本号 syntax = "proto3"; // 指定生成 user.pb.go的包名 package proto; // 定义客户端请求的数据格式 message UserRequest{ // 定义请求参数 string name = 1; } // 定义服务端相应的额数据格式 message UserResponse{ //定义响应参数 int32 id = 1; string name = 2; int32 age = 3; // 字段修饰符 // repeated表示可变数组,类似于切片类型 repeated string hobby = 4; } // 相当于接口 // service 定义开放调用的额服务 service UserInfoService{ //相当于接口内的方法 // 定义请求参数为UserRequest,响应参数为UserResponse rpc GetUserInfo(UserRequest) returns (UserResponse){} }
2. 生成.go文件
- pycharm 中打开命令行,输入命令生成接口文件:
protoc -I . --go_out=plugins=grpc:. ./user.proto
3.编写服务端
package main import ( "context" "fmt" pb "go-micro/my-micro/gRPC/proto" "google.golang.org/grpc" "net" ) // 定义服务端实现约定的接口 type UserInfoService struct { } var u = UserInfoService{} // 实现服务端需要首先的接口 func (s *UserInfoService) GetUserInfo(ctx context.Context, req *pb.UserRequest) (resp *pb.UserResponse, err error) { name := req.Name // 在数据库查用户信息 if name == "zhangsan" { resp = &pb.UserResponse{ Id: 1, Name: name, Age: 22, //切片字段 Hobby: []string{"Sing", "run", "basketball"}, } } err = nil return } func main() { // 1. 监听 addr := "127.0.0.1:8080" lis, err := net.Listen("tcp", addr) if err != nil { fmt.Printf("监听异常:%s\n", err) } fmt.Printf("开始监听:%s\n", addr) // 2.实例化gRPC s := grpc.NewServer() // 3.在gRPC上注册微服务 // 第二个参数类型需要接口类型的变量 pb.RegisterUserInfoServiceServer(s,&u) // 4.启动gRPC服务 s.Serve(lis) }
4. 编写客户端
package main import ( "context" "fmt" pb "go-micro/my-micro/gRPC/proto" "google.golang.org/grpc" ) func main() { // 1. 创建与gRPC服务端的连接 conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithInsecure()) if err != nil { fmt.Printf("连接异常:%s\n", err) } defer conn.Close() // 2. 实例化gRPC客户端 client := pb.NewUserInfoServiceClient(conn) // 3. 组装参数 req := new(pb.UserRequest) req.Name = "zhangsan" // 4. 调用接口 resp, err := client.GetUserInfo(context.Background(), req) if err != nil { fmt.Printf("响应异常:%s\n", err) } fmt.Printf("响应结果: %v\n", resp) }