-
Notifications
You must be signed in to change notification settings - Fork 45
online problems practice
landon edited this page Dec 7, 2018
·
10 revisions
- 监控先行
- 线上常见问题
- 问题排查、定位、解决
- 参考、补充
- Q & A
- 游戏正式上线后,研发这边可能没有线上服务器的权限,不能直接在线上服务器排查问题,所以必须要监控先行-grafana
- 测试期间有线上服务器权限,可以使用一些命令行直接排查问题
- 不过强烈建议将监控指标定时采样到监控服务器
- 监控指标
- 业务参数
- tps(throughput)、latency
- connections
- threadpool#queue size
- method execute time(logic handler/db save/db load/startup/shutdown/login/logout)
- error log
- jvm 参数(jstat/jmx)
- class
- S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
- DeadlockDetector
- thread state
- cpu
- db
- mongo/redis
- slow operations
- high flow
- connections
- os参数
- cpu、memory、io(带宽/流量)、network
- 业务参数
- 业务参数直接打点监控、jvm参数可直接通过jmx api获取
- 注腾讯的机器只能往里进 不能出来 即不能push信息到外部;只开放部分端口
- 要使用pull的方式
- 监控图形化界面、报警(钉钉)
- 玩家卡
- cpu高(如死循环、无限递归、fgc-stw),当前业务线程被占用,其他消息排队
- 线程被阻塞,如访问一个三方http,超时
- 死锁
- 方法执行耗时如大量玩家登录
- 并发太高,线程处理不过来,导致排队,出现'雪崩效应'
- 内存飙高(溢出、泄露)
- java 进程#res、OU一直增加
- FGC、FGCT增加,回收后内存没有明显变化
- 注:GC后res不变,不会还内存给os
- oom
- oom-killer
- 堆外内存泄露
- 数据库
- crash(如mongo primary节点挂掉-如被oom-kill)
- 连接数问题,可能出现操作mongo时抛出异常
- redis变慢
- 数据库内网流量很大(一个mongo副本集可能服务器多台backend),内网带宽被撑爆
- 业务bug
- 刷资源-回档
- 如策划配错了一个大数值
- 如邮件领取bug导致邮件未删除
- 如业务bug先加未扣
- 如扣钱逻辑不验证,外挂发过来负数,导致加钻
- 逻辑参数验证问题
- 如输入被外挂攻击,如之前的商店购买,正常最多购买10个,但是外挂发过来1亿个
- 未处理异常
- 时间调度业务未处理异常,导致影响其他时间调度的业务
- 打点、推送、日志等抛出异常,影响业务逻辑
- 网络层问题
- 顶号、断线重连、每日重置
- 登录异常(登录抛异常导致玩家无法登录,要注意新业务不要影响就玩家要做数据兼容,或者数据时要登录做脚本修复-避免玩家无法登录)、支付问题(支付未发货、刷单—未排重、丢单)
- vms/global
- 版本更新、登录验证、支付
- 三方http未做超时处理(连接超时、read超时),导致卡住业务线程,如监控的上报服务
- ...
- 刷资源-回档
-
整体情况
top # 监控整体CPU和内存 P # 按照CPU排序 M # 按照内存排序 可主要观察res jps -v # 查看java进程启动参数 load/us/id/...也可以看一下 整体cpu如果超过70% 就要报警 整体内存如果超过70% 就要报警 free -g # 需要看 + buffers/cache
-
整体卡
jstat -gcutil # 确认一下是否是fgc引起的stw top –Hp pid # 查看哪个线程占用cpu高 printf 0x%x tid # 转为16进制 jstack pid | grep nid –A 10 # 查看线程堆栈,找到占用cpu高的线程堆栈从而确认 # 可多次jstack,如果发现某业务线程的堆栈一直是固定的某一个,可能死循环、死锁、blocked
-
内存问题较高
jinfo pid/jps -v # 确认整体jvm启动参数 top + M + res # 确认Java进程res是否较高 jmap -heap # 确认java内存整体占用(cms#jdk低版本显示有bug),主要确认堆内存和metaspace是否占用过高 jstat -gcuitl # 二者结合 jmap -histo | head # 按照实例排序,注意如果加上live参数的话,会强制执行一次fgc jcmd pid VM.native_memory summary # Native Memory Tracking,需要启动参数增加-XX:NativeMemoryTracking=detail # 其他工具 pmap -x pid google-perftools #分析堆外内存 # 注:如果发现内存确实涨的很厉害,很快可能要oom了 1. 使用jmap -dump:format=b,live,file=MemoryLeak.hprof pid # 将堆内存快照导出来分析,可能会卡几秒,mat进行分析 2. 如果无法即时发现oom的问题,那么此时建议重启服务器,否则oom或者oom-killer可能会回档,后果比较严重 # 之前出现过的oom-killer问题 1. python进程占用内存较高,触发了oom-killer,killer了java进程 2. java进程越来越多的临时对象进入ou,但是一直未触发fgc(但此时res可能已经很高),此时mongod触发存库,也占用内存,触发了oom-killer(单机集群) 3. 可以强制执行一次fgc 如通过jmap histo:live或者jcmd pid GC.run或者System.gc
-
数据库统计
# mongo统计 mongostat -h xxx:40001 -u 'uuu' -p ppp--authenticationDatabase admin -n 10 mongotop -h xxx:40001 -u 'yy' -p ppp --authenticationDatabase admin -n 1 db.serverStatus(); db.stats(); db.players.stats(); rs.status(); 开启Profiling,慢查询 # redis 1. redis-benchmark 2. info(注:掌趣包括腾讯的一些机器很多命令不能使用,如keys *)
-
其他辅助
- http://xxx 玩家实时在线
- http://yyy 监控系统信息(cpu/内存/流量)
- 如果是内部测试可以使用jconsole/jvisualvm/yourkit/jprofiler直接观察
- 建议使用java11开源的jfr
- 日常开发可直接使用远程调试debug
- 服务器日志
- 熟练使用less(/、G、gg、n、N、ctrl + b、ctrl + f)、grep(-A、-B、-C)
- 注:线上服务器通常不要直接使用less或者vim打开大文件,会比较占用内存和cpu,而且使用完毕一定要退出,否则会一直在后台,如top直接就可以看到less会占用很高的cpu
-
问题定位和解决
- 直接增加日志排查,更建议使用btrace/greys/jvm-sandbox
- 使用bsh,查询内存数据
- 导号到内网,尝试复现解决bug
- 配置表可以直接热更(指后端)
- hotfix解决bug(建议使用instrumentation)
- java -profiling-practice
- Java调优系列之工具篇之btrace、gperftools
- JVM内存非典型术语介绍
- oom-metaspace
- fastjson-heap-oom
- 游戏服务器数据存储策略和宕机保护
- Java项目中mongo问题总结
- jvm-sandbox
- greys
- btrace
- gperftools
- show-busy-java-threads
- 【译】MongoDB的监控
- Redis性能监控
- jmap -histo 发现Player实例有819个,但在线玩家只有90多个,而数据库实际的玩家也只有690多个?why?
- jmap -histo:live参数后,执行fgc后,Player实例变为117个,说明确实是临时对象
- TODO 需要排除原因,为什么实例有819个?难道有多个实例Player指向同一个player?
- 做一个实现,有一个hashmap,put了很多对象,然后调用了clear,但是没有触发gc,此时实际占用的内存?
- TODO 测试
- jdk11的zgc可以了解一下,避免stw
- 之前服务器突然卡了一下(所以玩家卡了一小下),可能是因为fgc#stw