Go语言程序开发gRPC服务的完整攻略
什么是gRPC
gRPC是一种高性能、通用的开源RPC框架,其目标是将客户端和服务端应用程序连接在一起,使得在任何地方、任何语言中都可以轻松地基于标准化的协议通信。可以轻松的进行快速的开发和强大的服务的构建,以提供跨平台和跨系统的功能调用,可以使得开发人员更轻松地创建分布式应用程序。
gRPC的工作原理
gRPC使用Google开发的ProtoBuf作为数据传输格式,客户端和服务端声明protobuf类型,gRPC会生成对应的服务端和客户端代码。客户端从protobuf文件自动生成类型安全的调用,gRPC处理连接、负载均衡、错误信息等细节。
gRPC的优点
- 高性能:gRPC基于HTTP/2协议进行通信,支持多路复用、流、压缩头等功能,可大大提高通信性能。
- 多语言支持:gRPC支持多种语言,如Go、Java、Python等。
- 自动生成代码:gRPC可以根据.proto文件,自动化生成客户端和服务器端代码。
- 面向服务设计:gRPC是基于微服务架构的设计,支持对服务进行版本控制、部署和后期维护。
- 双向流:gRPC支持双向流传输(Stream),客户端和服务端可以同时发送和接收消息。
Go语言程序开发gRPC服务的过程
Go语言中开发gRPC服务的过程分为以下几个步骤:
- 使用proto3语法定义服务(.proto文件)。
- 使用protoc命令生成Go代码。
- 实现服务端和客户端代码。
- 运行和测试gRPC服务。
步骤1:使用proto3语法定义服务
定义服务信息,这里以定义一个UserService为例。
syntax = "proto3";
package user;
service UserService {
rpc CreateUser(User) returns (Result) {}
rpc GetUser(UserID) returns (User) {}
}
message User {
string Name = 1;
int32 Age = 2;
}
message UserID {
int32 ID = 1;
}
message Result {
int32 Code = 1;
string Message = 2;
}
步骤2:使用protoc命令生成Go代码
安装protobuf。
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go
生成Go代码。
protoc -I . --go_out=plugins=grpc:. ./*.proto
步骤3:实现服务端和客户端代码
服务端
package main
import (
"context"
"fmt"
"grpc-demo/pb/user"
"log"
"net"
"google.golang.org/grpc"
)
const (
port = ":50051"
)
type server struct{}
func (s *server) CreateUser(ctx context.Context, in *user.User) (*user.Result, error) {
fmt.Printf("CreateUser: %v\n", in)
return &user.Result{Code: 200, Message: "OK"}, nil
}
func (s *server) GetUser(ctx context.Context, in *user.UserID) (*user.User, error) {
fmt.Printf("GetUser: %v\n", in)
u := &user.User{Name: "test", Age: 26}
return u, nil
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
user.RegisterUserServiceServer(s, &server{})
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
客户端
package main
import (
"context"
"fmt"
"grpc-demo/pb/user"
"log"
"time"
"google.golang.org/grpc"
)
const (
address = "localhost:50051"
)
func createUser(c user.UserServiceClient) {
u := &user.User{Name: "test", Age: 26}
r, _ := c.CreateUser(context.Background(), u)
fmt.Printf("createUser: %v\n", r)
}
func getUser(c user.UserServiceClient) {
uid := &user.UserID{ID: 123}
u, _ := c.GetUser(context.Background(), uid)
fmt.Printf("getUser: %v\n", u)
}
func main() {
conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithTimeout(1*time.Second))
if err != nil {
log.Fatalf("failed to connect: %v", err)
}
defer conn.Close()
c := user.NewUserServiceClient(conn)
createUser(c)
getUser(c)
}
步骤4:运行和测试gRPC服务
启动服务端。
go run server.go
运行客户端。
go run client.go
以上便是完整的Go语言程序开发gRPC服务的攻略。
示例说明
这里提供两个示例,一个是定义UserService服务,一个是定义ProductService服务。
示例1:定义UserService服务
syntax = "proto3";
package user;
service UserService {
rpc CreateUser(User) returns (Result) {}
rpc GetUser(UserID) returns (User) {}
}
message User {
string Name = 1;
int32 Age = 2;
}
message UserID {
int32 ID = 1;
}
message Result {
int32 Code = 1;
string Message = 2;
}
在服务端实现CreateUser和GetUser两个方法,客户端实现对应的调用方法。
示例2:定义ProductService服务
syntax = "proto3";
package product;
service ProductService {
rpc GetProduct(ProductID) returns (Product) {}
rpc ListProduct(ListRequest) returns (ProductList) {}
}
message Product {
int32 ID = 1;
string Name = 2;
int32 Price = 3;
}
message ProductID {
int32 ID = 1;
}
message ListRequest {
int32 Page = 1;
int32 Size = 2;
}
message ProductList {
repeated Product Items = 1;
}
在服务端实现GetProduct和ListProduct两个方法,客户端实现对应的调用方法。
这里只是简单提供了protobuf文件和服务端、客户端的代码,更完整的代码可以参考我的博客文章:Go语言gRPC服务开发入门。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Go语言程序开发gRPC服务 - Python技术站