gRPC 四模式之 一元RPC模式

简介: gRPC 四模式之 一元RPC模式

一元RPC模式

一元 RPC 模式也被称为简单 RPC 模式。在该模式中,当客户端调用服务器端的远程方法时,客户端发送请求至服务器端并获得一个响应,与响应一起发送的还有状态细节以及 trailer 元数据(这部分不是默认发送的,需要自己实现)


[[Pasted image 20231115104223.png]]

使用场景

单次通讯,传输数据包的时候,返回收到应答。

在一元RPC模式中,状态细节和trailer元数据并不是默认就有的,它们是由服务器端根据需要添加的。状态细节通常包含了关于RPC调用的状态信息,例如是否成功,如果失败了具体是什么原因等。而trailer元数据则是一些额外的信息,例如调用的时间,服务器的处理时间等。

具体来说,状态细节和trailer元数据的形式取决于你使用的RPC框架和编程语言。在gRPC中,状态细节和trailer元数据通常以键值对的形式存在,键和值都是字符串。例如,你可能会看到这样的状态细节:{"status": "success"},或者这样的trailer元数据:{"processing-time": "123ms"}。


请注意,这只是一个例子,实际的状态细节和trailer元数据会根据你的应用需求和服务器的实现来定。

在gRPC中,服务器可以通过grpc::ServerContext对象来设置trailer元数据。这些元数据在RPC调用结束时发送给客户端。以下是一个C++的示例,展示了如何设置和发送trailer元数据:

#include <grpcpp/grpcpp.h>
#include "your_service.grpc.pb.h"  // 替换为你的服务的protobuf头文件

class YourServiceImpl final : public YourService::Service {
  grpc::Status YourMethod(grpc::ServerContext* context, const YourRequest* request,
                          YourResponse* reply) override {
    // 处理你的方法逻辑...

    // 在RPC调用结束时,设置trailer元数据
    context->AddTrailingMetadata("processing-time", "123ms");

    return grpc::Status::OK;
  }
};

在这个例子中,服务器在处理完YourMethod方法后,通过AddTrailingMetadata方法添加了一个名为"processing-time"的trailer元数据,值为"123ms"。这个元数据会在RPC调用结束时发送给客户端。

至于状态细节,它通常包含在返回的grpc::Status对象中。例如,如果你的方法出现了错误,你可以返回一个包含错误信息的grpc::Status对象:

return grpc::Status(grpc::StatusCode::INTERNAL, "An internal error occurred");

在这个例子中,服务器返回了一个状态码为INTERNALgrpc::Status对象,状态细节为"An internal error occurred"。这个状态细节会被发送给客户端,客户端可以通过检查返回的grpc::Status对象来获取这个信息。

在服务端返回时,设置多个状态和元数据

在gRPC中,你可以通过多次调用AddTrailingMetadata方法来添加多个trailer元数据。每次调用都会添加一个新的键值对。例如:

std::string status_detail = R"({
  "error": "An internal error occurred",
  "error_code": 123,
  "error_info": "Some additional info"
})";
return grpc::Status(grpc::StatusCode::INTERNAL, status_detail);

在这个例子中,服务器添加了三个trailer元数据:“processing-time”,“server-id"和"timestamp”。


至于状态细节,gRPC的grpc::Status对象只支持设置一个状态细节。如果你需要传递多个状态信息,你可以将它们编码为一个字符串,例如JSON格式的字符串,然后设置为状态细节。例如:

std::string status_detail = R"({
  "error": "An internal error occurred",
  "error_code": 123,
  "error_info": "Some additional info"
})";
return grpc::Status(grpc::StatusCode::INTERNAL, status_detail);

在这个例子中,服务器将多个状态信息编码为一个JSON格式的字符串,然后设置为状态细节。客户端可以解析这个字符串来获取这些状态信息。

客户端接取trailer元数据

客户端可以接收到服务端发送的trailer元数据和状态细节,并根据需要进行处理。

在gRPC中,客户端可以通过grpc::ClientContext对象来获取trailer元数据。例如:

grpc::ClientContext context;
YourResponse response;
grpc::Status status = stub->YourMethod(&context, request, &response);

