因为业务需要,需要一个跨语言调用的RPC框架,gRPC是Google发布的基于HTTP 2.0传输层协议承载的高性能开源软件框架,本文使用Golang实现一个简单的gRPC服务端。
环境 | 版本 |
---|---|
系统 | CentOS7 |
Golang | 1.19 |
libprotoc | 22.0 |
golang
安装见golang官方
安装 protoc
见官方
将相应软件下载下来, 然后将 bin 文件夹添加到 $PATH
项目中安装grpc
go get google.golang.org/grpc
安装protoc-gen-go
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
安装protoc-gen-go-grpc
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
安装protoc-gen-grpc-gateway
go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway@latest
安装protoc-gen-swagger
go install github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger@latest
go install
的文件会安装在$GOPATH/bin
下,所以将$GOPATH/bin
添加到$PATH
echo 'export PATH=$PATH:$GOPATH/bin' >> ~/.bashrc
source ~/.bashrc
生成的golang代码存放在./hello
下
生成golang包名为hello
注册的服务为名称为Hello
调用方法为PrintHello
传入的结构体为HelloRequest
带有一个string
类型参数:name
返回的消息结构体为HelloReply
带有一个string
类型参数为:message
syntax = "proto3";
option go_package="./hello;hello";
package hello;
service Hello {
rpc PrintHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
其中option go_package = "path;name";
path 表示生成的go文件的存放地址,会自动生成目录
name 表示生成的go文件所属的包名
执行
mkdir -p pb
protoc -I ./ hello.proto --go_out=./pb --go-grpc_out=./pb
就会在pb目录下生成hello/hello.pb.go
文件和hello/hello_grpc.pb.go
,其中包含golang中的服务和消息类型
go mod init server
package main
import (
"context"
"fmt"
"net"
"server/pb/hello"
"google.golang.org/grpc"
)
const (
port = ":1234"
)
type server struct {
hello.UnimplementedHelloServer // 必须加的结构体
}
func (s *server) PrintHello(ctx context.Context, in *hello.HelloRequest) (*hello.HelloReply, error) {
fmt.Printf("客户端消息:: %v", in.Name)
return &hello.HelloReply{Message: "Hello " + in.Name}, nil
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
fmt.Printf("无法监听端口: %v", err)
panic(err)
}
s := grpc.NewServer()
hello.RegisterHelloServer(s, &server{})
fmt.Println("服务启动于", port)
if err := s.Serve(lis); err != nil {
fmt.Printf("无法提供服务: %v", err)
panic(err)
}
}
go mod tidy
go run server.go
显示如下,则gRPC服务端在1234端口启动
服务启动于 :1234
package main
import (
"context"
"fmt"
"server/pb/hello"
"google.golang.org/grpc"
)
func main() {
// 建立GRPC连接
conn, err := grpc.Dial("localhost:1234", grpc.WithInsecure())
if err != nil {
fmt.Printf("无法建立连接: %v", err)
panic(err)
}
defer conn.Close()
c := hello.NewHelloClient(conn)
r, err := c.PrintHello(context.Background(), &hello.HelloRequest{Name: "hello"})
if err != nil {
fmt.Printf("无法发起gRPC请求: %v", err)
panic(err)
}
fmt.Printf("返回的消息: %s", r.Message)
}
go run client.go
最后显示gRPC服务端返回的消息:
返回的消息: Hello hello