1.1 grpc是什么
gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.
1.2 为什么要使用rpc
rpc主要是分布式系统之间调用,相当于http容器,更多的封装了服务发现,负载均衡、熔断降级一类面向服务的高级特性
所以使用rpc是 因为良好的rpc调用是面向服务的封装,针对服务的可用性和效率等都做了优化。单纯使用http调用则缺少了这些特性。
2 使用grpc创建一个rpc服务
2.1 创建xxx.proto文件,定义服务,设计api
这里设计一个复制字符串功能的api
2.1.1 创建doublestr.proto文件
syntax = "proto3";
option go_package = "doublestr";
package doublestr;
// 提供一个字符串复制的功能
service Greeter {
// Sends a greeting
rpc doubleStr (StrRequest) returns (StrReply) {}
}
message StrRequest {
string origin = 1;
}
message StrReply {
string message = 1;
}
2.1.2 使用protoc生成代码
protoc -I ./ ./doublestr.proto --go_out=plugins=grpc:./
执行完以后会在目录下生成doublestr.pb.go文件
2.1.3 *服务端实现api接口
package main
import (
"context"
"log"
"net"
grpc "google.golang.org/grpc"
pb "qiban.com/mypro/doublestr"
)
const (
port = ":50051"
)
// server is used to implement helloworld.GreeterServer.
type server struct {
pb.GreeterServer
}
func (s *server) DoubleStr(ctx context.Context, in *pb.StrRequest) (*pb.StrReply, error) {
log.Println("Received: " + in.GetOrigin())
res := in.GetOrigin() + in.GetOrigin()
return &pb.StrReply{Message: res}, nil
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
2.1.4 *客户端代码
// client
package main
import (
"context"
"log"
"os"
"time"
"google.golang.org/grpc"
pb "qiban.com/mypro/doublestr"
)
const (
address = "localhost:50051"
defaultName = "doubleStr"
)
func main() {
conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewGreeterClient(conn)
name := defaultName
if len(os.Args) > 1 {
name = os.Args[1]
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.DoubleStr(ctx, &pb.StrRequest{Origin: name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.GetMessage())
}
2.1.4 运行server 和client
cd server
go run main.go
cd client
go run main.go