tongweb信创项目线上业务添堵题目排查

打印 上一主题 下一主题

主题 1821|帖子 1821|积分 5463

介绍

老项目迁移到TongWeb服务内,另外还必要接入其他的新服务与功能。
TongWeb 是一款国产的应用服务器软件,TongWeb 由东方通科技股份有限公司研发,旨在为企业级应用提供可靠、高效且安全的运行环境,能够承载和支撑各类 Java EE 等相干应用的部署、运行与管理。
生产上状态

TongWeb: 专用机版本
jvm堆:16G;卡顿时大概利用10G多
国产CPU:64核利用率大概74%
线程池:最少50,最高1500/400/200都试过,都可以复现;
http通道:io模式:nio2/nio都可以复现;
用户数:高峰时间,大概300多人:
监控信息看:线程池线程已利用完,利用率100%,感觉是线程不释放。
重启tongweb可以办理卡顿;天天大概8点多可以均可以复现,偶尔不复现

猜想

业务堵塞,导致tongWeb的线程资源耗尽 ,说白了执行业务任务耗时,高峰时期尤为显着
CPU偏高:CPU冲高题目,由于某些代码不考性能,并发一高特殊容易出现CPU资源不敷,又进一步拖累业务。
排查思绪

请留意以下操作一定要在业务堵塞高峰时期执行,请提前写好shell
第一步 清除系统上其他历程,系统资源,磁盘IO等干扰

检察其他历程的CPU,内存,磁盘IO(特殊是交换分区),网络IO,命令:top ,free,iostat 等
第二步 网络抓包利用tcpdump抓取pcap包tcpdump -i any tcp port 端口


可以显着看到TCP的零窗口堵塞非常之多,是否服务器返回数据字节数偏多,是前端、还是后端,如下图所示,显着该服务不是前后端分离。

留意,哀求到服务返回将近3秒。请一定结合网卡的吞吐量来排查确定题目。如果要求高并发,优化点之一

重置连接数也如此之多,更加说明业务被堵塞了
第三步 利用命令netstat抓取tcp链接的详情netstat -nat | grep -i “tcp” | grep -i “:端口” > tcp.txt


可以看到redis连接数惊人,可想而知写代码的人, redis相干业务代码一定存在什么题目。
业务服务哀求的连接数大概470 正常。
第四步 打印GC日志

猜测利用G1算法 整体看下正常。但是GC线程数过大浪费资源。设计GC参数设置不公道这里不过多展开。

第五步 dump文件,以及jstack打印线程堆栈分析

内存利用没有多大题目,存在内存走漏风险几乎可以清除

首先分析TongWeb线程

检察大多数线程堆栈线程日志都调用这几个方法,结合业务代码发现在这里,堵塞告急缘故原由,(由于安全没法截取源码代码演示各人看)

业务逻辑代码逻辑bug毛病


那CPU题目呢?继续检察堆栈线程日志
经典的Apache BeanUtils 拷贝对象性能题目
BeanUtils.copyProperties 方法虽然方便,但在性能上并不理想。它利用反射来获取和设置属性,而反射操作是比力慢的。
当必要大量复制对象时,性能影响会变得更加显著
BeanUtils 默认允许对全部属性举行读写,这可能导致意外地修改不应该被修改的字段
如果你的对象中有敏感数据,直接利用 BeanUtils 复制可能会导致数据走漏。
利用 BeanUtils 时,非常处置惩罚通常较为粗糙

sleep持有cpu的资源不释放。



redis可能得大key题目,至于内存碎片化要去服务器排查

JDK原生序列化题目
1、无法跨语言
这一缺点几乎是致命伤害,对于跨历程的服务调用,通常都必要思量到不同语言的相互调用时间的兼容性,而这一点对于jdk序列化操作来说却无法做到。这是因为jdk序列化操作时是利用了java语言内部的私有协议,在对其他语言举行反序列化的时间会有严峻的拦阻。
2、序列化之后的码流过大
jdk举行序列化编码之后产生的字节数组过大,占用的存储内存空间也较高,这就导致了相应的流在网络传输的时间带宽占用较高,性能相比力为低下的环境

各种序列化技能性能对比

第五步 打印threaID的cpu高于阈值并打印堆栈线程日志

