程序员如何优雅地解决线上问题?
沈阳市和平区爱尚职业培训机构
发表于:2022-08-05 17:13:09 8次浏览身为一个程序员,遇到线上问题那都是家常便饭的事儿。
如果你在深夜看到一群同事围在一起,他们是在共同探讨什么哲学问题么?非也,他们一定是遇到了线上BUG。
线上问题只要影响到了核心业务流程那便是事故,所以一旦事故发生,无论你在约会,还是周末打游戏,甚至是在睡觉,只要接到了来自公司的,那只能赶紧连上公司网络加班了。
BUG分类
线上问题是复杂多变的,我们一般将bug分为系统和业务bug。
系统bug
业务部署在整套系统上运行,一旦出现系统bug则业务会被严重拖垮。如CPU爆满、服务不可用、甚至服务器宕机等都属于系统的bug。
如果是CPU,那是由哪个线程,哪个类,甚至是哪个方法导致的?
若是业务流程正常但是部分服务性能拉跨,那么如何定位到问题在哪儿?
因为是线上发生的事儿,所以重点在于如何迅速解决。
以下分享我常用的一些问题排查工具。
linux定位工具
1.CPU高负载,甚至?
perf工具
perf是linux的性能分析工具,核心作用之一就是用来查看热点函数的分布情况。
用它可以生成火焰图查看到函数的资源占用情况,函数的调用栈越深火焰就越高。所以对于异常的函数一眼就能看出。
如上图通过调用栈你可以看出Monitor管程在反复调用enter和wait,这种情况下就可以判断出该程序已经发生死锁且存在性能问题。假设有大量线程请求这段代码,那么CPU资源将被迅速打满!
在的“713B站事故”里技术团队在事故发生时就用到了当前工具生成了火焰图,地分析出了事故的根因也就是导致CPU的lua热点函数。
2.某一进程存在异常嫌疑,想知道它的状态?
ps命令
我们项目部署的服务器里在跑的进程老多了,java进程、nginx进程、redis、消息队列进程等等。
举个例子,假设在某量高峰期系统监控到整个服务性能下降5倍,业务被严重拖垮,在确定没有业务层面bug的情况下大概率就是因为服务性能达到瓶颈了。如何确定瓶颈在哪儿?
大部分情况下通过系统告警就可以知道大概问题所在。如发生消息堆积我们就该怀疑消息生产者和消费者的状态,这个时候就要具体去查看消息队列这一进程。
可以使用一些轻量级的linux命令,如ps:
[root@linuxfancy ~]# ps -ef | grep queuejob
root 1303 1 0 Apr17 ? 00:00:00 /usr/sbin/queuejob
root 3260 3087 0 Apr17 ? 00:00:00 /usr/bin/queuejob /bin/sh -c exec -l /bin/bash -c "env GNOME_SHELL_SESSION_MODE=classic gnome-session --session gnome-classic"
root 24174 19508 0 11:39 pts/0 00:00:00 grep --color=auto ssh
[root@linux265 ~]# ps -aux | grep queueA
root 1303 0.0 0.0 82468 1204 ? Ss Apr17 0:00 /usr/sbin/queueA
root 3260 0.0 0.0 52864 572 ? Ss Apr17 0:00 /usr/bin/queueA /bin/sh -c exec -l
root 24188 0.0 0.0 112652 956 pts/0 S+ 11:39 0:00 grep --color=auto ssh
该命令还可以用于对进程的资源使用情况进行排序:
[root@linuxfancy ~]# ps aux | sort -nk 3
[root@linuxfancy ~]# ps aux | sort -rnk 4
3.我想知道内存&磁盘的使用情况?
vmstat命令
vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写。
它是一个用于监控内存和磁盘使用情况的工具,但是也可以用来查看CPU的一些指标,如中断次数等。使用它可以查看内存使用的详细信息和磁盘的读/写情况。
以上表头字段的说明如下:
Procs(进程):
r: 运行队列中进程数量
b: 等待IO的进程数量
Memory(内存):
swpd: 使用虚拟内存大小
free: 可用内存大小
buff: 用作缓冲的内存大小
cache: 用作缓存的内存大小
Swap(交换):
si: 每秒从交换区写到内存的大小
so: 每秒写入交换区的内存大小IO:(现在的Linux版本块的大小为1024bytes)bi: 每秒读取的块数bo: 每秒写入的块数
System(系统):
in: 每秒中断数,包括时钟中断
cs: 每秒上下文切换数
CPU(以百分比表示)
us: 用户进程执行时间(user time)
sy: 系统进程执行时间(system time)
id: 空闲时间(包括IO等待时间),中央处理器的空闲时间
wa: IO等待时间
从以上命令就可以很清晰地看出服务器的各方面性能情况。除此之外还有以下命令也可以在排查或者调优中使用:
业务bug
如何定位到业务bug?
出现了业务bug那就纯纯的是开发或测试的锅了。
bug确定后步一定是先看日志,只要你写需求的时候日志打的全,一般出现了问题日志或者告警都会时间推送。
通过日志我们可以定位到bug对应代码的位置,但这仅仅是步,因为你只知道哪里出了问题,并不知道代码出了什么问题(除非一眼就能看出)。
所以下一步,看数据,数据是业务应用的核心。若通过日志和页面表现查看到你的主流程是没有问题的,那么下一步就是要确定表的数据是否有问题,数据存在bug的表现会是各方面的,可能是用户反馈,也可能是流程错误,这要取决于你表的设计。
切记!!线上数据是重中之重,当你决定要修复数据,在处理之前一定要做好备份,这样起码可以保证事情不会变的更糟。一般情况下修改线上数据这种活都需要你写好SQL,然后经过leader审批再交给DBA来操作,一定不要干出删库跑路这种事哟。
假设验证了你数据是OK的,那么问题就极大可能出现在了代码层面。
当代程序员难过的瞬间无非就是有一个非常紧急的线上bug需要你来解决,但是摆在你面前的却是一堆屎山代码!!
修改业务bug重要的是要将buG点修改掉并且保证其它业务还能正常运行,这是牵一发而动全身的事情,否则bug只会越改越多。
所以平时应该预知到这些风险,做好代码设计。总结一下定位业务bug的正确步骤:
方案设计
代码设计
一般公司都有自己的代码设计规范。比如由外到里包装代码,每一个方法都要有对应的职责,并且一个方法不要超过100行,一个类不要超过1000行代码等。清晰的结构可以让你和他人更好地review代码,避免看起来一头雾水。
写业务逻辑有两种方式,一种就是简洁明了的线性逻辑,另一种就是通过封装代码来减少代码耦合提高内聚性,也就是我们说的设计模式的使用。两种方式各有优缺点,但是工作多年了咱写的代码也不能直里直气的,多少得带点”艺术“对吧?一下我经常使用但是也不会特别复杂的设计模式。
设计模式
工厂模式
这是常使用的设计模式之一。
文中图片素材来源网络,如有侵权请联系删除
程序员如何优雅地解决线上问题?原创内容,请点击 沈阳JAVA培训
热门课程
-
沈阳java架构师培训课程
询价
-
java工程师培训零基础入门
询价
-
沈阳web前端开发零基础培训
询价
-
沈阳软件测试零基础就业培训班
询价
-
沈阳编程零基础就业培训班
询价