grpc 完成异步 java 服务请求/响应映射

Posted

技术标签:

【中文标题】grpc 完成异步 java 服务请求/响应映射【英文标题】:grpc complete async java service request/response mapping 【发布时间】:2018-02-27 14:26:11 【问题描述】:

Java 服务(我们称之为门户)既是 gRPC 客户端又是服务器。它为数百万个 gRPC 客户端(服务器)提供服务,每个客户端都请求一些任务/资源。根据传入的请求,门户将找出后端服务并与其中的一个或多个对话,并将返回的响应发送给原始客户端。因此,这里的要求是:

    原来的数百万客户端会有自己的超时时间 门户不应有一个线程阻塞数百万客户端(异步)。对于每个客户端对后端服务的调用(异步),它也不应该有线程阻塞。我们可以使用收到客户端调用的同一线程来调用后端服务。 如果原始客户端超时,门户应该能够将其传达给后端服务或终止对后端服务的特定调用。 如果后端服务出错,门户应该能够将其传达回调用失败的特定客户端。

所以这里的问题是:

    我们必须在这里使用异步一元调用,对吗? 中间服务器(门户)如何将原始请求与后端服务的响应相匹配? 如果后端服务出错,中间服务器如何传播错误? 中间服务器如何传播截止日期? 如果源客户端终止,中间服务器如何取消对后端服务的请求?

【问题讨论】:

【参考方案1】:

gRPC Java 可以相对容易地制作代理。为这样的代理使用异步存根是很常见的。当代理创建其传出 RPC 时,它可以在传出 RPC 的回调中保存对原始 RPC 的引用。当传出 RPC 的回调触发时,只需向原始 RPC 发出相同的调用。这解决了消息和错误。

截止日期和取消传播由io.grpc.Context 自动处理。

您可能需要引用this grpc-level proxy example(尚未合并到 grpc/grpc-java)。它使用ClientCall/ServerCall,因为它很方便,而且它不想解析消息。使用StreamObserver API 也可以做同样的事情。

这种代理的主要困难是观察流量控制。我引用的示例就是这样做的。如果使用StreamObserver API,您应该将传递给服务器的StreamObserver 转换为ServerCallStreamObserver,并通过将ClientResponseObserver 传递给客户端存根来获取ClientCallStreamObserver

【讨论】:

以上是关于grpc 完成异步 java 服务请求/响应映射的主要内容,如果未能解决你的问题,请参考以下文章

java版gRPC实战之三:服务端流

如何在 gRPC 异步服务中使用共享完成队列

GRPC Java 服务器服务

微服务架构引入的问题及解决方案

循环阻止异步请求被发送。为什么以及如何解决?

gRPC-微服务间通信实践