本文通过一个简单的初始教程,带领大家初步体验下gRPC框架。
简单来说,RPC就是要像调用本地的函数一样去调远程函数,实现分布式调用,系统服务水平能力扩展。
gRPC是一个由google开源的高性能的分布式调用框架,支持跨语言进行RPC调用,同时也是一个CNCF孵化项目。官方的网址为:https://grpc.io
gRPC是一个现代开源高性能远程过程调用(RPC)框架,可以在任何环境中运行。它可以高效地连接数据中心内和数据中心之间的服务,并可插拔支持负载平衡、跟踪、运行状况检查和身份验证。它也适用于最后一英里的分布式计算,用于将设备、移动应用程序和浏览器连接到后端服务。
本文的环境采用的是arm版本的centos7的容器进行测试,所以安装的软件均为arm版本的。
提示有些包可能需要科学上网才能下载到。
curl -O https://dl.google.com/go/go1.19.4.linux-arm64.tar.gz
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.19.4.linux-arm64.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version
yum install -y wget unzip
wget https://github.com/protocolbuffers/protobuf/releases/download/v21.12/protoc-21.12-linux-aarch_64.zip
unzip protoc-21.12-linux-aarch_64.zip -d /usr/local/
go env -w GOPROXY="https://goproxy.cn,direct"
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
export PATH="$PATH:$(go env GOPATH)/bin"
go mod init grpc
mkdir server client protoc
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
option go_package = "grpc/protoc";
package protoc;
// The greeting service definition.
service MySvc {
rpc Myfunc (MyRequest) returns (MyReply) {}
}
// The request message containing the user's name.
message MyRequest {
string name = 1;
}
// The response message containing the greetings
message MyReply {
string result = 1;
}
这里采用的是proto buffer 版本为3,具体到语法规则可以参考官方网址:
https://developers.google.com/protocol-buffers/docs/proto3
protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative protoc/test.proto
package main
import (
"context"
"google.golang.org/grpc"
"log"
"net"
pb "grpc/protoc"
)
type mysrv struct {
pb.UnsafeMySvcServer
}
func (m *mysrv) Myfunc(ctx context.Context, in *pb.MyRequest) (*pb.MyReply, error) {
return &pb.MyReply{Result: "my:" + in.GetName()}, nil
}
func main() {
l, err := net.Listen("tcp", "127.0.0.1:8877")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterMySvcServer(s, &mysrv{})
log.Printf("server listening at %v", l.Addr())
if err := s.Serve(l); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
package main
import (
"context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"log"
pb "grpc/protoc"
)
func main() {
conn, err := grpc.Dial("localhost:8877", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
m := pb.NewMySvcClient(conn)
res, err := m.Myfunc(context.Background(), &pb.MyRequest{Name: "hello"})
if err != nil {
log.Printf("err:%v", err)
}
log.Printf("res:%v", res.GetResult())
}
go run server/main.go
go run client/main.go
2022/12/25 09:02:24 res:my:hello
可以看到本地的客户端可以调用到远程到服务端到方法,并返回正确的结果。