热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

GRPC:在Java/Scala中成为高吞吐量客户端

我有一项服务,可以以很高的速率传输邮件。当前,它由akka-tcp服务,每分钟发

我有一项服务,可以以很高的速率传输邮件。

当前,它由akka-tcp服务,每分钟发送350万条消息。我决定尝试一下grpc。
不幸的是,它导致吞吐量大大降低:每分钟约50万条消息,甚至更低。

请介绍如何对其进行优化?

我的设置

硬件:32核,24Gb堆。

grpc版本:1.25.0

消息格式和终结点

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

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字节的缓冲区。查看堆栈跟踪:


  

java.lang.Thread.State:已阻止(在对象监视器上)
          在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.writeUncompressed(MessageFramer.java:168)
          在io.grpc.internal.MessageFramer.writePayload(MessageFramer.java:141)
          在io.grpc.internal.AbstractStream.writeMessage(AbstractStream.java:53)
          在io.grpc.internal.ForwardingClientStream.writeMessage(ForwardingClientStream.java:37)
          在io.grpc.internal.DelayedStream.writeMessage(DelayedStream.java:252)
          在io.grpc.internal.ClientCallImpl.sendMessageInternal(ClientCallImpl.java:473)
          在io.grpc.internal.ClientCallImpl.sendMessage(ClientCallImpl.java:457)
          在io.grpc.ForwardingClientCall.sendMessage(ForwardingClientCall.java:37)
          在io.grpc.ForwardingClientCall.sendMessage(ForwardingClientCall.java:37)
          在io.grpc.stub.ClientCalls $ CallToStreamObserverAdapter.onNext(ClientCalls.java:346)

在构建高吞吐量grpc客户方面的最佳实践方面的任何帮助都受到赞赏。



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

性能与akka-tcp实现相当。

,

有趣的问题。计算机网络软件包使用stack of protocols进行编码,并且这些协议是在前一个协议的规范之上构建的。因此,由于要在基础协议之上添加额外的编码/解码步骤,因此协议的性能(吞吐量)受用于构建协议的性能的限制。

例如,gRPC构建在HTTP 1.1/2之上,而L7 Application层​​em>或HTTP上的协议,因此其性能为受HTTP的性能约束。现在TCP本身是建立在L4之上的,而gRPC位于传输层TCP,因此我们可以推断出TCP的吞吐量不能大于gRPC层中提供的等效代码。

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

,

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

我们的经验略有不同。我们正在使用Akka Cluster处理更小的实例。对于Akka远程处理,我们使用Artery从Akka TCP更改为UDP,并实现了更高的速率+更低的响应时间和更稳定的响应时间。 Artery中甚至有一个配置,有助于在CPU消耗和冷启动响应时间之间取得平衡。

我的建议是使用一些基于UDP的框架,该框架也为您提供传输可靠性(例如,Artery UDP),并且仅使用Protobuf进行序列化,而不是使用完整的gRPC。 HTTP / 2传输通道并不是真正用于高吞吐量,低响应时间的目的。


推荐阅读
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 在Java Web服务开发中,Apache CXF 和 Axis2 是两个广泛使用的框架。CXF 由于其与 Spring 框架的无缝集成能力,以及更简便的部署方式,成为了许多开发者的首选。本文将详细介绍如何使用 CXF 框架进行 Web 服务的开发,包括环境搭建、服务发布和客户端调用等关键步骤,为开发者提供一个全面的实践指南。 ... [详细]
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
  • Java能否直接通过HTTP将字节流绕过HEAP写入SD卡? ... [详细]
  • 在JavaWeb项目架构中,NFS(网络文件系统)的实现与优化是关键环节。NFS允许不同主机系统通过局域网共享文件和目录,提高资源利用率和数据访问效率。本文详细探讨了NFS在JavaWeb项目中的应用,包括配置、性能优化及常见问题的解决方案,旨在为开发者提供实用的技术参考。 ... [详细]
  • C#实现文件的压缩与解压
    2019独角兽企业重金招聘Python工程师标准一、准备工作1、下载ICSharpCode.SharpZipLib.dll文件2、项目中引用这个dll二、文件压缩与解压共用类 ... [详细]
  • 为什么多数程序员难以成为架构师?
    探讨80%的程序员为何难以晋升为架构师,涉及技术深度、经验积累和综合能力等方面。本文将详细解析Tomcat的配置和服务组件,帮助读者理解其内部机制。 ... [详细]
  • 本文详细介绍了如何在 Linux 系统上安装 JDK 1.8、MySQL 和 Redis,并提供了相应的环境配置和验证步骤。 ... [详细]
  • 本文详细介绍了Java代码分层的基本概念和常见分层模式,特别是MVC模式。同时探讨了不同项目需求下的分层策略,帮助读者更好地理解和应用Java分层思想。 ... [详细]
  • javax.mail.search.BodyTerm.matchPart()方法的使用及代码示例 ... [详细]
  • 使用ArcGIS for Java和Flex浏览自定义ArcGIS Server 9.3地图
    本文介绍了如何在Flex应用程序中实现浏览自定义ArcGIS Server 9.3发布的地图。这是一个基本的入门示例,适用于初学者。 ... [详细]
  • 本文深入解析了通过JDBC实现ActiveMQ消息持久化的机制。JDBC能够将消息可靠地存储在多种关系型数据库中,如MySQL、SQL Server、Oracle和DB2等。采用JDBC持久化方式时,数据库会自动生成三个关键表:`activemq_msgs`、`activemq_lock`和`activemq_ACKS`,分别用于存储消息数据、锁定信息和确认状态。这种机制不仅提高了消息的可靠性,还增强了系统的可扩展性和容错能力。 ... [详细]
author-avatar
nikechen
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有