gRPC入门

海哥  金牌会员 | 2023-4-17 20:25:07 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 534|帖子 534|积分 1602

1. gRPC简介

gRPC是一种高性能、开源和通用的远程过程调用(RPC)框架,由Google开源并维护。它使用Protocol Buffers(protobuf)作为接口定义语言(IDL),提供跨平台、跨语言的RPC调用支持。gRPC具有以下几个特点:

  • 高性能:使用HTTP/2协议,支持多路复用和流控制等特性,能够在客户端和服务器之间高效地传输大量数据。同时,gRPC还使用了基于平台优化的序列化和反序列化技术,提高了通信的效率。
  • 简单易用:gRPC的IDL语言简单易懂,同时提供了自动生成代码的工具,方便用户进行开发。用户只需要定义好IDL,并生成代码后即可在代码中使用类似于本地函数调用的方式进行远程过程调用。
  • 多语言支持:gRPC支持多种编程语言,如C++, Java, Python, Go, Ruby等,可以在不同编程语言之间进行RPC调用。
  • 可扩展性:gRPC支持各种扩展,包括拦截器、负载均衡、认证和授权等,可以满足不同场景下的需求。
  • 安全性:gRPC支持SSL/TLS安全传输,同时还提供了基于Token的认证机制,确保通信的安全性。
总之,gRPC提供了一种高效、可扩展、多语言、安全的RPC框架,适用于大规模分布式系统中的服务间通信,如微服务架构。
本文以go为例,介绍如何使用gRPC开发一个简单服务。
2. 准备工作

2.1 安装protoc

github系统对应的protoc预编译版,解压到/usr/local/下,以v22.3为例,具体操作如下:
  1. wget https://github.com/protocolbuffers/protobuf/releases/download/v22.3/protoc-22.3-linux-x86_64.zip
  2. unzip protoc-22.3-linux-x86_64.zip -d /usr/local/
  3. ldconfig
  4. protoc --version
  5. # libprotoc 22.3
复制代码
2.2 安装go相关插件

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
3. 实践

3.1 编写proto文件
  1. syntax = "proto3";
  2. option go_package = "./;hello";
  3. package hello;
  4. message HelloRequest{
  5.     string name = 1;
  6. }
  7. message HelloResponse{
  8.     string message = 1;
  9. }
  10. service ExampleService{
  11.     rpc SayHi (HelloRequest) returns (HelloResponse);
  12. }
复制代码
service ExampleService就是我们定义的服务,rpc SayHi (HelloRequest) returns (HelloResponse);就是服务中提供的接口,protoc会根据我们定义的proto文件生成相应的代码。
3.2 使用protoc生成代码

终端下执行以下命令即可生成我们需要的代码:
  1. protoc --go_out=. --go-grpc_out=. hello.proto
复制代码
--go_out指定go文件的生成目录,--go-grpc_out指定grpc文件的生成目录
此时打开生成的go文件大概率会发现飘红报错,此时可以在当前目录下执行go mod tidy同步下依赖即可。
3.3 编写服务端代码

示例只是简单实现一个echo服务,服务端代码如下:
  1. package main
  2. import (
  3.         "context"
  4.         "net"
  5.         pb "github.com/mengbin92/hello/protos/hello"
  6.         "google.golang.org/grpc"
  7. )
  8. // 服务实体
  9. type HelloService struct {
  10.         pb.UnimplementedExampleServiceServer
  11. }
  12. // 实现我们proto文件定义的接口
  13. func (sv *HelloService) SayHi(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
  14.         return &pb.HelloResponse{Message: "hello " + in.Name}, nil
  15. }
  16. func main() {
  17.         // 创建grpc服务示例
  18.         sv := grpc.NewServer()
  19.         // 注册我们的服务
  20.         pb.RegisterExampleServiceServer(sv, new(HelloService))
  21.         // 绑定端口,提供服务
  22.         lis, err := net.Listen("tcp", ":50001")
  23.         if err != nil {
  24.                 panic(err)
  25.         }
  26.         // 启动服务
  27.         sv.Serve(lis)
  28. }
复制代码
启动服务后,服务端会一直阻塞等待客户端的链接,直到收到kill信号:
  1. go run server.go
复制代码
3.4 实现客户端
  1. package main
  2. import (
  3.         "context"
  4.         "fmt"
  5.         pb "github.com/mengbin92/hello/protos/hello"
  6.         "google.golang.org/grpc"
  7.         "google.golang.org/grpc/credentials/insecure"
  8. )
  9. func main() {
  10.         // 创建grpc连接
  11.         conn, err := grpc.Dial("localhost:50001", grpc.WithTransportCredentials(insecure.NewCredentials()))
  12.         if err != nil {
  13.                 panic(err)
  14.         }
  15.         defer conn.Close()
  16.         // 实例化客户端
  17.         client := pb.NewExampleServiceClient(conn)
  18.         // 发送请求
  19.         req := &pb.HelloRequest{Name: "world"}
  20.         resp, err := client.SayHi(context.TODO(), req)
  21.         if err != nil {
  22.                 panic(err)
  23.         }
  24.         fmt.Printf("get response from server: %s\n", resp.Message)
  25. }
复制代码
客户端启动后向服务端发送world,服务端返回hello world:
  1. go run client.go
  2. # get response from server: hello world
复制代码
至此,一个简单的gRPC服务就已经搞定了。
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

海哥

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表