if (!status.ok()) {
  std::cout << "RPC failed with code " << status.error_code()
            << ", message: " << status.error_message() << std::endl;

  // 获取trailer元数据
  auto trailers = context.GetServerTrailingMetadata();
  for (const auto& kv : trailers) {
    std::cout << "Trailer key: " << kv.first << ", value: " << kv.second << std::endl;
  }
}

在这个例子中,客户端首先调用YourMethod方法并获取返回的grpc::Status对象。如果RPC调用失败,客户端会打印出错误信息,然后通过GetServerTrailingMetadata方法获取trailer元数据并打印出来。

至于状态细节,客户端可以通过grpc::Status对象的error_message方法来获取。例如:

std::cout << "Status detail: " << status.error_message() << std::endl;

在这个例子中,客户端打印出了状态细节。如果状态细节是一个编码的字符串,例如JSON格式的字符串,客户端可以解析这个字符串来获取状态信息。


客户端发送 header 元数据、状态细节

在gRPC中,客户端也可以设置和发送header元数据和状态细节。这可以通过grpc::ClientContext对象来实现。

首先,客户端可以通过AddMetadata方法来设置header元数据:

grpc::ClientContext context;
context.AddMetadata("client-id", "client-001");
context.AddMetadata("timestamp", "2022-01-01T00:00:00Z");

然后,客户端可以通过TryCancel方法来取消RPC调用,并通过set_cancel_message方法来设置状态细节:

context.TryCancel();
context.set_cancel_message("The request was cancelled by the client");

在这个例子中,客户端取消了RPC调用,并设置了状态细节为"The request was cancelled by the client"。


请注意,这只是一个例子,实际的使用方式会根据你的应用需求和gRPC的API来定。在gRPC中,客户端也可以设置和发送header元数据和状态细节。这可以通过grpc::ClientContext对象来实现。


首先,客户端可以通过AddMetadata方法来设置header元数据:

grpc::ClientContext context;
context.AddMetadata("client-id", "client-001");
context.AddMetadata("timestamp", "2022-01-01T00:00:00Z");

在这个例子中,客户端设置了两个header元数据:“client-id"和"timestamp”。

然后,客户端可以通过TryCancel方法来取消RPC调用,并通过set_cancel_message方法来设置状态细节:

context.TryCancel();
context.set_cancel_message("The request was cancelled by the client");

在这个例子中,客户端取消了RPC调用,并设置了状态细节为"The request was cancelled by the client"。

补充:

取消RPC调用通常是因为客户端不再需要RPC的结果,或者因为某些条件已经改变,使得继续等待响应变得没有意义。取消可以用于各种情况,例如:


  1. 超时: 如果一个RPC调用超过了预定的时间还没有响应,客户端可能会选择取消它,以避免无限期地等待。
  2. 用户干预: 如果用户发起了一个操作,然后在操作完成前改变了主意,客户端应用可能需要取消相关的RPC调用。
  3. 资源优化: 如果客户端已经发送了多个RPC调用,但是得到了足够的信息来完成任务,它可能会取消剩余的调用,以节省服务器资源和网络带宽。
  4. 错误恢复: 如果在RPC调用过程中发生了错误,客户端可能会取消该调用,并尝试其他恢复策略。
  5. 依赖关系变化: 如果RPC调用的结果依赖于某些条件,而这些条件在调用过程中发生了变化,客户端可能需要取消调用。

取消RPC调用是异步编程中常见的一种模式,它允许应用程序更有效地管理资源和用户交互。在gRPC中,客户端可以通过调用grpc::ClientContext的TryCancel方法来取消RPC调用。服务端可以通过检查grpc::ServerContext::IsCancelled来响应取消事件,并及时停止处理。


分享一个有趣的 学习链接:https://xxetb.xet.tech/s/HY8za



