Grpc 服务优化 GC 的一个问题,请教一下大佬们

2024-04-12 17:36:56 +08:00
 dsvshx

背景:

客户端用的是 grpc 协议,这个动不了。所以服务端必须用 grpc 协议,但是我们的服务流量非常大。proto 中的 bytes 会比较大,会卡在 gc 上,性能上不去。

方案

服务端不用 grpc 框架,自己用 netty 来实现,就是两层,一层用 Netty Http2 相关的封装,一层自己手动解析 proto 的二进制,遇到 bytes 字段直接用 ByteBuf ,省掉了拷贝到堆内存的 byte[],进而节省这部分的 gc 。返回的时候直接编码成二进制 proto 的格式。

有人做过类似的吗,有什么坑吗? 或者有没有其他更好的方案解决 gc 问题,提高性能?

3126 次点击
所在节点    Java
31 条回复
haython
2024-04-12 17:45:50 +08:00
服务端非用 java 不可吗?
selca
2024-04-12 17:47:03 +08:00
外包给 1 楼
lifei6671
2024-04-12 17:55:42 +08:00
我以为你说 Golang 呢。原来是说的 Java 。Java 的瓶颈也不在 GC 上吧。
lmshl
2024-04-12 18:18:32 +08:00
一个大部分连续的 bytes 卡住 gc ,听起来还是很离谱的,除非你给出详细测试步骤,不然很难证明你的前提是对的。
即便你前提成立,也可以简单粗暴的直接上 ZGC 来解决,不需要你重复发明任何东西。
me1onsoda
2024-04-12 18:26:58 +08:00
gc stw 时长是多少
chendy
2024-04-12 18:29:31 +08:00
> proto 中的 bytes 会比较大,会卡在 gc 上
比较大是多大,卡在 gc 是怎么卡呢?

最简单的办法就是不动任何其他参数然后使劲拉内存
dsvshx
2024-04-12 19:26:48 +08:00
@lifei6671 流量大概快 2GB/s 了,每秒生成的垃圾也比较大。然后 grpc 用堆内存也得拷贝一份,cpu 也会高
dsvshx
2024-04-12 19:29:54 +08:00
@lmshl 目前是 ZGC ,流量太大 2GB/s ,堆都用了 40G 了,偶尔还是会有内存分配暂停。单个 grpc 请求比较大,可能会有几十 M
dsvshx
2024-04-12 19:30:29 +08:00
@me1onsoda 用的 ZGC ,stw 比较短,但是会有 Allocation Stall ,几百毫秒
dsvshx
2024-04-12 19:32:25 +08:00
@chendy 最大可能几十 MB ,单机流量快 2GB/s 。用的 ZGC ,主要是 Allocation Stall 内存分配暂停。
dsvshx
2024-04-12 19:34:36 +08:00
@haython 对,必须得用 java
wenhuibrave
2024-04-12 19:46:00 +08:00
zgc 设置了每隔多久强制 gc 吗?我猜测需要根据目前 gc 的具体情况做下 gc 调优,调节一些 gc 参数
dsvshx
2024-04-12 19:53:20 +08:00
@wenhuibrave 都不用强制 GC ,每分钟十几次,主要是流量大 2GB/s ,垃圾多,算下来也是这么个 GC 频率。gc 调优治标不治本。所以才想不用 grpc ,自己去解析 ByteBuf
luozic
2024-04-12 20:23:14 +08:00
描述:单个请求最大几十 MB ,单机流量 2GB/s ?
+++++++++++++++
我觉得这种还是去你们自己测试环境复现一下,把 jvm 的内存占用详细的用 arthas jfr 等工具抓一下,用那种火焰图工具看一下。
+++++++++++++++++++++++++
现在这隔靴瘙痒的,并不清楚,到底是那部分占用内存过多。
最近看到的最详细的 Java 极限性能调优过程的 1brc 挑战的 blog ,参考一下大牛是怎么极限调优的。

https://questdb.io/blog/billion-row-challenge-step-by-step/
luozic
2024-04-12 20:23:47 +08:00
流量录制+回放,就是一种不错的复现方式
zhady009
2024-04-12 22:09:00 +08:00
可以试试 Vertx, 不过我认为并不能解决你现在的问题
https://github.com/LesnyRumcajs/grpc_bench/discussions/354
momo24672
2024-04-12 22:13:46 +08:00
whx
2024-04-12 23:15:10 +08:00
https://inside.java/2023/11/28/gen-zgc-explainer/

不知道分代 zgc 能解决不,得升级到 jdk21
ccde8259
2024-04-13 03:12:27 +08:00
都知道卡 gc 了,直接的方法就是不让他参与 gc 嘛……unsafe 去 malloc 到非堆上,然后自己做对象生命周期管理就行啊……
laminux29
2024-04-13 04:00:56 +08:00
堆机器,负载均衡,试试看?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1032027

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX