我使用的是“流式RPC”API,其中MyRequests和MyResponse都是流式传输的
service MyStreamedService {
rpc myOperation(**stream** MyRequest) returns (**stream** MyResponse)
}
下面是一个稍微简化的类,它封装了一个gRPC流;
public class MyStreamWrapper implements StreamObserver<MyResponse> {
public MyStreamWrapper(ManagedChannel myChannel) {
myStub = MyStreamedServiceGrpc.newStub(myChannel);
// create a stream and maintain a long lived reference to the stream via StreamObserver's
myStream = myStub.myOperation(this);
}
@Override
public void onNext(MyResponse r) {
// handle the response (not shown)
}
@Override
public void onError(Throwable t) {
// very unfortunate that there is no error code in this API !
// throttle (not shown but if I don't throttle, eats CPU)
// Create a new stream
myStream = myStub.myOperation(this);
}
@Override
public void onCompleted() {
// server has called StreamObserver<MyRequest>.onCompleted
// Create a new stream using the async API
myStream = myStub.myOperation(this);
}
// Context: many threada that want to send a request asynchronously
public void send(MyRequest r) {
synchronized(myStream) {
myStream.onNext(r);
}
}
}
问题
我认为我理解的事情...
事实证明,所有答案都可以在HTTP/2规范中找到https://datatracker.ietf.org/doc/html/rfc7540#这是非常可读的。
一般评论:我发现gRPC文档很难理解,直到我意识到大多数更深层次的问题都可以通过研究HTTP2来回答,例如,HTTP2请求与proto IDL中的应用程序请求对象不符合1:1。关键点:HTTP2请求在流的持续时间内持续,可以携带许多应用程序请求对象。
流观察者
的方法是异步的,它们返回非常快,实际的网络通信将在某个时候由另一个线程执行。Stream观察者
强制转换为一个CallStream观察者
)。如果您忽略对方的就绪状态,gRPC将在其内部缓冲区中缓冲消息,直到对方就绪。不过,由于第1点中描述的缓冲,这可能会导致在某些情况下过度使用内存。grpclb
策略是最常见的负载平衡选择:它将维护多个HTTP/2连接到多个可用后端的集合,每个连接可能具有多个HTTP /2流(HTTP/2流与gRPC Streams对应1-1)。此外,grpclb将主动探测这些连接,以验证它们是否健康,并自动重新发出DNS查询(或任何其他名称解析服务,如果您使用自定义NameResolver
),以查看是否在需要时添加了任何新的后端。如果您想要使用grpc-grpclb
,请记住包含运行时依赖项。grpclb
通常不可用(大多数android设备缺乏运行后台负载均衡器的能力,即使可能,它也会很快耗尽设备的电池),但是您的连接通常会通过一些位于后端服务器前面的负载均衡器。在这种情况下,每个新的RPC通常会转到占用最少的后端。关于“我理解的事情”部分的澄清:“子通道”通常基本上是HTTP/2连接:通道是可能多个HTTP/2连接(取决于客户端能力:见第5点)到多个后端(当然取决于服务器配置)的集合,每个连接可以有多个独立的流(每个gRPC调用一个HTTP/2流)。
在服务器应用到服务器应用gRPC的情况下,关于负载平衡和名称解析的一些注意事项:
NameResolver
s.
我有这个代码: 我一直在犯这样的错误: java:不兼容的类型:com。应用句子分类请求。无法将生成器转换为com。应用句子分类请求 我已经使用Maven插件生成了gRPC Java文件。在看了多个例子后,我不确定我的问题是什么。
问题内容: 首先,让我解释一下上下文: 我必须创建一个客户端,该客户端将发送许多HTTP请求以下载图像。这些请求必须是异步的,因为一旦完成图像,它将被添加到队列中,然后打印到屏幕上。由于图像可能很大且响应分块,因此我的处理程序必须将其聚合到缓冲区中。 因此,我遵循Netty示例代码(HTTP勺示例)。 目前,我有三个静态映射,用于为每个通道存储通道ID和缓冲区/块布尔值/我的最终对象。 在那之后,
当我运行我的gRPC客户端,它试图将请求流式传输到服务器时,我收到了这个错误:"TypeError: has typelist_iterator,但期望其中之一:bytes, unicode" 我需要以某种方式对我发送的文本进行编码吗?错误消息有一定的意义,因为我肯定是在传入一个迭代器。我从gRPC留档中假设这是需要的。(https://grpc.io/docs/tutorials/basic/p
我从使用go的GRPC开始。我阅读了官方文档,并举了几个例子。 在大多数示例中,您不识别客户端,而是使用流读取/写入数据。我看到上下文中有用于检索身份验证信息的应用编程接口,并且可以为聊天请求识别客户端。但是,如果我想根据客户端标识保留流的引用/索引呢? 例如, 假设我在聊天室有3个用户。我将rpc表示为(也可能是服务器流) 例如,一个用户向该组发送一条消息,该组需要向另两个用户发送。因此,如果我
按照这里的Apache HttpAsyncClient示例,HTTPGET请求并不是一次性触发的,而是(大部分)同步触发的。 下图显示了请求的发送顺序(除了一个)。当增加请求数量时,这仍然是正确的。 我使用了另一个库(AsynHttpClient ),请求发送得更快,而且是随机的。 有什么办法可以改进这段代码,让它真正异步执行? 我添加了用于参考的代码。
客户端通过HTTP请求(通过浏览器post)调用Servlet,然后Servlet应向外部网站发送请求(get),并从网站接收响应(post)。servlet继续响应并向客户端发送响应(post)。 我的问题是如何在Servlet中发送和接收请求/响应并将某些内容发送回客户端?