生产相关问题解决思路

CPU占用问题

CPU负载是最能直观反映服务器当前的运行状况的指标,CPU负载过高会导致服务响应变慢甚至服务不可用,一般通过登入服务器后台执行命令来监控CPU负载情况。

top命令

top命令是最常用的服务器性能监控命令,登入后台执行top命令后,会定时刷新输出服务器资源占用情况。

3-1 top命令监控服务器CPU负载

针对CPU负载,我们一般只需要关注两处参数,load average和进程占用CPU时间比。

load average即系统负载,输出了1分钟、5分钟、15分钟前到现在的任务队列平均值,一般情况下load average值不超过服务器CPU核数,就说明进程没有排队现象,如超过CPU核心数量,则说明服务器压力偏高,会出现服务响应慢或不可用的现象(比如4C8G的服务器,如果load average值超过4,则说明服务器压力偏高)。

查看服务器核数可使用以下命令:

cat /proc/cpuinfo |grep "processor"|sort -u|wc -l

如果监控到服务器load average过高,需要进一步定位是哪些进程和线程占用CPU资源高,这时可先观察各进程占用的CPU时间比。执行top命令后,再键入大写P,进程列表就会根据%CPU列排序,可以获取到占用CPU资源多的进程PID。

获取到进程PID后,执行ps -mp PID -o THREAD,tid,time命令,根据TIME列找到最占用CPU时间的线程,记录下线程号TID。 

3-2 定位异常线程

之后执行printf "%x\n" TID命令,将线程ID转换为16进制。

3-3 线程号转换进制

最后执行命令jstack PID | grep TID打印出异常线程的堆栈信息。

3-4 输出异常线程堆栈

vmstat命令

vmstat命令与top命令类似,可以输出给定时间间隔的服务器的状态值,包括服务器的CPU使用率、内存使用率、虚拟内存使用情况、IO等。vmstat 1表示间隔1秒采集输出,执行结果如下图所示:

3-5 vmstat执行结果

对于CPU负载监控,我们一般只需要关注前两列r b,以及最后的us sy id列。

r:表示CPU任务队列,即等待执行的进程数,此值与load average值类似,如超过CPU核数,则说明进程出现排队,服务器压力偏高。

b:阻塞的进程数,如果此值恒不为0,则说明中间件有进程阻塞,需要进一步排查。

us:用户CPU占用时间。

sy:系统CPU占用时间。

id:系统CPU空闲时间。

us+sy+id=100,故如果us或sy值很高,说明服务器压力很大。

内存占用问题

内存溢出是生产Server最常见的宕机原因,对于内存使用率的监控一般通过命令和gclog配合实现。

free -m命令

free命令可以显示服务器当前内存使用情况,-m代表以兆字节为单位显示

第一行Mem含义:

total 总内存

used 已经使用内存

free 空闲内存

shared 共享内存

buffers Buffer 缓冲区内存

cached Page 高速缓存

第二行(-/+ buffers/cache):

used 应用实际使用的内存(第一行used-buffers-cached)

free 实际可分配的内存(第一行free+buffers+cached)

第三行Swap(交换区,即虚拟内存):

total 交换区总空间

used 已用的交换区空间

free 剩余的交换区空间

我们一般关注第二行的used和free指标,即排除缓存区的内存占用情况。

当第二行的free已经很少,且Swap区的used很多时,就说明服务器内存不足,需要进行内存调优或内存扩容。

jmap命令

对于JVM堆栈的内存分析,可以通过jmap命令实现

最常用的命令是jmap -histo:live 3248579pid,用来输出堆内对象的内存占用情况。

可以在输出的列表中观察到堆内对象的名称(class name)、创建实例数(instances)、占用内存(bytes),如果某类的内存占用特别多,则可推测有内存泄露。

gclog分析

除了通过命令观察服务器内存占用情况之外,中间件输出的JVM gclog也是判断内存是否需优化的重要依据

第一列是时间戳,从堆创建时开始计时。

第二列是垃圾收集类型,一般的gclog输出包括GC和Full GC两种(也有部分gclog输出的是YC和OC,含义一样),分别代表年轻态和老年态垃圾收集。

