Java 业务开发常见错误 100 例
朱晔
贝壳金服资深架构师
52944 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 48 讲
代码篇 (23讲)
Java 业务开发常见错误 100 例
15
15
1.0x
00:00/00:00
登录|注册

33 | 加餐3:定位应用问题,排错套路很重要

设置JVM参数保留堆快照
应用层面
中间件和存储
网络层面
主机层面
日志级别是INFO以上
记录错误、异常信息
难以留出充足时间排查问题
权限管控严格
造数据、造压力模拟场景
使用JDK自带的jvisualvm或阿里的工具
单步调试
使用熟悉工具
监控和工具使用
客户端兼容性问题还是服务端问题
复盘是改进的关键
分析问题需要经验
定位问题要先分类
分析问题需要依据
如果无法定位到根因,有再出现的风险
不要轻易怀疑监控
快照类工具和趋势类工具需要结合使用
排查网络问题要考虑三个方面
考虑资源相互影响
考虑资源限制类问题
根据调用拓扑来分析问题
通过分类寻找规律
考虑“鸡”和“蛋”的问题
系统资源不够问题
外部因素问题
程序问题来源
定位问题出在哪个层次
快照
监控
日志
生产环境
测试环境
开发环境
思考与讨论
重点回顾
分析和定位问题需要注意的九个点
分析定位问题的套路
生产问题的排查依赖监控
排查问题的思路取决于环境
60%案例来源于开发业务项目和代码审核
40%案例来源于线上生产事故
课程案例实用
感谢学生留言
课程更新13讲
定位Java应用问题,有哪些排错套路?

该思维导图由 AI 生成,仅供参考

你好,我是朱晔。
咱们这个课程已经更新 13 讲了,感谢各位同学一直在坚持学习,并在评论区留下了很多高质量的留言。这些留言,有的是分享自己曾经踩的坑,有的是对课后思考题的详细解答,还有的是提出了非常好的问题,进一步丰富了这个课程的内容。
有同学说,这个课程的案例非常实用,都是工作中会遇到的。正如我在开篇词中所说,这个课程涉及的 100 个案例、约 130 个小坑,有 40% 来自于我经历过或者是见过的 200 多个线上生产事故,剩下的 60% 来自于我开发业务项目,以及日常审核别人的代码发现的问题。确实,我在整理这些案例上花费了很多精力,也特别感谢各位同学的认可,更希望你们能继续坚持学习,继续在评论区和我交流。
也有同学反馈,排查问题的思路很重要,希望自己遇到问题时,也能够从容、高效地定位到根因。因此,今天这一讲,我就与你说说我在应急排错方面积累的心得。这都是我多年担任技术负责人和架构师自己总结出来的,希望对你有所帮助。当然了,也期待你能留言与我说说,自己平时的排错套路。

在不同环境排查问题,有不同的方式

