我们的项目通常被部署在linux系统中,在部署项目之前,我们会评估宿主机器所需要的配置,主要是内存、CPU、磁盘、网络等,我们关注点主要在CPU层面。
1、上线之前,根据业务并发能力峰值(均值)来评估所需CPU的个数,即预计承载能力(配额)。
2、当程序上线以后,根据监控情况,还要评估资源利用率来决定是否升配或者降配,即实际承载能力结余或者缺额。
3、程序运行期间,可能有各种各样的突发情况,导致比如CPU瞬间、持续过高,以至于系统服务水平降低。
本文主要通过上述问题逐步展开思考。CPU就像车辆的引擎,非常重要,直接关系到系统的运算能力,反应到我们的实际程序,就是程序的计算速度(不完全是);通俗来讲,我们的宿主机器,CPU个数多、计算频率高,所能支撑的并发能力也就相对较高,反之亦然。
涉及到的主要指令:top、mpstat、pidstat、iostat。
CPU利用率:针对进程,所占用CPU的时间比。其中IO等待不会占用CPU处理时间,但可能引起load过高。
CPU负载(平均):即常说的load,一段时间内正在使用CPU和等待CPU的平均总任务数(task,即进程);比如单核CPU时load=1,表示此CPU利用率为100%且无任务等待CPU,此时如果load=2则表示利用率为100%且有一个任务在等待。(包含CPU利用率总和 + 等待任务数,比如300%的利用率 = 3)
我们可以通过top命令查看CPU利用率和load:
在top运行页面,输入“1”即可查看每个CPU的利用率。我们需要注意,在任务栏中,%CPU表示当前进程的CPU利用率,此值为多个CPU之和,目前我们基本都是多核CPU,此值可能会大于100%,比如此进程(多任务)使用了2个CPU的60%,那么此时%CPU为120%。
一个进程瞬时的%CPU过高本身并不会引入太大问题,且整体多个CPU利用率(每个)持续保持一个中位水平(30%)反而是个好事情;不过某单个进程持续的CPU利用率过高时(长时间超过100%),我们需要引起注意,需要排查一下它是否在进行比如持续“并发的进行IO流处理”、较高并发请求处理(线程池)等,此时我们可以适度考虑增加CPU个数。
还有一种特殊情况,就是一个进程的CPU利用率为100%却发生在一个CPU上,其他CPU空闲。这种情况通常可能是程序的BUG,比如死循环等。还有一种情况“超线程”(hyper threading),单个进程的%CPU利用率在数倍以上,但是整个CPU的%us值却很小(通常单个CPU单位时间内只能处理一个进程指令,超线程可以实现在单个CPU上并发的处理多个任务的指令)。
CPU负载,我们通常关注是平均负载(average load),linux系统支持1分钟、5分钟、15分钟均值,如上图所示top指令的首行,也可以使用“uptime”(mpstat、sar、vmstat都可以完成):
# uptime
00:09:16 up 408 days, 12:56, 1 user, load average: 0.02, 0.04, 0.00
load通常是评估任务并发争抢CPU资源时“激烈”程度:
1、load = 1,core=1;表示此CPU利用率为100%,无进程任务等待CPU;如果load=1,core=2,等同于其中一个CPU利用率为100%(或者两个CPU之和为100%),另一个空闲,无进程任务等待CPU。
2、load = 2,core=1;表示此CPU利用率为100%,有一个进程任务在等待CPU;如果load=2,core=2,表示两个CPU的利用率均为100%,无进程等待CPU。
load的值需要参考CPU的个数(core个数),core=4、load=4则表示4个CPU的利用率都为100%;所以load值是可以大于1的,也完全可能大于cpu个数;但是当load > CPU时,说明“超负载”了,可以考虑适度扩容或者优化。
(大部分人因为load = cores * 0.7是一个比较合理的load负载值,比如4core,load为2.8比较理想,具体此值的科学性暂不做追究)
我们可以通过“lscpu”指令查看系统的CPU配额:
# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
## CPU总虚拟核心数 = Sockets * Core per Socket * Thread per core
CPU(s): 4
On-line CPU(s) list: 0-3
## 每个实际核心的虚拟核数
Thread(s) per core: 2
## 每个处理器持有的实际核心数
Core(s) per socket: 2
## 处理器个数
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 63
Model name: Intel(R) Xeon(R) CPU E5-2666 v3 @ 2.90GHz
Stepping: 2
CPU MHz: 2893.524
BogoMIPS: 5863.29
Hypervisor vendor: Xen
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 25600K
NUMA node0 CPU(s): 0-3
多处理器(Multi-Processor):即有多个物理处理器构成的硬件环境。(Sockets)
多核处理器(Multi-Core-Processor): 即每个物理处理器内部有多个核心。(Core per sockets)
多线程核心(Multi-thread-Core):每个处理核心支持的并发线程数,也就是常说的虚拟核心数。(Threads per Core)
处理器个数(CPU):处理器单元的个数,支持的并发处理能力,虚拟核心总数,也是我们常说的CPU个数。
1、CPU利用率不高、但是load很高的问题:我们已知,CPU利用率主要体现在进程对CPU资源的消耗上(计算和调度),但是CPU在资源调度层面其实消耗很少但是通常是处于wait状态,等待资源响应,以磁盘IO为例(包括NFS网络磁盘等),这并不需要消耗太多CPU资源,但是CPU仍然需要等待IO的状态,多任务(进程或者线程)并发的进行IO操作、特别是IO操作明显较慢时,就会出现这种情况。比如我们使用JAVA程序并发的进行多文件读写等。此时我们需要借助其他工具来帮助我们判定问题的根源:
使用“iostat -txk 1”或者“sar -d 1”(每个一秒采样)来查看:
#iostat -txk 1
12/13/2018 02:34:33 PM
avg-cpu: %user %nice %system %iowait %steal %idle
0.79 0.00 0.12 0.02 0.02 99.05
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
xvda 0.00 2.12 0.00 2.75 0.02 48.37 35.13 0.02 8.00 0.67 0.18
xvdb 0.00 0.00 0.00 0.00 0.00 0.44 252.94 0.00 8.21 0.84 0.00
其中%iowait值很高的时候,比如30%以上,我们就需要注意了。iowait表示CPU等待时间与总时间的占比,此值较高表示CPU大量的时间都在等待而不是在做实际工作,说明我们的文件IO部分已经有较大的瓶颈了,对于数据库、存储类型的服务需要关注这些。此外,我们需要明确,网络IO的阻塞通常是不占用iowait。(如果单纯分析进程对磁盘消耗,可以使用iotop指令)
1)tps:我们基于sar指令,可以看到每个磁盘的tps信息,即每秒IO请求数,不同类型的磁盘所能支持的tps是不同的,tps越高表示磁盘实际处理的请求数越多(此值高可能导致iowait,但是还取决于数据的大小avgrq-sz)。tps高不代表IO效率高,如果TPS高但是IO吞吐量小,说明都是一些小请求,此时我们可能需要优化IO请求。
2)avgqu-sz:很重要的一个判断指标,表示已接收但尚未被服务的请求数(等待队列数),此值越大,表示IO请求积压的越多,说明IO请求量已经超过了磁盘的实际处理速率,也是判断iowait原因的指标之一,通常avgqu-sz高,iowait也跟着高。我们通常建议大家适度合并IO操作,太多的、小的磁盘IO请求其实是对性能的浪费(avgrq-sze)而且影响磁盘的IO能力。
3)await:IO请求平均操作时间,此时间包括从请求被接收、队列等待、到实际执行结束;await值越高,反应在进程层面就是IO请求慢,此值越高iowait相应约高。
4)svctm:IO操作实际被执行的平均时间(不包含等待),通常大量数据IO操作会更耗时。可以对比await一起参考,通常比await小,这两个值比较接近说明IO较少的等待。
5)%util:很重要的参数,磁盘性能利用率,单位时间内磁盘处理IO所用时间的占比;此值越高,表示磁盘约繁忙,利用率高是个好事情,但是也需要警醒我们注意扩容磁盘个数。此值通常用于判断磁盘效能的瓶颈,如果过高,表示应用对磁盘效能的需求比实际能力要高,考虑升配和扩容吧。但是它本身并不能用于确定iowait。
此外,还有一个更奇怪的现象,就是应用程序没有太多磁盘IO操作,但是CPU iowait仍然很高,这通常是系统内存不足、不断触发内存与swap空间的交换导致,我们需要升级内存或者关闭swap功能(swap,成败萧何也)。我们可以通过“vmstat”来查看swap的交换情况。
此外,我们还需要关注CS次数(通过vmstat查看,CPU上下文切换),有一种情况,就是“cs切换次数很高,load也很高,但是CPU列用率并不是很高”,这种情况在一个网络代理Server或者相类似的组件中偶尔会出现。我们可以通过“pidstat -w” 来查看进程中cs的次数,如果发现有特别高的(每秒几千次),可以考虑先把进程关闭,观察一下load变化。对于java程序,盲目的设置较大的线程池用于处理网络IO操作,也可能导致这种问题的发生。
我们可以通过“iotop -o”找到磁盘高耗的进程,然后在使用上述原则去判断。
2、CPU利用率很高,但是load较低的问题:这种情况在“超线程”模式下,是会发生的;此外,如果有限的几个计算密集型的进程,仍然会较高的消耗CPU,而不会导致load较高(但是load肯定高),只要没有等待的任务,此时的load不需要过度担忧。
有关CPU的其他几个指标:
1、%us:用户态进程CPU占用率(时间)。
2、%sy:系统内核CPU占用率,此值通常较低,但是有时候开启大量的系统进程,比如shell console进行日志输出、计算,也会导致很高的%sy。有些信息表示,系统级的swap操作也会导致%sy很高,本人未能实际验证。
3、%wa:基本语义同iowait。
4、%hi:硬中断,比如网卡、磁盘、键盘等触发的中断请求处理所消耗的CPU占比。
5、%si:软中断,由应用进程程序触发的中断,对于一些涉及到高并发的网路IO、异步IO(NIO多路复用、AIO等)等应用、代理Server可能需要关注这些。软中断,我们没法避免和消除,也是很频繁和常见的,只需要注意一个事情,默认情况下(云平台优化的另说)si只发生在0号CPU上,所以0号CPU的%si很高(一般也不会特别高,因为si的处理通常都很快速,可能si的次数很大),我们可以通过“service irqbalance start” 开启中断平衡策略,此后si可以在多个CPU之间发生而不是集中在0号。(之所以在一个CPU上,主要是能耗考虑,其他CPU可以休眠节约能耗而不是频换唤醒来处理这种“很小”的中断请求)(vmstat 可以查看有关中断次数)。
对于java而言,老生常谈的问题:如果JAVA服务突发或者持续CPU高耗,怎么发现问题的原因?在此,再啰嗦一遍!
1、找到高耗的进程:使用“top”指令,然后shift + p,按照CPU利用率排序,持续观察一段时间,找到相应的进程ID,我们假定只有一个java进程。(这种姿势很多,大家选择各自喜欢的命令)
2、继续使用top,“top -Hp 37507”
此命令主要是根据PID获取相应的线程ID(十进制),当然也可以继续使用shift + p,按照CPU利用率排序。其中“37588”“37628”持续高耗CPU。
3、将线程ID,转换成hex:printf '%x\n 37588' ,值为92d4
4、通过jstack dump线程栈信息:jstack -l 37507 > /tmp/stack.dump,建议多采样几次,线程信息文件很小,几十K,不用担心。
5、我们通过“vim stack.dump”文件,搜索“92d4”找到线程的执行状态信息:
"SinkRunner-PollingRunner-DefaultSinkProcessor" #33 prio=5 os_prio=0 tid=0x00007f609c003000 nid=0x92d4 runnable [0x00007f60f81fe000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.NativeThread.current(Native Method)
at sun.nio.ch.NativeThreadSet.add(NativeThreadSet.java:46)
at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:207)
- locked <0x00000005df810918> (a java.lang.Object)
at java.nio.channels.Channels.writeFullyImpl(Channels.java:78)
at java.nio.channels.Channels.writeFully(Channels.java:101)
at java.nio.channels.Channels.access$000(Channels.java:61)
at java.nio.channels.Channels$1.write(Channels.java:174)
- locked <0x00000005df8107e8> (a java.nio.channels.Channels$1)
at java.io.OutputStream.write(OutputStream.java:75)
at org.apache.flume.serialization.BodyTextEventSerializer.write(BodyTextEventSerializer.java:70)
...
可以看到此线程正在进行文件读取。
此外,我们需要认知一下,JAVA中的线程处于BLOCK/WAITING(对应wait()、sleep()、join()等等)其实不消耗CPU的,但是无休止的、频繁的阻塞、唤醒多线程,仍然可能导致CPU利用率极高,比如粗暴的死循环“Thread.sleep(0)”等。
1、上线之前,我们的web项目部署环境,单机的CPU个数如何评估?
我们认定,大家的web项目均为分布式部署,但是单台机器的CPU个数该如何评估呢?其实这个事情,没有公式可以计算,因为合理值取决“业务操作类型(高耗还是短频快)”、“并发量(峰值、均值)”、“是否大量访问外部存储系统”、“本地磁盘性能”、“网络效能”等等,甚至老板的任性(过高的、不切实际的夸大业务能力,过于苛刻的SLA要求)都会对机器的配置产生很大影响。
我们建议:
1)粗略评估业务均值的并发能力;对于web系统通常是QPS,然后根据接口的平均响应时间,换算成所需并发能力,比如接口处理时间为10ms推导出每秒可以处理100个请求,8Core应该可以支持800 QPS,如果你需要单机支持2000QPS,那么可以暂定至少需要16Core(> 1600QPS)。对于存储类型的系统,我们还需要考虑磁盘IOPS等。
2)考虑你的业务峰值,尽管我们的系统配置不能按照峰值来配额,但是如果没有合理的消峰策略(限流等),我们仍然可能面临崩溃。
3)最重要的,就是通过压力测试,来评估你的实际需要,这才是可行的、科学的方式;构建一个与实际环境接近的业务模型和服务集群,通过压测,评估4Core、8Core等等配置下的服务能力,以及集群环境下对整体服务能力的加权等。
4)对于web系统,我们建议多个中小型配置的机器,优于少量的高配机器。对于存储类型、服务中间件等则另说。
2、我们系统运行如何判断是否决定升配或者降配?
我们可以通过监控,持续观测系统对CPU的消耗,综合评估业务的增长速率,我们即可评估出当前以及未来一段时间内系统对CPU的实际需要能力。CPU利用率、load就是很直观的数据。我们也可以使用比如“vmstat”、“sar -q”(runq-sz,等待CPU的任务数,持续大于2)等来判断CPU的瓶颈。
参考:
1、https://www.tecmint.com/understand-linux-load-averages-and-monitor-performance/
2、https://serverfault.com/questions/667078/high-cpu-utilization-but-low-load-average
3、https://unix.stackexchange.com/questions/134381/very-high-cpu-load-but-nothing-significant-in-top
4、https://unix.stackexchange.com/questions/405636/high-load-but-low-cpu-usage
- 大小: 340.2 KB
- 大小: 97.1 KB
- 大小: 107 KB
分享到:
相关推荐
通过Java程序获取Windows/Linux系统的CPU信息、内存信息、硬盘信息、网络信息、操作系统信息等。
java 获取win/linux系统指标, 内存 cpu 负载 进程 网络io 磁盘io 等
系统实现了基于Java的Linux运维监控工具Wgcloud,支持系统硬件信息、内存、CPU、温度、磁盘空间及IO、硬盘SMART、系统负载、网络流量等监控,服务接口监测,大屏展示,拓扑图,端口监控,进程监控,Docker监控,日志...
Linux运维监控工具,支持系统硬件信息,内存,cpu,温度,磁盘空间及IO,硬盘smart,系统负载,网络流量等监控,服务接口监测,大屏展示,拓扑图,端口监控,进程监控,docker监控,日志监控,文件防篡改,数据可视...
服务器信息管理
1、WGCLOUD支持主机或服务器各种指标监测(cpu使用率,cpu温度,内存使用率,磁盘容量空间,磁盘IO,硬盘SMART健康状态,系统负载,连接数量,网卡流量,硬件系统信息等)。 2、支持监测服务器上的进程应用、文件...
使用此工具,您只需将 Jmeter 结果文件 (.jtl)、一些 NMON 资源监控日志 (.nmon) 和 CPU 负载监控日志 (.load) 放入目录,然后运行该工具即可获得分析图表。 该工具可以启用自动性能测试。 系统要求 操作系统 Linux...
公司的产品一直紧跟 .net core 3.0 preview 不断升级, 部署到 Linux 服务器后, 偶尔会出现某个进程CPU占用100%. 由于服务部署在云上, 不能使用远程调试; 在局域网内的Linux 服务器 或 Windows开发机上又不能重现这...
cpu mem disk net 线程,进程 第三方库 poi Jsoup zxing Gson 数据结构 树 栈 链表 队列 图 操作系统 linux 代码控制 自动化代码检查 sonar 代码规范 阿里巴巴Java开发规范手册 UMPAY——...
最近学习Nginx+tomcat实现 负载均衡。 首先大家注意: 本文章中没有session共享,关于session共享我会在下一篇中讲解,先实现Nginx+...们的系统既要求性能,又要比较好的利用上负载均衡 关于memcached稍后会发表出来
其核心模块包括:服务器群集监视,ES群集监视,CPU监视,内存监视,数据监视(mysql,oracle,pg),服务心跳检测,应用程序进程管理,磁盘IO监视,系统负载监视,监视警报信息推送。 WGCLOUD-v2.3.6中文版自述文件...
java收银系统源码系统设计说明 这个README是基于 . 然而,这个版本包含了我在浏览材料时附加的附加注释和知识。 第 1 步:回顾可扩展性视频讲座 涵盖的主题: 垂直缩放 水平缩放 缓存 负载均衡 数据库复制 数据库...
OSHI是Java的免费的基于JNA的(本机)操作系统和硬件信息库。 它不需要安装任何其他本机库,并且旨在提供一种跨平台的实现来检索系统信息,例如OS版本,进程,内存和CPU使用率,磁盘和分区,设备,传感器等。 支持...
kangle的访问控制理念来自linux的iptables防火墙,kangle实现很多最小化的匹配模块和标记模块,通过组合,反转可以实现最复杂的需求;从而实现强大的访问请求控制(url,ip地址,连接数/网速限制,http头,时间控制,多种...
其核心模块包括:服务器群集监视,ES群集监视,CPU监视,内存监视,数据监视(mysql,oracle,pg),服务心跳检测,应用程序进程管理,磁盘IO监视,系统负载监视,监视警报信息推送。 1.采用服务器与客户端的协同...
相关巡检记录单: 备注:《服务器信息列表》 《服务器指示灯巡检表》 服务器系统管理 服务器系统管理主要分为: Windows系统管理 Linux系统管理 Windows系统管理 1. 磁盘空间使用 计算机管理——磁盘管理 磁盘空间...
ORC是一种专为Hadoop工作负载设计的自描述类型感知列式文件格式。 它针对大型流读取进行了优化,但具有集成支持,可快速查找所需的行。 以列格式存储数据使阅读器仅可以读取,解压缩和处理当前查询所需的值。 由于...
CPU指标主要指的CPU利用率,包括用户态(user)、系统态(sys)、等待态(wait)、空闲态(idle)。CPU 利用率要低于业界警戒值范围之内,即小于或者等于75%;CPU sys%小于或者等于30%, CPU wait%小于或者等于5%。单核CPU也需...
此命令通过结合Linux操作系统的ps命令和jvm自带的jstack命令,查找Java进程内CPU利用率最高的线程,一般适用于服务器负载较高的场景,并需要快速定位导致负载高的原因。