• RPC和gRPC的区别


    1. 协议和传输层

    • RPC

      • 概念:RPC 是一个通用的概念,指的是程序在网络上调用远程服务的技术。
      • 传输协议:可以使用多种传输协议(如 TCP、HTTP、甚至自定义协议),具体取决于实现。
      • 序列化格式:传统 RPC 可以使用不同的序列化格式,如 XML-RPC 使用 XML,JSON-RPC 使用 JSON。
    • gRPC

      • 概念:gRPC 是 Google 开发的具体 RPC 框架,基于 HTTP/2 和 Protocol Buffers(protobuf)。
      • 传输协议:基于 HTTP/2,支持多路复用、流控制、头部压缩等特性。
      • 序列化格式:默认使用 Protocol Buffers(protobuf),一种高效的二进制序列化格式。

    2. 性能

    • RPC

      • 性能:传统 RPC(如 XML-RPC 和 JSON-RPC)通常使用文本格式,序列化和反序列化开销较大,性能可能较低。
      • 适用场景:适用于较简单的、性能要求不高的场景。
    • gRPC

      • 性能:由于使用了 HTTP/2 和 protobuf,gRPC 提供了高性能和低延迟,适合高并发和大规模系统。
      • 适用场景:非常适合需要高性能、低延迟的分布式系统和微服务架构。

    3. 功能特性

    • RPC

      • 功能:通常只支持基本的请求-响应模式,不支持复杂的通信模式。
      • 扩展性:功能较为基础,可能需要额外的组件来实现负载均衡、服务发现等功能。
    • gRPC

      • 功能:支持多种通信模式,包括单向 RPC、服务器流式 RPC、客户端流式 RPC 和双向流式 RPC。
      • 扩展性:内置负载均衡、服务发现、超时控制、重试机制等高级功能。
      • 安全性:提供内置的 SSL/TLS 支持,确保通信安全。

    4. 多语言支持

    • RPC

      • 语言支持:传统 RPC 实现可能针对特定语言(如 Java RMI、Python 的 xmlrpc),跨语言支持较弱。
      • 工具和库:需要额外的工具或库来实现不同语言之间的互操作性。
    • gRPC

      • 语言支持:支持多种编程语言,包括 C++, Java, Python, Go, Ruby, C#, Node.js 等。
      • 工具和库:提供自动生成的客户端和服务器端代码,简化了不同语言之间的互操作性。

    5. 版本和演进

    • RPC

      • 版本:传统 RPC 可能没有标准的版本控制机制。
      • 演进:通常没有内置的版本控制支持,可能需要额外的设计和实现。
    • gRPC

      • 版本:支持 API 版本控制,通过在定义文件中指定不同的服务版本来实现。
      • 演进:随着技术的发展,gRPC 继续扩展和改进,增加了新的特性和功能。

    gRPC 中,支持四种不同的 RPC 模式:单向 RPC、服务器流式 RPC、客户端流式 RPC 和双向流式 RPC。每种模式适用于不同的应用场景。以下是每种模式的详细说明:

    1. 单向 RPC(Unary RPC)

    概念

    客户端发送一个单独的请求到服务器并等待响应。这是最常见的 RPC 模式,类似于普通的函数调用。

    使用场景
    • 简单的请求-响应模式。
    • 需要立即返回结果的操作,如获取某个对象的详情。
    示例

    客户端发送一个请求来获取用户信息,服务器返回该用户的信息。

    1. ervice UserService
    2. { rpc GetUser (UserRequest) returns (UserResponse) {} }
    3. message UserRequest { int32 user_id = 1; }
    4. message UserResponse { string name = 1; int32 age = 2; }

    2. 服务器流式 RPC(Server Streaming RPC)

    概念

    客户端发送一个请求到服务器,服务器返回一个流式响应。客户端可以读取从服务器返回的多个消息,直到流结束。

    使用场景
    • 需要返回大量数据时,例如从数据库中检索多条记录。
    • 实时数据更新,如股票价格流。
    示例

    客户端请求一个用户的所有订单,服务器以流的形式返回订单信息。

    1. service OrderService
    2. {
    3. rpc ListOrders (OrderRequest) returns (stream OrderResponse) {}
    4. }
    5. message OrderRequest { int32 user_id = 1; }
    6. message OrderResponse
    7. { int32 order_id = 1;
    8. string product_name = 2;
    9. double price = 3; }

    3. 客户端流式 RPC(Client Streaming RPC)

    概念

    客户端发送一个流式请求到服务器,服务器在接收到所有请求消息后返回一个响应。

    使用场景
    • 客户端需要发送大量数据到服务器进行处理。
    • 例如,上传一个大文件,分块传输。
    示例

    客户端以流的形式发送多个传感器数据点,服务器处理后返回处理结果

    service SensorService { rpc RecordMetrics (stream MetricRequest) returns (MetricResponse) {} } message MetricRequest { double value = 1; string timestamp = 2; } message MetricResponse { string status = 1; }

    4. 双向流式 RPC(Bidirectional Streaming RPC)

    概念

    客户端和服务器都可以发送和接收多个消息。消息在流中按顺序发送,客户端和服务器可以随时读写消息。

    使用场景
    • 实时聊天应用。
    • 在线游戏中客户端和服务器的实时通信。
    • 需要双向数据流的复杂应用场景。
    示例

    客户端和服务器之间的实时聊天。

    1. proto 文件定义
    2. service ChatService { rpc Chat (stream ChatMessage)
    3. returns (stream ChatMessage) {} }
    4. message ChatMessage { string user = 1; string message = 2; string timestamp = 3; }

    实现

    以 Python 为例,这里是实现上述模式的一些基本代码:

    单向 RPC

    服务端代码

    1. rviceServicer(user_pb2_grpc.UserServiceServicer):
    2. def GetUser(self, request, context):
    3. response = user_pb2.UserResponse(name="John Doe", age=30)
    4. return response

    客户端代码

    with grpc.insecure_channel('localhost:50051') as channel: stub = user_pb2_grpc.UserServiceStub(channel) response = stub.GetUser(user_pb2.UserRequest(user_id=1)) print(response)

    服务器流式 RPC

    服务端代码

    class OrderServiceServicer(order_pb2_grpc.OrderServiceServicer): def ListOrders(self, request, context): orders = [order_pb2.OrderResponse(order_id=1, product_name="Product1", price=100.0), order_pb2.OrderResponse(order_id=2, product_name="Product2", price=150.0)] for order in orders: yield order

    客户端代码

    with grpc.insecure_channel('localhost:50051') as channel: stub = order_pb2_grpc.OrderServiceStub(channel) responses = stub.ListOrders(order_pb2.OrderRequest(user_id=1)) for response in responses: print(response)

    客户端流式 RPC

    服务端代码

    1. class SensorServiceServicer(sensor_pb2_grpc.SensorServiceServicer):
    2. def RecordMetrics(self, request_iterator, context):
    3. for request in request_iterator: print(f"Received metric:
    4. {request.value} at {request.timestamp}")
    5. return sensor_pb2.MetricResponse(status="Metrics Recorded")

    客户端代码

    with grpc.insecure_channel('localhost:50051') as channel: stub = sensor_pb2_grpc.SensorServiceStub(channel) requests = (sensor_pb2.MetricRequest(value=i, timestamp=str(i)) for i in range(5)) response = stub.RecordMetrics(requests) print(response)

    双向流式 RPC

    服务端代码

    class ChatServiceServicer(chat_pb2_grpc.ChatServiceServicer): def Chat(self, request_iterator, context): for chat_message in request_iterator: print(f"Received message from {chat_message.user}: {chat_message.message}") yield chat_pb2.ChatMessage(user="Server", message="Hello " + chat_message.user, timestamp="now")

    客户端代码

    1. with grpc.insecure_channel('localhost:50051')
    2. as channel: stub = chat_pb2_grpc.ChatServiceStub(channel)
    3. def generate_messages(): for i in range(5):
    4. yield chat_pb2.ChatMessage(user="Client", message=f"Message {i}",
    5. timestamp=str(i)) responses = stub.Chat(generate_messages())
    6. for response in responses: print(response)

    头部压缩(Header Compression)是 HTTP/2 引入的一项技术,用于减少 HTTP 请求和响应头部的大小,从而提高网络传输的效率和性能。在 HTTP/1.x 中,每个请求和相应地都会承载完整的头部信息,这些头部信息往往包含大量的波形数据。头部压缩通过减少波形和优化传输效率,显着提升了性能。

    头部压缩的机制

    HTTP/2 使用了一种名为 HPACK 的头部压缩算法,主要包含以下两个部分:

    1. 静态表(Static Table)

      • 静态表包含了一组常用的 HTTP 头部字段及其值的预定义列表。这些字段在每个 HTTP/2 实现中都是固定的。
      • 通过静态表,可以使用一个较小的索引值来表示常见的头部字段,从而减少数据传输量。
    2. 动态表(Dynamic Table)

      • 动态表在连接生命周期内动态维护头部字段值。

     

  • 相关阅读:
    N-129基于springboot,vue学生宿舍管理系统
    行情分析——加密货币市场大盘走势(10.18)
    php加密解密
    四、【React-Router5】样式丢失问题
    掌握这些技巧,让Excel批量数据清洗变得简单高效!
    怎样理解Redis中的AOF重写?
    数组与链表
    ps aux 命令使用
    JavaScript 各种小案例
    JavaSE之可变参数和泛型
  • 原文地址:https://blog.csdn.net/weixin_62518305/article/details/140934586