最近笔者经常处理了一些线上的问题机器。特抽空写一篇文章将处理系统性能问题和优化思路进行总结,方便后续工作中系统故障的排查。作为运维,收到网管系统性能报警应该是常有的事情。而快速进行问题定位并解决则是工作的关键。我们在排查或者优化一个系统的时候无外乎从以下几个方面考虑:
1.CPU的使用率异常,如某个核心的使用率过高,而其它核心则处于空闲的状况。
2.内存的使用状况:通常需要注意是否程序内存泄漏导致的。
3.磁盘IO性能:通常磁盘IO不正常时我们需要判断程序是否处在顺序读写的状态。
4.网络IO负载:如web服务要考虑time_wait状态的连接数;如代理服务器,检查系统打开的socket连接数。
5.程序性能问题:缓存和DB类注关注写的性能,web服务类关注内存的使用
6.系统BUG:一般都是在某些高并发场景才体现出来问题。
常用的判断工具和命令的用法总结如下:
1.系统性能综合判断工具vmstat
当系统出现性能瓶颈后可以使用vmstat命令简单判断一下进程的运行状况及系统资源的使用率,详细输入情况如下:
注意事项:
1.r和b的数量,一般r小于CPU的核心数,b表示阻塞的队列长度。如果r并未达到最大值而b的数量较多,我们就需要观察进程所需要的资源状况。
2.注意in和cs的比例和数量,in表示中断的请求数,而cs才代表CPU对中断的处理状况。如果有较多的上下文切换则可以结合top命令观察CPU性能。
选项解释:
r running状态进程个数,小于CPU核心数(CPU时间片 + 所需要的资源) b 被阻塞的进程队列的长度(等待I/O完成即进程所需要的资源未到位或者未拿到CPU时间片) swpd 从物理内存交换至交换分区的数据量 free 空闲物理内存空间 buff buffer cache的空间大小,即IO处理时的缓冲。(结果) cache page cache的空间大小,缓存的是linux中的具体文件。进程运行时所需要的资源。(过程) si 从内存转到swap分区 so 从swap到内存(kb/s) bi 从块设备读入内存的数据量(kb/s),如select bo 从内存保存至块设备的数据量(kb/s),如update,insert in 中断发生的速率,通常意味每秒多少次中断请求发生产生原因:时间片轮转,IO(磁盘/网络) cs 对中断的响应,即上下文切换(进程切换)个数
2.LinuxCPU使用状况排查命令top(htop)
注意事项:
1.键入1观察各CPU使用状况,可能会出现某些核心使用率较高而某些核心却处于空闲状态。如果运行类似于nginx这样的web应用可以将核心与进程绑定,这样既能将用户请求负载均衡也能减小CPU上下文切换的消耗。
2.使用该命令一般会查看每个CPU的使用率。如果发现id资源较少,也可以观察wa状态百分比,该状态高百分比也有可能是程序未能拿到运行时所需要的资源或者时间片。所以有的时候我们发现系统load较高,而cpu use较少的情况。都是因为进程在等待所运行资源的到位。
3.可以键入M基于内存使用大小排序观察各进程内存使用大小。
选项解释:
3.内存信息展示free
注意事项:
1.根据buffers和cached的含义,一般我们认为系统可用内存大小为:free + cached
2.linux内存处理机制:程序在运行的过程中,进程会加载程序所需要的资源到内存,而当进程运行结束其所cache的资源也不会被释放。当其它程序需要资源时,才会根据策略对cache中的内存进行清理。这种内存使用机制有利于提高利用共享内存通信程序的效率。
4.实时内核slab缓存信息展示
Linux内核需要为临时对象如任务或者设备结构和节点分配内存,缓存分配器管理着这些类型对象的缓存。现代Linux内核部署了该缓存分配器以持有缓存,称之为片。不同类型的片缓存由片分配器维护。slabtop命令,该命令显示了实时内核片缓存信息。
SReclaimable代表可回收内存的大小,可以使用slabtop -s c选项基于cache size进行排序展示各组件的slab使用状况。
5.系统IO判断命令iostat
注意事项:
1.类似iostat这种交互式命令,我们通常都会观察取得第二次往后的数据。上图中最后一列表示1s中有百分之多少的时间用于I/O操作。或者说1s中有多少时间IO队列是非空的。
2.如果%util接近100%,说明产生的IO请求太多,IO系统已经满负荷,该磁盘可能存在性能瓶颈。可考虑程序是否为顺序读写。
3.idle小于70%时,如果wa较多,伴随IO就会有较大的压力,可以结合vmstat查看b参数(等待资源的进程数)和wa参数(资源及时间片)排查。
选项解释:
rrqm/s 每秒进行 merge 的读操作数目。即 delta(rmerge)/s wrqm/s 每秒进行 merge 的写操作数目。即 delta(wmerge)/s r/s 每秒完成的读 I/O 设备次数。即 delta(rio)/s w/s 每秒完成的写 I/O 设备次数。即 delta(wio)/s rsec/s 每秒读扇区数。即 delta(rsect)/s wsec/s 每秒写扇区数。即 delta(wsect)/s rkB/s 每秒读K字节数。是 rsect/s 的一半,因为每扇区大小为512字节。(需要计算) wkB/s 每秒写K字节数。是 wsect/s 的一半。(需要计算) avgrq-sz 平均每次设备I/O操作的数据大小 (扇区)。delta(rsect+wsect)/delta(rio+wio) avgqu-sz 平均I/O队列长度。即 delta(aveq)/s/1000 (因为aveq的单位为毫秒)。 await 平均每次设备I/O操作的等待时间 (毫秒)。即 delta(ruse+wuse)/delta(rio+wio) svctm 平均每次设备I/O操作的服务时间 (毫秒)。即 delta(use)/delta(rio+wio)
6.网络连接排查命令netstat
1.常用选项:
netstat -tunlp 显示 tcp/udp监听的端口和运行进程。如不使用-n选项,会根据/etc/services中的文件解析端口名称 /etc/services 该文件显示协议端口及对应的名称,可以自行更改 netstat -s 协议包数据统计 netstat -tan 显示所有的TCP链接,协助tcp状态机进行问题排查,最大socket 65535等
2.socket设置:
对于linux操作系统来说,默认能够打开的2^16=65536(0- 65535)端口,而系统默认设置的随机端口号只有28232个,可以通过以下文件查看:
$ cat /proc/sys/net/ipv4/ip_local_port_range 32768 61000
3.思路扩展:
对于一般的反向代理server,除了自身服务监听端口外,可以使用的随机和后端real server链接的端口也是有限的的。需要使用上面的方法修改一下内核参数。而服务器对前端用户的响应是通过socket处理的。为了尽可能的提高并发访问量需要使用ulimit命令提升系统能够打开的最大文件描述符。socket的端口是高速TCP/IP协议把请求发到这个socket处理程序上socket.accept()来,然后生成的socket对象会记住具体是哪个客户端发来的请求。所以在系统性能可能打开最大的文件描述符的范围内,服务端可以用这一个端口服务无数的客户端。
4.加速端口回收实现端口快速重用:常用方法可以自行Google。
7.网络流量抓取工具tcpdump
tcpdump命令的使用较为灵活,一般可以基于源和目的协议/端口/IP进行数据抓去,详细使用语法这里就不再介绍了 。需要特别注意的是我们一般使用-c选项指定抓取数据包的数量,-w选项以wireshark能够理解的方式保存抓去的内容。
通过以上的一些命令及问题的处理思路,大致能够对一台服务器的使用状况做初步的判断。欢迎大家随时交流~~