目录
一,问题背景:
线上有个项目jvm参数大概这么配置,然后最近项目经常告警,接口响应超时。
-javaagent:D:\apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=my-service
-Dskywalking.collector.backend_service=127.0.0.1:11800
-Djava.net.preferIPv4Stack=true
-server -Xms1536m -Xmx1536m
-XX:MaxNewSize=128m
-Djava.awt.headless=true
-XX:+CMSClassUnloadingEnabled
二,实验结论:
这里先给出实验结果
实验条件 1,1000个线程请求100次, 2,接口异步停顿10s 3,内存配置1.5G | 服务原有jvm配置(默认po) | 去掉新生代128 | 开启Cms | 开启G1 |
内存波动 | 逐步上升后回落 | 内存平稳 | 内存平稳 | 内存平稳 |
吞吐量、qps | 449 | 592 | 572 | 694 |
|
|
|
|
|
可以看出:
由于项目用了1.8默认的-XX:+UseParallelOldGC 所以新生代默认是三分之一的内存分配,大概500m,但是由于项目jvm参数限制死了新生代128M,
所以当并发量高的时候,分配的对象直接进入老年代,内存逐渐飙升,直到触发老年代Gc后回落。
Gc过程导致项目响应缓慢,触发了业务告警。
结论:jvm参数配置不合理
三,实验过程:
实验前置条件:
采用jmeter模拟并发请求
模拟1000个线程,循环100次,模拟10万请求,请求一个接口
接口代码异步处理,并且模拟异步处理耗时10s的任务
private static ThreadFactory pushThreadFactory = new ThreadFactoryBuilder().setNameFormat("event-redirect-%d").build();
private static ThreadPoolExecutor appPushExecutor = new ThreadPoolExecutor(32, 64,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(5000),pushThreadFactory, new ThreadPoolExecutor.AbortPolicy());
//模拟代码
@RequestMapping("/testIP")
@ResponseBody
public String testIP(HttpServletRequest request) {
String ip = IpUtils.getRealIp(request);
appPushExecutor.submit(()->{
try {
List<Student> list = new ArrayList<>();
for (int i = 0; i < 20000; i++) {
Student student = new Student();
student.setName("name");
student.setAge(1);
student.setNum(1);
list.add(student);
}
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
log.info("testIP===========");
return "testIP";
}
1,服务原有jvm配置
-javaagent:D:\apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=my-service
-Dskywalking.collector.backend_service=127.0.0.1:11800
-Djava.net.preferIPv4Stack=true
-server -Xms1536m -Xmx1536m
-XX:MaxNewSize=128m
-Djava.awt.headless=true
-XX:+CMSClassUnloadingEnabled
内存逐步飙升后回落后继续飙升(回落部分是oldGc)
吞服量449qps
2,去掉新生代128m的限制
-javaagent:D:\apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=my-service
-Dskywalking.collector.backend_service=127.0.0.1:11800
-Djava.net.preferIPv4Stack=true
-server
-Xms1536m
-Xmx1536m
-Djava.awt.headless=true
-XX:+CMSClassUnloadingEnabled
内存平稳
吞吐量和592qps
3,Cms垃圾回收器
-javaagent:D:\apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=my-service
-Dskywalking.collector.backend_service=127.0.0.1:11800
-Djava.net.preferIPv4Stack=true
-server
-Xms1536m
-Xmx1536m
-Djava.awt.headless=true
-XX:+CMSClassUnloadingEnabled
-XX:+UseConcMarkSweepGC
内存波动平稳
吞吐量572qps
4,开启G1
-javaagent:D:\apache-skywalking-apm-es7-8.4.0\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=my-service
-Dskywalking.collector.backend_service=127.0.0.1:11800
-Djava.net.preferIPv4Stack=true
-server
-Xms1536m
-Xmx1536m
-XX:+UseG1GC
内存波动平稳
吞吐量694qps