grpc

  1. rpc使服务之间的方法调用像本地一样,感知不到网络通信的存在。

  2. rpc是基于tcp协议的,但grpc是基于http2协议的。http2的好处是公开通用。

  3. rpc主要有两个工作,序列化(对象转换为二进制,用于网络传输),编解码(被调用方收到数据包,需要知道他的方法名,输入参数在数据包的起始位置等)

  4. grpc中函数中的context参数是啥意思

    在 gRPC 中,函数中的context参数是用于传递上下文信息的对象。它提供了一种在不同的函数调用之间共享状态、传递截止时间、取消信号以及其他相关信息的方式。 context参数通常被用作第一个参数传递给 gRPC 服务方法。

    通过context,可以实现以下功能:

    • 截止时间控制:可以设置请求的截止时间,当超过截止时间时,gRPC 框架可以自动取消请求。
    • 取消请求:可以通过context发送取消信号,通知正在进行的请求取消操作。
    • 传递元数据:可以在context中添加键值对形式的元数据,这些元数据可以在服务端和客户端之间进行传递。
    • 共享状态:可以在context中存储和共享一些与请求相关的状态信息。 context的使用使得 gRPC 服务能够更好地处理并发请求、超时情况和取消操作,同时也方便了在不同函数之间传递相关的上下文信息。
  5. context.abort()

    context.abort() 是 gRPC 框架中用于终止 RPC(Remote Procedure Call)调用的方法。它可以在服务器端或客户端使用,用于在出现错误或异常情况时,主动中断正在进行的 RPC 调用,并向对方发送一个错误状态码和可选的详细信息。 以下是 context.abort() 的一般用法:

    1. 在服务器端,当服务器在处理 RPC 调用时遇到错误或异常情况,可以调用 context.abort() 来终止该调用。这将导致客户端收到一个错误响应,并可以根据错误状态码进行相应的处理。
    2. 在客户端,当客户端发现与服务器的连接出现问题或 RPC 调用超时等情况时,也可以调用 context.abort() 来中断调用。 通过使用 context.abort(),可以在 gRPC 通信中及时处理错误情况,并提供更明确的错误反馈。这样可以帮助开发者更好地处理异常情况,增强系统的健壮性和可靠性。
  6. proto文件可以有多个,之间通过import引入。当不确定参数类型时,可以import Any 类型,代指任何类型。

  7. http1中一个TCP通道在同一时刻只能处理一个请求,也就是说只有存在response结果时,才能接着处理下一个请求

    而http2中引入了流和二进制帧,在同一个TCP通道中可以处理多个请求,在一个TCP通道中,虚拟出了多个流,流之间处理请求不分先后,不会阻塞,并进行了头部压缩,大幅度提高了交互效率

  8. 在grpc中可以直接使用stream。

    分为客户端流(请求参数前加上stream关键字),服务端流(返回参数中前加上stream关键字),双向流(请求参数和返回参数中前加上stream关键字)

    客户端流:客户端发送多个流,服务端处理一次

    服务端流:客户端只发送一个请求,服务端多次响应,直至完成

    双向流:两端不停的发消息,可用于心跳检测,websocket

  9. 以下是这些流模式各自常见的使用场景:

    客户端流

    • 文件上传:客户端可以逐步将一个大文件分块发送给服务器进行处理,比如图像、视频等的上传。
    • 实时数据采集:例如传感器持续发送数据到服务器进行分析和存储。

    服务端流

    • 实时监控数据推送:服务器主动向客户端推送实时更新的监控信息,如股票行情、天气数据等。
    • 逐步返回大量查询结果:当查询结果非常多时,服务器可以逐步流式返回,而不是一次性返回导致延迟过高。

    双向流

    • 实时交互应用:如在线游戏中,双方可以实时交互信息,包括动作、状态等。
    • 即时通讯:客户端和服务器之间可以实时双向传递消息,类似聊天应用。
    • 协作编辑:多个客户端与服务器进行双向交互,实现实时协作编辑文档等操作。

    例如,在一个视频会议应用中,可能会使用双向流来实时传输音频和视频数据;在一个工业控制系统中,可能使用客户端流来上传设备状态数据,同时使用服务端流来下发控制指令。

  10. sirius_pb2_grpc.GRPCServicer

    sirius_pb2_grpc.GRPCServicer 通常是在使用 gRPC(Google 远程过程调用)框架时定义的一个服务类。

    在 gRPC 中,服务端需要实现定义好的服务接口,而这个接口是在 .proto 文件中定义的,并通过 protoc 编译器生成对应的 Python 代码(其中就包括了从 GRPCServicer 继承的类)。

    例如,如果在 .proto 文件中有如下定义的服务:

    service SiriusService {
      rpc SomeMethod (SomeRequest) returns (SomeResponse) {}
    }
    

    那么 protoc 编译器生成的 Python 代码中可能就会有一个名为 SiriusServiceServicer 的类,它继承自 sirius_pb2_grpc.GRPCServicer ,服务端需要创建这个类的实例,并实现其中具体的方法(如上述例子中的 SomeMethod )来处理客户端的请求。

    以下是一个简单的示例代码,展示了如何创建一个继承自 GRPCServicer 的服务类并实现其中定义的方法:

    假设已经有一个生成的 example_pb2_grpc.py 文件(包含了 ExampleServiceServicer 类),对应的 .proto 文件里定义了一个 rpc DoSomething (ExampleRequest) returns (ExampleResponse); 的服务方法。

    import grpc
    from concurrent import futures
    from example_pb2_grpc import ExampleServiceServicer
    from example_pb2 import ExampleRequest, ExampleResponse
    
    class MyExampleService(ExampleServiceServicer):
        def DoSomething(self, request, context):
            # 处理客户端的请求并返回响应
            result = f"Received request with data: {request.data}"
            return ExampleResponse(result=result)
    
    def serve():
        # 创建 gRPC 服务器,并指定线程池大小
        server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
        # 将自定义的服务类添加到服务器中
        add_ExampleServiceServicer_to_server(MyExampleService(), server)
        # 绑定服务器的端口
        server.add_insecure_port('localhost:50051')
        # 启动服务器
        server.start()
        print("Server started. Listening on port 50051...")
        try:
            # 保持服务器运行,直到被中断
            while True:
                time.sleep(60 * 60 * 24)  # 一天的秒数,实际应用中可以根据需要修改
        except KeyboardInterrupt:
            server.stop(0)
    
    if __name__ == '__main__':
        serve()
    

    在上述示例中:

    • MyExampleService 继承自 ExampleServiceServicer
    • 实现了 DoSomething 方法,该方法接收 ExampleRequest 类型的请求参数 requestcontext(用于处理 RPC 的上下文信息,例如设置超时、获取元数据等,这里简单示例没有用到它),并返回一个 ExampleResponse 对象作为响应。
    • serve 函数中创建服务器实例后,通过 add_ExampleServiceServicer_to_server 方法将 MyExampleService 的实例添加到服务器,这样服务器就知道如何处理客户端对 DoSomething 方法的调用请求了。
  11. sirius_pb2_grpc.GRPCStub(channel)

    在使用 grpc 库创建一个 GRPCStub 对象。

    channel 通常是一个与 gRPC 服务器建立的连接通道。通过将这个通道传递给 GRPCStub 的构造函数,可以创建一个客户端存根,用于向服务器发送请求和接收响应。

posted @ 2024-06-07 09:34  疯啦吧你  阅读(12)  评论(0编辑  收藏  举报