前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >远程过程调用系统gRPC

远程过程调用系统gRPC

作者头像
Yuyy
发布2022-09-21 10:24:35
4400
发布2022-09-21 10:24:35
举报
文章被收录于专栏:yuyy.info技术专栏

简介

  • gRPC 可以将 Protocol buffers 用作其接口定义语言 ( IDL ) 和底层消息交换格式(也可以使用其他的,例如json)
  • 远程调用,跨语言,更容易创建分布式应用和服务
概念图
概念图
  • 和其他RPC一样,基于服务定义的思想,结合Protocol buffers+gRPC 插件,定义好服务后,服务端实现相应接口,客户端直接调用生成好的方法即可

主要使用场景

  • 低延迟、高度可扩展的分布式系统。
  • 开发与云服务器通信的移动客户端。
  • 设计一个需要准确、高效和语言独立的新协议。
  • 分层设计以实现扩展,例如。身份验证、负载平衡、日志记录和监控等。

核心概念

定义服务

代码语言:javascript
复制
service HelloService {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}
四种方式
  1. 简单rpc,就像正常调用函数一样 rpc GetFeature(Point) returns (Feature) {}
流式rpc

解决的问题

  • 传输的数据太大,造成瞬时网络压力
  • 大数据需要接收完才能处理

分类

  1. 服务端流式rpc rpc ListFeatures(Rectangle) returns (stream Feature) {}
  2. 客户端流式rpc rpc RecordRoute(stream Point) returns (RouteSummary) {}
  3. 双向流式rpc rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
    • 服务端收到请求后,不用等到读取完才响应,可以接收一点,响应一点,官网的原话是:服务器和客户端可以玩“乒乓”

具体介绍看官方文档,现在没用到这块

同步和异步

在 gRPC-Go 中,RPC 以阻塞/同步模式运行,这意味着 RPC 调用等待服务器响应,并且将返回响应或错误。

看来只能自己起goroutine了,但这样很麻烦,野生goroutine需要自己去维护异常处理和日志

设置超时

可主动终止RPC

示例

定义服务helloworld.proto

代码语言:javascript
复制
syntax = "proto3";

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

利用buf生成代码

执行buf mod init生成buf.yaml

配置buf,buf.gen.yaml

代码语言:javascript
复制
# 配置protoc生成规则
version: v1
managed:
 enabled: true
 go_package_prefix:
 # proto文件中不使用option定义包名称,因为proto生成代码可以放在不同项目中使用,因此在buf.gen.yaml中进行定义
   default: helloworld
   except:
     - buf.build/googleapis/googleapis
plugins:
 # 使用go插件生成go代码
 - name: go
   out: ./
   opt: paths=source_relative
 # 使用go-grpc插件生成grpc代码
 - name: go-grpc
   out: ./
   opt:
     - paths=source_relative
     - require_unimplemented_servers=false

执行buf generate 生成helloworld.pb.gohelloworld_grpc.pb.go

创建服务端

代码语言:javascript
复制
type server struct {
    pb.UnimplementedGreeterServer
}

// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    log.Printf("Received: %v", in.GetName())
    return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}
  • 继承生成的默认实现类
  • 重写实现接口方法

启动服务端

代码语言:javascript
复制
    flag.Parse()
    lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})
    log.Printf("server listening at %v", lis.Addr())
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
  • 监听端口
  • 创建 gRPC 服务器的实例
  • 向 gRPC 服务器注册我们的服务实现
  • 调用Serve()服务器以进行阻塞等待,直到进程被杀死或被Stop()调用

创建客户端

代码语言:javascript
复制
    flag.Parse()
    // Set up a connection to the server.
    conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()
    c := pb.NewGreeterClient(conn)

    // Contact the server and print out its response.
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()
    r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    log.Printf("Greeting: %s", r.GetMessage())
  • 创建 gRPC通道来与服务器通信
  • 可以使用DialOptions在服务需要时设置身份验证凭据(例如,TLS、GCE 凭据或 JWT 凭据)
  • 创建客户端
  • 调用服务方法
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-4-20 1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
    • 主要使用场景
    • 核心概念
      • 定义服务
        • 四种方式
      • 同步和异步
        • 设置超时
          • 可主动终止RPC
          • 示例
            • 定义服务helloworld.proto
              • 利用buf生成代码
                • 创建服务端
                  • 启动服务端
                    • 创建客户端
                    相关产品与服务
                    多因子身份认证
                    多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档