要说排查问题的思路,我们首先得明白是在什么环境排错。
如果是在自己的开发环境排查问题,那你几乎可以使用任何自己熟悉的工具来排查,甚至可以进行单步调试。只要问题能重现,排查就不会太困难,最多就是把程序调试到 JDK 或三方类库内部进行分析。
如果是在测试环境排查问题,相比开发环境少的是调试,不过你可以使用 JDK 自带的 jvisualvm 或阿里的Arthas,附加到远程的 JVM 进程排查问题。另外,测试环境允许造数据、造压力模拟我们需要的场景,因此遇到偶发问题时,我们可以尝试去造一些场景让问题更容易出现,方便测试。
如果是在生产环境排查问题,往往比较难:一方面,生产环境权限管控严格,一般不允许调试工具从远程附加进程;另一方面,生产环境出现问题要求以恢复为先,难以留出充足的时间去慢慢排查问题。但,因为生产环境的流量真实、访问量大、网络权限管控严格、环境复杂,因此更容易出问题,也是出问题最多的环境。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文总结了在Java应用中排查问题的一些套路和方法。作者指出了在不同环境下排查问题的方式,包括开发环境、测试环境和生产环境。在生产环境中,排查问题很大程度上依赖监控,包括日志、监控和快照。作者强调了日志记录的重要性,以及在生产环境中做好多层次的监控,包括主机层面、网络层面、中间件和存储层面,以及应用层面的监控。此外,作者还提到了快照的重要性,特别是设置堆快照参数用于在出现OOM时保留堆快照。文章详细介绍了定位问题的套路,包括程序发布后的Bug、外部因素、系统资源不够造成系统假死的问题等,并提供了针对不同问题的排查方式和解决方法。对于CPU使用高、内存泄漏或OOM、IO问题、网络相关问题等,作者都提供了具体的分析流程和解决建议。整体而言,本文为读者提供了丰富的排查问题经验和实用技巧,对于Java应用开发和排查问题的读者具有一定的参考价值。 文章还提出了两个思考与讨论问题,分别是关于App首页展示空白的问题以及分析定位问题时的监控和工具选择。这些问题引发了读者对于实际问题的思考和讨论,增加了文章的互动性和实用性。 总的来说,本文内容丰富,涵盖了Java应用排查问题的方方面面,对读者具有一定的参考价值,尤其是对于开发人员和系统运维人员来说,是一篇值得阅读的技术文章。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 业务开发常见错误 100 例》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(20)

  • 最新
  • 精选
  • hellojd
    置顶
    我们线上k8s管理服务,有时候oom,服务重启由k8s触发的,这将导致设置的生成dump 文件无效。有好的思路吗?

    作者回复: 1、需要明白,xmx设置的堆只是java进程使用内存的一部分 https://stackoverflow.com/questions/53451103/java-using-much-more-memory-than-heap-size-or-size-correctly-docker-memory-limi 所以你需要通过监控排查到底哪部分内存超限,但是heap的oom dump肯定是需要做的,并且配置-XX:NativeMemoryTracking=detail -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics,需要的时候可以通过jcmd <pid> VM.native_memory summary/detail排查 2、在排查清问题之前可以适当放开k8s的limit,以便你可以观察到内存增长的区域,方便排查问题 3、可以和运维沟通一下,在oom killed的时候(oom killed应该会让pod状态变为unhealth,这个时候可以触发hook)能否做一下heapdump、jstack等,数据不要保存在容器里 当然,像Darren的回复,在死之前做几次dump也是可以的

    2020-04-09
    3
    13
  • Darren
    首先先试着回答下@hellojd童鞋的问题,不一定对,仅供参考:k8s应该在cpu或者内存的使用率上做报警,大于90%的时候可以dump和jstack一次,甚至jstat也可以做,然后95%的时候也同样执行一次, 甚至98或者99的时候也可以做一次,这样不仅可以保留现场,同时还可以对比。可以更好的排查问题。 说说遇到的问题吧,前几天刚刚发生的:上线了一个新功能,正常情况下没事,但是只要运行新业务, 就发现内存的使用率慢慢升高,随后导致CPU的使用率升高,最后CPU的使用率大于90%,直接出发报警,最后导致服务挂了; 在分析挂之前的dump的时候发现,JDBCClientImpl有几十万个,4G的dump文件中,JDBCClientImpl就占用了3G多,在分析jstat的文件,发现full GC特别频繁,但是回收效果并不明显,导致CPU飙升,因为使用的是vertx框架,connection是手动管理; 新功能有一个情况是A方法获取connection,但是A方法内部也要调用B方法,就把connection传递给B方法,然后在B方法中关闭链接,但是B方法并不是每次都被调用,有if条件,当时是为了做健壮性判断的,现在导致不进B方法,导致数据库连接不释放,内存使用率飙升,full GC执行多次触发CPU报警。 还有一个元数据区的问题,JDK8默认的元数据区大小是20.8M,因为class等都放在元数据去,当加载的calss文件多的时候,20.8M是不够的,只要元数据扩容,必定引起full GC,因此建议在启动的时候对于元数据区设定一个合适的大小。 试着回答下问题: 1、APP的问题就不回答了,因为没有APP的经验; 2、目前我们的监控主要是(Springboot项目)spring boot actuator+Prometheus+Grafana; spring boot actuator监控jvm内部情况; 自定义exporter采集硬件使用情况及容器内部使用情况,统一上报Prometheus,然后Grafana做显示。 非Springboot项目,采用的是自研类似spring boot actuator的功能,暴露相关的metric,也是上报Prometheus。

    作者回复: 感谢分享

    2020-04-09
    24
  • 👽
    真不敢相信,如此高质量的内容,竟然只是选学的不定期加餐!!!

    作者回复: :)

    2020-04-09
    12
  • 👽
    本文理解: 应对出错其实主要就是三个阶段。 1. before:保证留有合理的日志 2. ing:提供及时的预警以及监控 3. after:有充足的应对问题的应急预案,版本回滚,服务降级等 关于个人的排错过程主要是线性的。端到端的一个过程。例如:A调B,B调C,C调D。我的做法是先看A和D,两个业务端是否正常。如果都正常,ABC的顺序挨个排查。检查A是否接收到返回结果,如果没有,则检查B是否接收到返回结果。比较粗暴,但在小型业务系统里,个人感觉处理也还好。 对于与服务器不一样的问题,通常会模拟一份服务器数据,然后本地做压测模拟服务器流量。保证问题的复现,能在本地复现问题,排查基本上就不是什么难事了。这一思路在 唐扬 老师的《高并发系统设计40问》 中有提到,模拟服务器环境,其实就是尽量把流量,数据库等环境,尽量贴近服务器环境。

    作者回复: 总结的很好

    2020-04-09
    2
    11
  • yinchi_516564
    分享几个遇到的运维犯的错误: 1、现象:同一个请求有时候能查出结果,有时候返回为空 原因:经排查是运维把应急时候用的服务器(直接返回200)误添加在了nginx代理中 2、现象:同一笔请求有时候很快,有时候超时60s 原因:运维路由规则配错导致 到mongodb 的去程和回程路径不一导致原来的mongo链接失效,client在默认情况下不会主动收回这些链接,当再次读写时就出现异常 3、现象:同一笔请求有时候慢,有时候快 原因:容器部署的服务有两个api实例假死,导致请求回源,拉低了接口整体响应的速度 目前使用到的工具 Grafana监控 主要做api接口监控 Kibana监控 主要做日志监控 听云Server 主要做服务器资源监控 还会用到arthas及MAT分析工具 最后,听老师的课程,涨了不少知识,日后写代码、分析问题有点点底气了,感谢老师无私的分享!

    作者回复: 👍🏻

    2020-04-09
    2
    8
  • 技术骨干
    内存的问题,搁以前我基本分析不出来

    作者回复: 后面有加餐会带你详细分析

    2020-04-16
    4
  • 👽
    如果你现在打开一个 App 后发现首页展示了一片空白,那这到底是客户端兼容性的问题,还是服务端的问题呢?如果是服务端的问题,又如何进一步细化定位呢?你有什么分析思路吗? 首先,切换设备,或者模拟请求,查看服务是否正常访问。以排除客户端问题。 确保服务端服务器状态,1确保正在运行,2资源占用处于正常状态,没有出现满载,3服务器可以被正常访问,排除网络问题。随后,备份即时的所有可能有需要的日志,条件允许尝试重启服务或者回滚,保证线上服务正常以及客户体验。时候根据遗留日志尝试进行排查。如果依然无果,模拟服务器环境和流量,进行Debug。 对于分析定位问题,你会做哪些监控或是使用哪些工具呢? 无论监控还是定位,对个人来说: 首当其冲:Top,检查内存CPU占用情况等等。定期不定期检查一下服务正常运行,并确认资源占用情况。 对于请求,个人的监控是,记录所有慢请求(处理时间过长的请求)。针对慢请求的情况分析,比如说,一个理应极快的请求出现了慢请求的情况就需要去分析,缓存问题,网络问题等等。 曾经的项目,会监控服务状态,服务如果宕机了会给相应负责人发送短信通知排查。

    作者回复: 👍🏻

    2020-04-09
    4
  • Demon.Lee
    一是,程序逻辑有问题或外部依赖慢,使得业务逻辑执行慢,在访问量不变的情况下需要更多的线程数来应对。比如,10TPS 的并发原先一次请求 1s 可以执行完成,10 个线程可以支撑;现在执行完成需要 10s,那就需要 100 个线程。 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 每秒都来10请求,10秒就是100个请求,故需要100个线程,终于想明白了,我是真的好笨😭。 老师的课破10000不是事吧,被低估了,我去部落吆喝吆喝。

    作者回复: 👍🏻

    2020-04-23
    1
  • Geek_3b1096
    非常实用谢谢老师

    作者回复: 欢迎转发

    2020-04-19
    1
  • Geek_a07e7d
    老师,请教个问题,k8s部署的服务怎样通过jvm自带命令查看堆栈信息

    作者回复: 这是一样的 进入docker环境后执行命令 pid是1

    2020-11-07
收起评论
显示
设置
留言
20
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部