第三列表示垃圾收集前后对应栈区的内存占用,括号内是堆总内存占用。

最后一列是系统中断时长。

正常情况下,垃圾收集多是年轻态的垃圾收集,特点是速度快,系统中断时间短,耗时一般在毫秒级。

而Full GC,即老年态垃圾收集的耗时就比较长,一般是秒级。

如果gclog中短时间内出现大量Full GC,且系统中断时间都较长(十几秒或几十秒),则说明当前堆有内存溢出风险,需要马上进行处理释放内存。

磁盘占用问题

磁盘空间也是需要定时关注的服务器监控指标之一,尤其是对于一些基于文件存储的服务,如影像存储服务器和SSDB缓存服务器。

查看磁盘空间常用的命令是df和du,下面分别进行介绍。

df命令

如果要查看服务器磁盘空间使用率,可以通过df -h命令

此命令会列出文件系统所有磁盘分区的大小和使用占比,如果目标目录的磁盘使用率(Use%)超过80%,则需要尽快进行磁盘空间清理或扩容。

线程占用问题

线程阻塞和线程不足也是常见的造成服务不可用的原因,尤其是对于包含异步线程逻辑的系统,更应该关注线程的使用情况。

线程数限制

生产服务器一般会设置用户的最大线程数限制,如果用户创建的线程数超过此限制,就会报出OutOfMemoryError:unable to create new native thread错误(OutOfMemoryError有多种类型,不一定都是堆内存溢出)。

查看用户线程数限制可执行ulimit -a命令(文件打开数限制open files也可以看到)

查看当前线程数可通过pstree -p | wc -l命令

查看线程堆栈详情可以通过执行jstack PID命令,在输出的线程详情中可以找出异常的活动线程、异步线程,或者阻塞的线程。

线程阻塞定位

在发生线程阻塞时,需要在堆栈中快速定位STUCK的线程。可以通过jstack命令搜索。

执行jstack PID | grep STUCK找到阻塞的线程

网络连通性问题

非车核心系统一些服务需要调用外部系统的接口,有些接口地址还需要配置网络跨区访问,所以针对一些新增的接口地址要提前进行网络连通性检测,尤其是新增的服务器,要根据核心新一代权限配置清单逐一验证网络连通性。下面介绍几种常用的网络连通性验证方法。

telnet命令

telnet命令是最常用的网络连通性检测命令(由于很多服务器都对ping命令做了限制,且ping命令不能指定端口,故建议使用telnet,不过ping命令还是有很多用处的,比如查看域名解析的IP,或者查看网络延迟和丢包率),用于检测到目标IP:Port的网络是否连通。命令格式为:telnet IP Port

如果提示Connected则说明网络是连通的,如果一直Trying就说明网络不通。检测完毕后ctrl+]+quit退出。

有些服务器没有安装telnet,这时可以利用ssh远程登录口令测试网络连通性。命令格式为:ssh -p Port -v root@IP

如果提示connection established,则说明网络是连通的。

curl命令

对于外部接口的检测,有时候仅确认网络连通是不够的,还需要检测接口是否可用,这时可以利用curl命令测试接口可用性。

curl支持模拟Get和Post调用,对于Get调用或不带参数的接口,可以直接执行curl URL测试接口可用性。

对于参数在Header里的Post请求,命令格式为:

curl -d "args1=a&args2=b" URL

对于参数在Body里的Post请求,可以指定Content-type,命令格式为:

echo 'XML'|curl -X POST -H 'Content-type:text/xml' -d @- URL

netstat命令

服务器偶尔会报出无法建立连接或too many open files的错误,这时除了要考虑网络问题和文件打开数限制(此处的文件打开数是习惯叫法,更准确的描述是句柄限制,建立网络连接同样需要消耗句柄)之外,还需要考虑是否有未及时关闭的连接,即是否有大量的TIME_WAIT和CLOSE_WAIT连接。

可以通过netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'命令查看服务器的连接状态

如果TIME_WAIT或CLOSE_WAIT数量偏高且持续增长,则说明程序中可能出现了socket句柄泄露,需要通过代码扫描等手段检查是否有未及时释放的资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值