由于安全题目,朋侪告诉甲方不允许执行该脚本。(请留意top -Hp 方式排查cpu高的题目,偶然间线程一闪而过导致手动铺抓比力难,故利用脚本比力好),详细详情请参考添加链接形貌
保举脚本编写
  1. #!/bin/bash
  2. # 由crontab触发每分钟执行一次,判断CPU使用率大于阈值时触发dump
  3. # 使用方式:
  4. # 把当前文件放到项目中与start.sh相同的目录
  5. # 修改start.sh 在脚本最后加一行,一般是这一行后边 echo "$APP_NAME is up runnig :)"
  6. # echo "* * * * * sh /export/App/bin/cpu-peak-dump.sh" | crontab -
  7. # 可配置项:
  8. # 触发dump的cpu阈值。default 70
  9. # STACK_DUMP_CPU_THRESHOLD=xxx
  10. # 触发dump时列举的线程数(按使用率由高到低排列) default 10
  11. # STACK_DUMP_THREAD_COUNT=xxx
  12. # 配置方式,使用行云分组的环境变量配置即可
  13. # stack log 存放目录 /export/Logs/
  14. # stack log 文件名: jstack_snapshot_$(date +%Y%m%d%H%M%S).log
  15. # 最后,记得配置相应的日志清理策略
  16. # 设置CPU阈值,当CPU使用率达到该阈值时触发线程快照
  17. CPU_THRESHOLD="${STACK_DUMP_CPU_THRESHOLD:-100}"
  18. THREAD_COUNT="${STACK_DUMP_THREAD_COUNT:-30}"
  19. echo "Current CPU_THRESHOLD is $CPU_THRESHOLD"
  20. JAVA_PID=$(pgrep -d, -x java)
  21. echo "Current JAVA_PID is $JAVA_PID"
  22. # 使用top命令获取当前CPU使用率,并提取其中的CPU利用率百分比
  23. CPU_USAGE=$(top -b -n 1 | grep -A10 "PID USER" | grep java | grep "$JAVA_PID" | awk '{print $9}' | cut -d'.' -f1)
  24. echo "Current Java($JAVA_PID) CPU_USAGE :$CPU_USAGE"%
  25. if [ -z "$JAVA_PID" ]; then
  26.   echo "No Java process found."
  27.   exit 1
  28. fi
  29. # 检查CPU使用率是否超过阈值
  30. if [[ $CPU_USAGE -gt $CPU_THRESHOLD ]]; then
  31.   # 使用top命令查找占用CPU最高的前十个线程,并获取它们的信息
  32.   TOP_THREADS=$(top -H -b -n 1 -p "$JAVA_PID" | grep -A$THREAD_COUNT 'PID USER' | head -n $THREAD_COUNT | grep -v 'PID')
  33.   # 使用jstack捕捉JVM线程快照
  34.   # 请将下面的Java进程ID替换为你要监视的Java进程的实际进程ID
  35.   JSTACK_OUTPUT=$(/export/servers/jdk1.8.0_191/bin/jstack "$JAVA_PID")
  36.   JSTACK_OUTPUT_FILE="/export/Logs/jstack_snapshot_$(date +%Y%m%d%H%M%S).log"
  37.   echo "当前JAVA进程ID($JAVA_PID)CPU使用率:$CPU_USAGE"% >>$JSTACK_OUTPUT_FILE
  38.   # 获取占用CPU最高的前十个线程的信息,包括线程的PID和堆栈信息,并将它们合并到同一行输出
  39.   echo "Top ${THREAD_COUNT} CPU占用线程信息:" >>$JSTACK_OUTPUT_FILE
  40.   while read -r THREAD_INFO; do
  41.     THREAD_TID=$(echo "$THREAD_INFO" | awk '{print $1}')
  42.     THREAD_NID=$(printf "%x\n" $THREAD_TID)
  43.     THREAD_STACK=$(echo "$JSTACK_OUTPUT" | sed -n "/nid=0x$THREAD_NID /,/^$/p")
  44.     THREAD_CPU_USAGE=$(echo "$THREAD_INFO" | awk '{print $9}')
  45.     echo "=======================================================" >>$JSTACK_OUTPUT_FILE
  46.     echo "线程TID: $THREAD_TID, THREAD_NID:$THREAD_NID, CPU使用率: $THREAD_CPU_USAGE%" >>$JSTACK_OUTPUT_FILE
  47.     echo "$THREAD_STACK" >>$JSTACK_OUTPUT_FILE
  48.   done <<<"$TOP_THREADS"
  49.   #  echo "====all stack as below:====" >>$JSTACK_OUTPUT_FILE
  50.   #  echo "$JSTACK_OUTPUT" >>$JSTACK_OUTPUT_FILE
  51.   echo "捕捉了JVM线程快照并保存到 $JSTACK_OUTPUT_FILE"
  52. fi
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

徐锦洪

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表