在部署项目前,你需要估量一个项目运行硬件环境需要的资源。项目运行过程中,需要对服务器资源进行监控,以便提前预警规避风险。

通常线上项目出问题,除了项目自身的bug外,多是由于服务器资源不足导致的。比如内存溢出、磁盘空间满了、网络不可用,打开句柄最大连接数限制等。

查看当前运行进程参考博文:Linux服务器进程管理与监控(top|kill|ps|nohup)​ 查看磁盘空间参考博文:Linux - df与du命令查看磁盘空间 修改最大连接数参考博文:Linux - ulimit命令详解与修改不生效 文件权限修改参考博文:chmod/chown命令与文件权限设置

下面详细介绍一下系统资源监控的几个常见命令。

【1】vmstat命令监控系统资源

vmstat命令的含义为显示虚拟内存状态(“​​Virtual Memory Statistics​​”),但是它可以报告关于进程、内存、I/O等系统整体运行状态。

① 基本介绍

语法

vmstat (选项) (参数)

选项

  • -a:显示活动内页;
  • -f:显示启动后创建的进程总数;
  • -m:显示slab信息;
  • -n:头信息仅显示一次;
  • -s:以表格方式显示事件计数器和内存状态;
  • -d:报告磁盘状态;
  • -p:显示指定的硬盘分区状态;
  • -S:输出信息的单位。

参数

  • 事件间隔:状态信息刷新的时间间隔;
  • 次数:显示报告的次数。

② 命令实例

