JavaJava 程序员

服务启动过程性能波动的分析与解决方案

2022-05-26  本文已影响0人  马小莫QAQ

1、前言

2、问题表象

3、先说结论

4、排查过程

其实知识点就放在那里,重要的是能够将实际遇到的问题和知识点联系到一起并能更深刻的理解这部分知识。这样才能转化为经验。

4.1 最初的排查

-XX:+PrintGC 输出GC日志
-XX:+PrintGCDetails 输出GC的详细日志
-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式,你启动的时候相当于12点,跟真实时间无关)
-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-Xloggc:../logs/gc.log 日志文件的输出路径

4.2 换个思路

4.3 分析利器Arthas

不得不说,Arthas 真的是一个很好用的分析工具,节省了很多复杂的操作。

图中可以看出C2 CompilerThread 占据了非常多的CPU资源。

4.4 问题的核心

5、尝试解决

第 0 层:程序解释执行,默认开启性能监控功能(Profiling),如果不开启,可触发第二层编译;
第 1 层:可称为 C1 编译,将字节码编译为本地代码,进行简单、可靠的优化,不开启 Profiling;
第 2 层:也称为 C1 编译,开启 Profiling,仅执行带方法调用次数和循环回边执行次数 profiling 的 C1 编译;
第 3 层:也称为 C1 编译,执行所有带 Profiling 的 C1 编译;
第 4 层:可称为 C2 编译,也是将字节码编译为本地代码,但是会启用一些编译耗时较长的优化,甚至会根据性能监控信息进行一些不可靠的激进优化。

5.1 关闭分层编译

增加参数 : -XX:-TieredCompilation -client (关闭分层编译,开启C1编译)

5.2 增加C2 线程数

增加参数 :-XX:CICompilerCount=8 恢复参数:-XX:+TieredCompilation

5.3 推论

6、解决方案

6.1最终方案

6.2先放结果

6.3 预热设计

6.3.1 整体的流程表示
6.3.2 对其中的细节解释

①:排序系统接收不同的code的请求(可以理解为不同的业务的请求),在图中,不同的请求以不同的颜色标记出来。

②:表达排序系统请求的入口,虽然内部都是链式执行,但是对外的RPC是不同的接口。

③:此处使用的AOP是Around方式来完成的,设计了特定注解来减少warmup操作对既有代码的入侵。此注解放置在入口的RPC实现处,即可自动采集请求信息。

④:表达的是排序系统的流式编排系统,对外有不同的RPC的接口,但是其实内部最终都使用flowexecutor.run 来实现不同业务的不同链路的串联和实现。

⑤:AOP中使用异步存储的方式,这样可以避免因为warmup在采集流量的时候影响正常请求的RT,但是这里需要注意的是,这里的异步存储一定要注意对象的深度拷贝,否则将会出现很奇怪的异常,因为后续的链路中。排序系统都是拿着Request对象来操作的,而warmup的异步操作由于文件等操作会略慢,所以如果Request对象已经被变动之后再序列化下来下次使用,就会因为已经破坏了原始的请求导致下次启动时warmup会有异常。所以在AOP中也进行了深度拷贝的操作,使得正常的业务请求和warmup序列化存储操作的不是同一个对象。

⑥:最初的AOP设计其实是使用的before设计的,也就是不关心执行的结果,在Request到来的时候就将流量持久化下来。但是后来发现,由于排序系统中本身就存在之前遗留的bug,可能有些请求就是会产生异常,如果我们不关注结果,仍然将可能触发异常的请求记录下来,那么预热的时候可能会产生大量的异常,从而引发报警。所以,AOP的切面由before调整为了Around,关注结果,如果结果不为空,才将流量序列化并持久化存储下来。

⑦:序列化之后的文件其实是需要分文件夹存储的,因为不同的code,也就是请求不同的业务RPC的时候,Request 的泛型是不同的,所以需要加以区分,并在反序列化的时候指定泛型。

⑧:最初的设计是单线程完成整个预热操作,后来发现速度太慢,需要预热12分钟左右,且排序系统机器较多,如果每组都增加12分钟是不可接受的。所以采用多线程方式预热,最后缩短为3分钟左右。

⑨:发布系统的发布方式其实是不断的调用check接口,如果有返回了,则表示程序启动成功,接下来会尝试调用online接口完成rpc,消息队列等组件的上线,所以修改了原有的check接口,由无意义的返回“ok”,调整为测试warmup流程是否完成。如果没完成则抛出异常,否则返回ok,这样既可完成在online之前,也就是接收流量之前,完成warmup,不会发生warmup还没结束,流量就来了的情况。

7、最后

作者:网易云音乐技术团队
链接:https://juejin.cn/post/7101884435900923935
来源:稀土掘金

上一篇 下一篇

猜你喜欢

热点阅读