网站首页 > 博客文章 正文
你以为程序员只是闷着头疯狂写bug,写好了发布到服务器就完了?
不,你还要修bug!但在那之前,你还要找bug!
那么问题来了,程序都部署都服务器了,怎么找bug呢?下面给大家介绍几种方法,帮助你轻松找到程序的bug。
日志篇
在上篇文章中,笔者介绍了《在Java代码中打日志需要注意什么?》。打日志是非常重要的,因为日志能够提供一些运行时的信息,非常有助于我们快速定位问题。
那么怎么通过日志去分析问题呢?我们首先从单机服务器说起,因为有时候可能bug是测试发现的,而测试环境一般机器都比较少,可能不会专门搭建ELK等日志收集器,所以可能是要到服务器上去看日志。
统一日志配置标准
这个其实是非常重要的,因为我们首先要找到日志文件的路径,才能找到日志进行分析。尤其在一个大点的团队,服务非常多,比较忌讳每个服务的日志文件路径乱放,找半天找不到日志放在哪。
所以建议团队有一个统一的日志配置标准。不论是格式、路径、保存日期和清理策略等,最好都保持一致,并写进团队的建设文档里,这样开发人员才能够快速地找到自己想要的日志。
分析日志常用命令
现在服务端大多部署在Linux服务器上,所以这里介绍一些在Linux上常用的分析日志的命令。
tail
tail命令是笔者最常用的命令。我们知道,日志文件大多都是追加的方式进行的。所以最新发生的问题一般都是在日志文件的末尾。tail命令可以打印出日志倒数第n行的日志,还可以通过-f参数来实时追踪。
# 打印x.log的末尾1000行日志,默认是10
tail x.log -n1000;
# 打印x.log末尾10行日志,并继续打印出后面新增的日志
tail x.log -f
# 这个跟上面是等价的
tailf x.log
复制代码
cat + grep
上面介绍的tail命令,可以输出文件的末尾n行。但有时候我们发现问题时已经有点晚了,这个时候可以在整个日志文件里面找。
通过cat命令,可以打印出整个日志文件的内容。但整个日志文件内容太多了,所以我们通常需要通过管道加上grep来结合,只提取我们需要的信息。
cat x.log | grep 'xxx'
复制代码
这里grep的内容“xxx”,通常建议以下值:
- 日志中的数据的id或者uid,比如43432413;
- 日志中的traceId;
- 日志中的问题描述,比如“call userService failed”;
- 日志中的文件,比如“UserServiceImpl”
当然了,这里的管道和grep,也可以和上面的tail命令相结合。另外,如果grep出来的内容比较多,后续还想分析,管道还可以将输出流输出到一个文件里,比如:
cat x.log | grep 'xxx' > temp.log
复制代码
输出到一个单独的文件里了,我们就能够对它进行下一步分析了,比如发生这个异常的数据有多少条,提取里面的关键信息。还可以通过sed命令来做。
比如:
# 打印temp.log
$ cat temp.log
error data: 124
error data: 121j
error data: 124fdsfsd
# 用正则提取里面的id
$ cat temp.log | sed -r "s/error data: (.*)/\1/g"
124
121j
124fdsfsd
复制代码
vi
cat + grep虽然好,但是不是很方便查看异常周围的日志。比如我们想查看完整的日常堆栈,可以通过vi的搜索功能来做。
vi是在Linux平台上常用的文本编辑器,功能非常强大。当然,很多朋友更习惯用功能更强的vim,用法是类似的。今天要介绍的是它的一些常用的搜索功能和跳转功能。
# 从前到后搜索
/searchKey
# 从后到前搜索
?SearchKey
# 定位光标到下一个搜索的地方
快捷键n
# 定位到光标上一个搜索的地方
快捷键N
# 设置显示行号
:set nu
复制代码
以上差不多能够在服务器上定位和分析日志了。如果你的服务器是分布式的,部署在很多台机器上,比如UAT环境和生产环境,那其实不建议再去服务器上手动分析日志,而是用成熟的日志框架去收集和分析日志。
比较常用的开源日志收集框架是ELK、Splunk等,它们都提供了web界面和丰富的查询语句支持。
远程Debug篇
现在JVM支持远程调试。其原理是因为Java是跨平台的,只要远程的字节码文件和本地的字节码文件相同,两个JVM可以通过调试协议进行通信。
?
所以这里需要保证本地和服务端的代码要一致,不然可能导致某个端点无法进入。尤其使用分支开发的同学需要注意分支是否一致
?
IDEA上有一个非常好用的远程Debug工具,下面简单介绍一下如何在IDEA上如何Debug。首先通过Run -> EditConfigurations进去,然后添加一个Remote。
然后配置一下host和端口就行了,这里需要注意的是端口是服务器上面的新端口,不要与服务本身的web端口冲突了,可以在应用启动时传入下图中的JVM参数指定端口和远程debug配置。
创建好以后,在IDEA打开你的远程debug,就可以愉快地Debug了。
?
不推荐在生产环境使用远程Debug
?
神器Arthas
Arthas是阿里开源的一款Java诊断工具,功能非常强大。官网上有一个在线的交互式教程,几分钟入门,非常方便。支持命令的自动补全、历史命令补全,管道等。这里介绍它的一些常用的功能。
Dashboard
Arthas的dashboard命令可以显示当前系统和JVM的实时状态。包括线程的状态、JVM的状态。
查看线程
通过thread 1可以打印「线程id」为1的栈。而且Arthas也支持管道,可以对输出通过管道进行grep:
[arthas@37]$ thread 1
"main" Id=1 TIMED_WAITING
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at demo.MathGame.main(MathGame.java:17)
Affect(row-cnt:0) cost in 9 ms.
[arthas@37]$ thread 1 | grep main(
at demo.MathGame.main(MathGame.java:17)
复制代码
查看方法的运行时信息
通过watch命令可以查看方法的运行时参数/返回值/异常信息。
[arthas@37]$ watch demo.MathGame primeFactors returnObj
Press Q or Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 40 ms.
ts=2020-05-10 02:53:46; [cost=1.129697ms] result=null
ts=2020-05-10 02:53:47; [cost=0.056254ms] result=null
ts=2020-05-10 02:53:48; [cost=0.056249ms] result=null
ts=2020-05-10 02:53:49; [cost=0.210126ms] result=@ArrayList[
@Integer[2],
@Integer[3],
@Integer[5],
@Integer[1039],
]
ts=2020-05-10 02:53:50; [cost=0.204834ms] result=@ArrayList[
@Integer[3],
@Integer[3],
@Integer[3],
@Integer[7],
@Integer[839],
]
复制代码
动态执行代码
这是我觉得Arthas里最强大的一个功能了!使用ognl命令可以让你的应用代码执行执行任意方法,用你制定的任何参数!比如:
[arthas@37]$ ognl '@java.lang.System@out.println("hello ognl")'
复制代码
这个时候,你的应用代码会输出“hello ognl”。
Arthas还有很多非常强大的功能,它甚至可以热更新代码,就是动态替换你想替换的某个类!
当然,笔者觉得Arthas的命令强大归强大,使用起来还是有一些复杂的,毕竟是一个基于命令行的程序。IDEA有一个arthas idea插件,可以生成arthas命令,有兴趣的同学可以试试~
以上就是关于如何更快更方便地找bug的介绍。早一秒找到bug,就早一秒挽救损失,说不定就能升职加薪哦~
关于作者
微信公众号:编了个程
个人网站:https://yasinshaw.com
笔名Yasin,一个有深度,有态度,有温度的程序员。工作之余分享编程技术和生活,如果喜欢我的文章,可以顺手「关注」一下公众号,也欢迎「转发」分享给你的朋友~
在公众号回复“面试”或者“学习”可以领取相应的资源哦~
猜你喜欢
- 2024-10-29 Jmeter常见压测错误解决(jmeter压测配置)
- 2024-10-29 TCP网络编程中connect()、listen()和accept()三者之间的关系
- 2024-10-29 移动硬盘不能读取(移动硬盘不能读取怎么修复)
- 2024-10-29 Linux Posic消息队列和System V消息队列的区别
- 2024-10-29 线上故障排查全套路,拿走不谢(在线故障检测时应注意什么)
- 2024-10-29 Arthas基础(二)(arthas原理)
- 2024-10-29 谁再说Synchronized慢,我跟谁急(是谁再说一遍)
- 2024-10-29 JVM监控命令详解(jvm gc监控)
- 2024-10-29 MySQL数据库监控(mysql数据库监控工具)
- 2024-10-29 JAVA 线上故障排查全套路(java线上debug)
你 发表评论:
欢迎- 367℃用AI Agent治理微服务的复杂性问题|QCon
- 360℃手把手教程「JavaWeb」优雅的SpringMvc+Mybatis整合之路
- 358℃初次使用IntelliJ IDEA新建Maven项目
- 351℃Maven技术方案最全手册(mavena)
- 348℃安利Touch Bar 专属应用,让闲置的Touch Bar活跃起来!
- 346℃InfoQ 2024 年趋势报告:架构篇(infoq+2024+年趋势报告:架构篇分析)
- 345℃IntelliJ IDEA 2018版本和2022版本创建 Maven 项目对比
- 342℃从头搭建 IntelliJ IDEA 环境(intellij idea建包)
- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)