目录
相关文章
|
8天前
|
消息中间件
RabbitMQ的 RPC 消息模式你会了吗?
【9月更文挑战第11天】RabbitMQ 的 RPC(远程过程调用)消息模式允许客户端向服务器发送请求并接收响应。其基本原理包括:1) 客户端发送请求,创建回调队列并设置关联标识符;2) 服务器接收请求并发送响应至回调队列;3) 客户端根据关联标识符接收并匹配响应。实现步骤涵盖客户端和服务器的连接、信道创建及请求处理。注意事项包括关联标识符唯一性、回调队列管理、错误处理及性能考虑。RPC 模式适用于构建可靠的分布式应用程序,但需根据需求调整优化。
|
21天前
|
前端开发 C# 开发者
WPF开发者必读:MVVM模式实战,轻松构建可维护的应用程序,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,MVVM(Model-View-ViewModel)模式通过分离关注点,提高了代码的可维护性和可扩展性。本文详细介绍了MVVM模式的三个核心组件:Model(数据模型)、View(用户界面)和ViewModel(处理数据绑定与逻辑),并通过示例代码展示了如何在WPF项目中实现MVVM模式。通过这种模式,开发者可以更高效地构建桌面应用程序。希望本文能帮助你在WPF开发中更好地应用MVVM模式。
48 0
|
27天前
|
网络协议 编译器 Go
揭秘!TCP、RPC、gRPC、HTTP大PK,谁才是网络通信界的超级巨星?一篇文章带你秒懂!
【8月更文挑战第25天】本文以教程形式深入对比了TCP、RPC、gRPC与HTTP这四种关键通信协议,并通过Go语言中的示例代码展示了各自的实现方法。TCP作为一种可靠的传输层协议,确保了数据的完整性和顺序性;RPC与gRPC作为远程过程调用框架,特别适合于分布式系统的函数调用与数据交换,其中gRPC在性能和跨语言支持方面表现出色;HTTP则是广泛应用于Web浏览器与服务器通信的应用层协议。选择合适的协议需根据具体需求综合考量。
101 0
|
3月前
|
存储 C++
gRPC 四模式之 双向流RPC模式
gRPC 四模式之 双向流RPC模式
95 0
|
3月前
|
安全 C++
gRPC 四模式之 客户端流RPC模式
gRPC 四模式之 客户端流RPC模式
41 0
|
3月前
|
C++
gRPC 四模式之 服务器端流RPC模式
gRPC 四模式之 服务器端流RPC模式
75 0
|
4月前
|
负载均衡 Dubbo Java
Dubbo 3.x:探索阿里巴巴的开源RPC框架新技术
随着微服务架构的兴起,远程过程调用(RPC)框架成为了关键组件。Dubbo,作为阿里巴巴的开源RPC框架,已经演进到了3.x版本,带来了许多新特性和技术改进。本文将探讨Dubbo 3.x中的一些最新技术,包括服务注册与发现、负载均衡、服务治理等,并通过代码示例展示其使用方式。
250 9
|
4月前
|
设计模式 负载均衡 网络协议
【分布式技术专题】「分布式技术架构」实践见真知,手把手教你如何实现一个属于自己的RPC框架(架构技术引导篇)
【分布式技术专题】「分布式技术架构」实践见真知,手把手教你如何实现一个属于自己的RPC框架(架构技术引导篇)
186 0
|
1月前
|
Dubbo 网络协议 Java
RPC框架:一文带你搞懂RPC
这篇文章全面介绍了RPC(远程过程调用)的概念、原理和应用场景,解释了RPC如何工作以及为什么在分布式系统中广泛使用,并探讨了几种常用的RPC框架如Thrift、gRPC、Dubbo和Spring Cloud,同时详细阐述了RPC调用流程和实现透明化远程服务调用的关键技术,包括动态代理和消息的编码解码过程。
RPC框架:一文带你搞懂RPC
|
1月前
|
XML 存储 JSON
(十二)探索高性能通信与RPC框架基石:Json、ProtoBuf、Hessian序列化详解
如今这个分布式风靡的时代,网络通信技术,是每位技术人员必须掌握的技能,因为无论是哪种分布式技术,都离不开心跳、选举、节点感知、数据同步……等机制,而究其根本,这些技术的本质都是网络间的数据交互。正因如此,想要构建一个高性能的分布式组件/系统,不得不思考一个问题:怎么才能让数据传输的速度更快?