首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >GRPC:在Java/Scala中制作高吞吐量客户端

GRPC:在Java/Scala中制作高吞吐量客户端
EN

Stack Overflow用户
提问于 2019-11-08 10:35:32
回答 3查看 2K关注 0票数 10

我有一项以相当高的速率传送信息的服务。

目前,它由akka提供服务,每分钟发送350万条消息。我决定试一试。不幸的是,它的吞吐量要小得多:~每分钟500 k条消息,甚至更少。

请你介绍一下如何优化它好吗?

我的设置

硬件:32核,24 32堆。

grpc版本:1.25.0

消息格式和端点

消息基本上是二进制blob。客户端将100 K- 1M或更多消息流到同一个请求(异步)中,服务器不使用任何响应,客户端使用无操作观察者。

代码语言:javascript
运行
复制
service MyService {
    rpc send (stream MyMessage) returns (stream DummyResponse);
}

message MyMessage {
    int64 someField = 1;
    bytes payload = 2;  //not huge
}

message DummyResponse {
}

问题:与akka实现相比,消息速率较低。我观察到CPU使用率很低,因此我怀疑grpc调用实际上是在内部阻塞,尽管它不这么说。调用onNext()确实不会立即返回,但是表中也有GC。

我试图产生更多的发件人来缓解这个问题,但没有得到很大的改善。

我的发现 Grpc在序列化每条消息时实际上为它分配了一个8KB字节缓冲区。请参阅堆栈跟踪:

com.google.common.io.ByteStreams.createBuffer(ByteStreams.java:58),com.google.common.io.ByteStreams.copy(ByteStreams.java:105),io.grpc.internal.MessageFramer.writeToOutputStream(MessageFramer.java:274),io.grpc.internal.MessageFramer.writeKnownLengthUncompressed(MessageFramer.java:230),io.grpc.internal.MessageFramer。io.grpc.internal.MessageFramer.writePayload(MessageFramer.java:141) at io.grpc.internal.AbstractStream.writeMessage(AbstractStream.java:53) io.grpc.internal.ForwardingClientStream.writeMessage(ForwardingClientStream.java:37) at io.grpc.internal.DelayedStream.writeMessage(DelayedStream.java:252) at io.grpc.internal.ClientCallImpl.sendMessageInternal(ClientCallImpl.java:473) writeUncompressed(MessageFramer.java:168)在io.grpc.internal.ClientCallImpl.sendMessage(ClientCallImpl.java:457) at io.grpc.ForwardingClientCall.sendMessage(ForwardingClientCall.java:37) at io.grpc.ForwardingClientCall.sendMessage(ForwardingClientCall.java:37) at io.grpc.stub.ClientCalls$CallToStreamObserverAdapter.onNext(ClientCalls.java:346)

对构建高吞吐量grpc客户端的最佳实践的任何帮助都表示赞赏。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-11-13 12:22:43

我通过在每个目的地创建几个ManagedChannel实例来解决这个问题。尽管有文章说ManagedChannel本身可以产生足够多的连接,所以一个实例就足够了,但在我的例子中不是这样的。

性能与akka-tcp实现相当.

票数 5
EN

Stack Overflow用户

发布于 2019-11-09 11:51:17

有趣的问题。计算机网络包使用协议栈进行编码,这些协议建立在前一个协议的规范之上。因此,协议的性能(吞吐量)受用于构建协议的性能的限制,因为您在底层协议的基础上添加了额外的编码/解码步骤。

例如,gRPC构建在HTTP 1.1/2之上,这是应用程序层上的一个协议,即L7,因此它的性能受HTTP性能的约束。现在,HTTP本身构建在位于传输层( Transport )或L4 (Transport)的TCP之上,因此我们可以推断,gRPC吞吐量不能大于在TCP层中提供的等效代码。

换句话说:如果您的服务器能够处理原始的TCP包,那么添加新的复杂性层(gRPC)将如何提高性能?

票数 0
EN

Stack Overflow用户

发布于 2019-11-14 03:30:27

我对Akka TCP在这里的表现印象深刻:D

我们的经历略有不同。我们正在使用Akka集群处理小得多的实例。对于Akka远程处理,我们使用Artery实现了从Akka TCP到UDP的转换,实现了更高的速率+更低的响应时间和更稳定的响应时间。在动脉中甚至有一个配置,帮助平衡CPU消耗和冷启动时的响应时间。

我的建议是使用一些基于UDP的框架,它也照顾到您的传输可靠性(例如,动脉UDP),只需要使用Protobuf来序列化,而不是使用完整的gRPC。HTTP/2传输通道并不是真正用于高吞吐量、低响应时间的目的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58764891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档