[root@VM_0_12_centos ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 992792 72236 16076 40116 8 3 35 26 0 1 1 1 98 1 0

字段说明:

Procs(进程)

  • r: 运行队列中进程数量,这个值也可以判断是否需要增加CPU。如果数量长期大于1那么说明CPU处理不过来,需要增加CPU。数量越大,系统越繁忙。
  • b: 等待IO的进程数量。数值越大,系统越繁忙。

Memory(内存)

  • swpd: 使用虚拟内存大小,如果swpd的值不为0,但是SI,SO的值长期为0,这种情况不会影响系统性能。单位KB
  • free: 空闲物理内存大小。单位KB
  • buff: 用作缓冲的内存大小。单位KB
  • cache: 用作缓存的内存大小,如果cache的值大的时候,说明cache处的文件数多,如果频繁访问到的文件都能被cache处,那么磁盘的读IO bi会非常小。单位KB

Swap交换分区

  • si: 每秒从交换区写到内存的大小,由磁盘调入内存。单位KB
  • so: 每秒写入交换区的内存大小,由内存调入磁盘。单位KB。这两个数值越大,标明数据需要经常在磁盘和内存之间交换,系统性能越差。

注意:内存够用的时候,这2个值都是0。如果这2个值长期大于0时,系统性能会受到影响,磁盘IO和CPU资源都会被消耗。有些朋友看到空闲内存(free)很少的或接近于0时,就认为内存不够用了,不能光看这一点,还要结合si和so。如果free很少,但是si和so也很少(大多时候是0),那么不用担心,系统性能这时不会受到影响的。

IO(现在的Linux版本块的大小为1kb)

  • bi: 每秒从块设备读入数据的总量,单位是块
  • bo: 每秒写到块设备的数据总量,单位是块。这两个数越大, 标明系统的I/O越繁忙。
    注意:随机磁盘读写的时候,这2个值越大(如超出1024k),能看到CPU在IO等待的值也会越大。

system(系统)

  • in: 每秒中断数,包括时钟中断。
  • cs: 每秒上下文切换数。
    注意:上面2个值越大,会看到由内核消耗的CPU时间会越大。

CPU(以百分比表示)

  • us: 用户进程执行时间百分比(user time)
    us的值比较高时,说明用户进程消耗的CPU时间多,但是如果长期超50%的使用,那么我们就该考虑优化程序算法或者进行加速。
  • sy: 内核系统进程执行时间百分比(system time)
    sy的值高时,说明系统内核消耗的CPU资源多,这并不是良性表现,我们应该检查原因。
  • id: 空闲时间百分比
  • wa: IO等待时间百分比
    wa的值高时,说明IO等待比较严重,这可能由于磁盘大量作随机访问造成,也有可能磁盘出现瓶颈(块操作)。
  • st:被虚拟机所盗用的CPU占比。

③ 更多实例

vmstat -a

显示活动内页

[root@VM_0_12_centos ~]# vmstat -a
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free inact active si so bi bo in cs us sy id wa st
0 0 994060 72312 413408 413360 8 3 35 26 0 1 1 1 98 1 0

vmstat -f

显示启动后创建的进程总数

[root@VM_0_12_centos ~]# vmstat -f
109423131 forks

vmstat -m

显示slab信息。slab是Linux操作系统的一种内存分配机制,slab分配算法采用cache 存储内核对象。slab 缓存、从缓存中分配和释放对象然后销毁缓存的过程必须要定义一个 kmem_cache 对象,然后对其进行初始化这个特定的缓存包含 32 字节的对象

[root@VM_0_12_centos ~]# vmstat -m
Cache Num Total Size Pages
ext3_inode_cache 37536 41720 800 5
ext3_xattr 1 44 88 44
journal_handle 37 144 24 144
journal_head 68 68 112 34
revoke_table 2 202 16 202
revoke_record 0 0 32 112
scsi_sense_cache 3 30 128 30
scsi_cmd_cache 15 15 256 15
dm_raid1_read_record 0 0 1064 7
kcopyd_job 0 0 3240 2
io 0 0 64 59
dm_uevent 0 0 2608 3
dm_rq_clone_bio_info 0 0 16 202
dm_rq_target_io 0 0 424 9
dm_target_io 0 0 24 144
dm_io 0 0 56 67
flow_cache 0 0 104 37
uhci_urb_priv 0 0 56 67
cfq_io_context 290 392 136 28
cfq_queue 291 384 240 16
bsg_cmd 0 0 312 12
mqueue_inode_cache 1 4 896 4
isofs_inode_cache 0 0 640 6
hugetlbfs_inode_cache 1 6 608 6
dquot 0 0 256 15
kioctx 12 20 384 10
kiocb 0 0 256 15
inotify_event_private_data 16397 16464 32 112
inotify_inode_mark_entry 6904 6912 120 32
dnotify_mark_entry 0 0 120 32
dnotify_struct 0 0 32 112
dio 0 0 640 6
fasync_cache 0 0 24 144
khugepaged_mm_slot 17 92 40 92
ksm_mm_slot 0 0 48 77
ksm_stable_node 0 0 64 59
ksm_rmap_item 0 0 64 59
utrace_engine 0 0 56 67
utrace 0 0 64 59
Cache Num Total Size Pages
pid_namespace 0 0 2168 3
posix_timers_cache 0 0 176 22
uid_cache 4 30 128 30
UNIX 45 52 896 4
.....

vmstat -s

以表格方式显示事件计数器和内存状态.

[root@VM_0_12_centos ~]# vmstat -s
1019992 total memory
949200 used memory
413880 active memory
414056 inactive memory
70792 free memory
16732 buffer memory
42124 swap cache
1048572 total swap
994016 used swap
54556 free swap
32948812 non-nice user cpu ticks
17363 nice user cpu ticks
24139157 system cpu ticks
4399088356 idle cpu ticks
45849102 IO-wait cpu ticks
209973 IRQ cpu ticks
273482 softirq cpu ticks
0 stolen cpu ticks
1554689792 pages paged in
1178456036 pages paged out
85334156 pages swapped in
29635971 pages swapped out
708801513 interrupts
4197004543 CPU context switches
1577362196 boot time
109423567 forks

vmstat -d

报告磁盘状态

[root@VM_0_12_centos ~]# vmstat -d
disk- ------------reads------------ ------------writes----------- -----IO------
total merged sectors ms total merged sectors ms cur sec
ram0 0 0 0 0 0 0 0 0 0 0
ram1 0 0 0 0 0 0 0 0 0 0
ram2 0 0 0 0 0 0 0 0 0 0
ram3 0 0 0 0 0 0 0 0 0 0
ram4 0 0 0 0 0 0 0 0 0 0
ram5 0 0 0 0 0 0 0 0 0 0
ram6 0 0 0 0 0 0 0 0 0 0
ram7 0 0 0 0 0 0 0 0 0 0
ram8 0 0 0 0 0 0 0 0 0 0
ram9 0 0 0 0 0 0 0 0 0 0
ram10 0 0 0 0 0 0 0 0 0 0
ram11 0 0 0 0 0 0 0 0 0 0
ram12 0 0 0 0 0 0 0 0 0 0
ram13 0 0 0 0 0 0 0 0 0 0
ram14 0 0 0 0 0 0 0 0 0 0
ram15 0 0 0 0 0 0 0 0 0 0
loop0 0 0 0 0 0 0 0 0 0 0
loop1 0 0 0 0 0 0 0 0 0 0
loop2 0 0 0 0 0 0 0 0 0 0
loop3 0 0 0 0 0 0 0 0 0 0
loop4 0 0 0 0 0 0 0 0 0 0
loop5 0 0 0 0 0 0 0 0 0 0
loop6 0 0 0 0 0 0 0 0 0 0
loop7 0 0 0 0 0 0 0 0 0 0
sr0 113 53 1228 36 0 0 0 0 0 0
vda 77834996 69360228 3109375284 120075066 137777864 157608361 2356914496 588130015 0 159991

vmstat -p [分区]

显示指定的硬盘分区状态。

[root@VM_0_12_centos ~]# lsblk -l
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 37.7M 0 rom
vda 252:0 0 50G 0 disk
vda1 252:1 0 50G 0 part /
[root@VM_0_12_centos ~]# vmstat -p vda1
vda1 reads read sectors writes requested writes
77834856 3109380676 136245914 2356923216

【2】dmesg显示开机时内核检测信息

dmesg命令被用于检查和控制内核的环形缓冲区。kernel会将开机信息存储在ring buffer中。您若是开机时来不及查看信息,可利用dmesg来查看。开机信息保存在​​/var/log/dmesg​​文件里。

① 基本介绍

语法

dmesg (选项)

选项

-c:显示信息后,清除ring buffer中的内容;
-s<缓冲区大小>:预设置为8196,刚好等于ring buffer的大小;
-n:设置记录信息的层级。

dmesg命令通常与其他命令结合使用,如more 、less、head、grep等。

② 生产案例

Java项目部署在了Docker容器中,docker容器使用K8S进行管理。有时会出现容器正常但是Java进程掉了的情况,这时看Java日志是没有异常信息的。dmesg 就派上用场了。

使用​​dmesg | grep '(java)'​​命令,发现不出所料,内存溢出了。

[root@VM_0_12_centos ~]# dmesg  | grep '(java)'
Out of memory: Kill process 21429 (java) score 118 or sacrifice child
Killed process 21429, UID 0, (java) total-vm:2366856kB, anon-rss:147080kB, file-rss:220kB
Out of memory: Kill process 10065 (java) score 168 or sacrifice child
Killed process 10065, UID 0, (java) total-vm:2415120kB, anon-rss:402748kB, file-rss:1812kB
Out of memory: Kill process 30240 (java) score 108 or sacrifice child
Killed process 30240, UID 0, (java) total-vm:2342068kB, anon-rss:118224kB, file-rss:500kB
Out of memory: Kill process 16335 (java) score 105 or sacrifice child
Killed process 16335, UID 0, (java) total-vm:2353812kB, anon-rss:278076kB, file-rss:1024kB
Out of memory: Kill process 3689 (java) score 177 or sacrifice child
Killed process 3689, UID 0, (java) total-vm:2460012kB, anon-rss:380620kB, file-rss:484kB
Out of memory: Kill process 16839 (java) score 173 or sacrifice child
Killed process 16839, UID 0, (java) total-vm:2386456kB, anon-rss:276544kB, file-rss:816kB
Out of memory: Kill process 14923 (java) score 142 or sacrifice child
Killed process 14923, UID 0, (java) total-vm:2456300kB, anon-rss:356304kB, file-rss:136kB
Out of memory: Kill process 16509 (java) score 161 or sacrifice child
Killed process 16509, UID 0, (java) total-vm:2379312kB, anon-rss:136800kB, file-rss:1336kB
...

dmesg t | grep java查看详细

[root@VM_0_12_centos ~]#  dmesg t | grep java
java invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
java cpuset=/ mems_allowed=0
Pid: 10072, comm: java Not tainted 2.6.32-642.6.2.el6.x86_64 #1
[23672] 0 23672 587737 25330 0 0 0 java
[15476] 0 15476 579978 14722 0 0 0 java
[21017] 0 21017 579187 27993 0 0 0 java
[21429] 0 21429 591714 36825 0 0 0 java
[18986] 0 18986 583675 34886 0 0 0 java
[30240] 0 30240 585517 31557 0 0 0 java
[10065] 0 10065 561715 4214 0 0 0 java
Out of memory: Kill process 21429 (java) score 118 or sacrifice child
Killed process 21429, UID 0, (java) total-vm:2366856kB, anon-rss:147080kB, file-rss:220kB
[23672] 0 23672 587737 21760 0 0 0 java
[15476] 0 15476 579978 13788 0 0 0 java
[21017] 0 21017 579187 20117 0 0 0 java
[18986] 0 18986 583675 22429 0 0 0 java
[30240] 0 30240 585517 23555 0 0 0 java
[10065] 0 10065 603780 101140 0 0 0 java
Out of memory: Kill process 10065 (java) score 168 or sacrifice child
Killed process 10065, UID 0, (java) total-vm:2415120kB, anon-rss:402748kB, file-rss:1812kB
java invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
java cpuset=/ mems_allowed=0
Pid: 16017, comm: java Not tainted 2.6.32-642.6.2.el6.x86_64 #1
[23672] 0 23672 587737 15046 0 0 0 java
[15476] 0 15476 579978 12575 0 0 0 java
[18986] 0 18986 583675 16124 0 0 0 java
[30240] 0 30240 585517 22526 0 0 0 java
[ 1964] 0 1964 581452 38605 0 0 0 java
[ 3689] 0 3689 580912 41385 0 0 0 java
[15896] 0 15896 585686 57140 0 0 0 java
[23672] 0 23672 587737 17561 0 0 0 java
[15476] 0 15476 579978 13556 0 0 0 java
[18986] 0 18986 583675 19468 0 0 0 java
[30240] 0 30240 585517 29681 0 0 0 java
[ 1964] 0 1964 582480 25260 0 0 0 java
[ 3689] 0 3689 596364 38950 0 0 0 java
[16368] 0 16368 581032 22236 0 0 0 java
Out of memory: Kill process 30240 (java) score 108 or sacrifice child
Killed process 30240, UID 0, (java) total-vm:2342068kB, anon-rss:118224kB, file-rss:500kB
java invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
java cpuset=/ mems_allowed=0
.....

【3】free命令查看内存使用状态

free命令可以显示当前系统未使用的和已使用的内存数目,还可以显示被内核使用的内存缓冲区。

语法

free(选项)

选项

  • -b:以Byte为单位显示内存使用情况;
  • -k:以KB为单位显示内存使用情况;
  • -m:以MB为单位显示内存使用情况;
  • -o:不显示缓冲区调节列;
  • -s<间隔秒数>:持续观察内存使用状况;
  • -t:显示内存总和列;
  • -V:显示版本信息。

实例

[root@VM_0_12_centos ~]# free
total used free shared buffers cached
Mem: 1019992 949668 70324 20 16820 46540
-/+ buffers/cache: 886308 133684
Swap: 1048572 993340 55232

第一部分Mem行解释(默认单位是KB):

total:内存总数;
used:已经使用的内存数;
free:空闲的内存数;
shared:多个进程共享的内存总数;
buffers :缓冲内存数;
cached :缓存内存数。

关系:total = used + free

第二部分(-/+ buffers/cache)解释:

(-buffers/cache) used内存数:第一部分Mem行中的 used – buffers – cached
(+buffers/cache) free内存数: 第一部分Mem行中的 free + buffers + cached

可见​​-buffers/cache​​​反映的是被程序实实在在吃掉的内存,而​​+buffers/cache​​反映的是可以挪用的内存总数

第三行:total是swap的总数;used是已经使用的swap数,free是空闲的swap数。默认单位KB


【4】查看CPU信息

CPU的主要信息保存在/proc/cpuinfo这个文件当中,我们只要查看这个文件,就可以知道cpu的相关信息。命令如下:

[root@VM_0_12_centos ~]# cat /proc/cpuinfo
processor : 0
vendor_id : AuthenticAMD
cpu family : 23
model : 1
model name : AMD EPYC Processor
stepping : 2
cpu MHz : 1996.226
cache size : 512 KB
physical id : 0
siblings : 1
core id : 0
cpu cores : 1
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm up rep_good extd_apicid unfair_spinlock pni pclmulqdq ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw arat xsaveopt fsgsbase bmi1 avx2 smep bmi2 rdseed adx
bogomips : 3992.45
TLB size : 1024 4K pages
clflush size : 64
cache_alignment : 64
address sizes : 48 bits physical, 48 bits virtual
power management:

【5】查看本机登陆用户信息

如果我们想要知道Linux服务器上目前已经登录的用户信息,可以使用w或who命令来进行查询。先看看w命令,命令格式如下

[root@VM_0_12_centos ~]# w
17:30:07 up 522 days, 21:20, 1 user, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 202.106.86.137 14:15 0.00s 0.05s 0.00s w

第一行其实和top命令的第一行非常类似,主要显示了系统当前时间,开机多久(up),有多少用户登陆(users),1分钟、5分钟、15分钟前的平均负载(load average)。

第二行是项目的说明,第三行开始每行代表一个用户。这些项目是:

  • USER:登陆的用户名;
  • TTY:登陆终端;
  • FROM:从哪个IP地址登陆;
  • LOGIN@:登陆时间;
  • IDLE:用户闲置时间;
  • JCPU:指的是和该终端连接的所有进程占用的CPU运算时间。这个时间里并不包括过去的后台作业时间,但却包括当前正在运行的后台作业所占用的时间;
  • PCPU:是指当前进程所占用的CPU运算时间;
  • WHAT:当前正在运行的命令