重点声明:以下工具和参数介绍,部分内容来源于网络,特此说明

一、运维必知工具

1.1 系统监控工具

1.1.1 top

1、介绍

显示系统上正在运行的进程,它是运维工作中必备命令之一,常用于监测系统负载、进程状态、内存和cpu实时使用情况

2、用法
linux系统命令行执行top


3、选项和参数

**a. 参数说明**
第一行:当前时间、系统已运行的时间、当前登录用户的数量,对应的5、10和15分钟内平均负载(小写l可切换)
*与uptime命令输出一致第二行:任务和进程。进程可以处于不同的状态。显示全部进程的数量。有正在运行、睡眠、停止、僵尸进程的数量(小写t可切换)第三行:CPU状态。 显示不同模式下的所占CPU时间的百分比。这些不同的CPU时间表示:
(小写t可切换)
us:user: 运行(未调整优先级的) 用户进程的CPU时间
sy:system: 运行内核进程的CPU时间
ni:niced:运行已调整优先级的用户进程的CPU时间
wa:IO wait: 用于等待IO完成的CPU时间
hi:处理硬件中断的CPU时间
si:处理软件中断的CPU时间
st:这个虚拟机被hypervisor偷去的CPU时间(译注:如果当前处于一个hypervisor下的vm,实际上hypervisor也是要消耗一部分CPU处理时间的)第四行:物理内存使用情况(free命令显示一致)第五行:虚拟内存使用情况(交换空间)第六行:
PID(进程ID,进程唯一标识符)
USER(进程所有者的实际用户名)
PR(进程的调度优先级。这个字段的一些值是'rt'。这意味这这些进程运行在实时态)
NI(进程的nice值(优先级)。越小的值意味着越高的优先级)
VIRT(进程使用的虚拟内存)
RES(驻留内存大小。驻留内存是任务使用的非交换物理内存大小)
SHR(进程使用的共享内存)
S(进程的状态,包括D-不可中断睡眠态,R-运行态,S-睡眠态,T-被跟踪或已停止,Z-僵尸态)
%CPU(自从上一次更新时到现在任务所使用的CPU时间百分比)
%MEM(进程使用的可用物理内存百分比)
TIME+(任务启动后到现在所使用的全部CPU时间,精确到百分之一秒)
COMMAND(运行进程所使用的命令)**b. 交互命令**
1)'h'或者'?':显示交互命令菜单
2)空格或回车:手动刷新,top命令默认在一个特定间隔(3秒)
3)A: 切换交替显示模式,显示4个窗口,a或w选择窗口,g可以切换
4)B:触发粗体显示
5)c:显示进程启动时的完整路径和程序名
6)i:显示空闲任务
7)k:输入要kill的进程号
7)R:反向排序
8)V:切换树视图
9)Z:改变配色,8中颜色可选,1-8选中,返回后使用z进行整体切换
10)x或y:切换高亮信息:'x'将排序字段高亮显示(纵列);'y'将运行进程高亮显示(横行)。依赖你的显示设置,让输出彩色来看到这些高亮。
11)u:输入特定用户**c. 命令行选项**
1)-b: 批处理模式
2)-c: 命令/程序名 触发:
3)-d: 设置延迟间隔
4)-i: 切换显示空闲进程
5)-n: 设置迭代数量,如:top -n 1 只显示一次top内容
6)-p: 监控特定的PID
7)-u 或 -U: 用户名 或者 UID

特别说明:详细使用可参考 https://linux.cn/article-2352-1.html*

1.1.2 free

参数

Mem:内存使用情况
Swap:交换分区使用情况
total:总内存大小
used:已使用内存的大小
free:未使用的内存大小
shared:共享中的;
buff/cache:缓存和缓冲区的内存大小(不理解缓冲缓存的可以详细查资料了解)
available:不仅包含未使用的内存,还包含了可回收的缓存缓冲,所以显示的比未使用的内存大
公式:
total=used+free+cache/buff
avaliable包含free和buff/cache剩余部分

1.1.3 df

1.1.4 vmstat

vmstat命令是最常见的Linux/Unix监控工具,属于sysstat包。可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。这个命令是我查看Linux/Unix最喜爱的命令,一个是Linux/Unix都支持,二是相比top,我可以看到整个机器的CPU,内存,IO的使用情况,而不是单单看到各个进程的CPU使用率和内存使用率(使用场景不一样)。

安装

yum install -y sysstat

一般vmstat工具的使用是通过两个数字参数来完成的,第一个参数是采样的时间间隔数,单位是秒,第二个参数是采样的次数,如:

实际上,在应用过程中,我们会在一段时间内一直监控,不想监控直接结束vmstat就行了,例如:
[root@xiyu_master ~]# vmstat 2(每2秒执行一次,需要手动中断)

参数解释

参数 类别 介绍
r 进程 表示运行队列(就是说多少个进程真的分配到CPU),我测试的服务器目前CPU比较空闲,没什么程序在跑,当这个值超过了CPU数目,就会出现CPU瓶颈了。这个也和top的负载有关系,一般负载超过了3就比较高,超过了5就高,超过了10就不正常了,服务器的状态很危险。top的负载类似每秒的运行队列。如果运行队列过大,表示你的CPU很繁忙,一般会造成CPU使用率很高。(等待运行的进程数,数值大,一直大于逻辑cpu核数就紧张)
b 进程 表示阻塞的进程,这个不多说,进程阻塞,大家懂的。(数值大的时候,关注数据库和中间件产品)
swpd 内存 虚拟内存已使用的大小,如果大于0,表示你的机器物理内存不足了,如果不是程序内存泄露的原因,那么你该升级内存了或者把耗内存的任务迁移到其他机器。(大于0,关注内存泄漏,结合si和so看,如果si和so为0,也没关系)
free 内存 空闲的物理内存的大小,我的机器内存总共8G,剩余3415M。单位KB/S
buff 内存 Linux/Unix系统是用来存储,目录里面有什么内容,权限等的缓存,我本机大概占用300多M,单位KB/S
cache 内存 cache直接用来记忆我们打开的文件,给文件做缓冲,我本机大概占用300多M(这里是Linux/Unix的聪明之处,把空闲的物理内存的一部分拿来做文件和目录的缓存,是为了提高 程序执行的性能,当程序使用内存时,buffer/cached会很快地被使用。)单位KB/S
si swap 每秒从磁盘读入虚拟内存的大小,如果这个值大于0,表示物理内存不够用或者内存泄露了,要查找耗内存进程解决掉。我的机器内存充裕,一切正常。(大于0,点内存泄漏或者不够用,单位KB/S)
so swap 每秒虚拟内存写入磁盘的大小,如果这个值大于0,同上。(大于0,点内存泄漏或者不够用,单位KB/S)
bi IO 块设备每秒接收的块数量,这里的块设备是指系统上所有的磁盘和其他块设备,默认块大小是1024byte,我本机上没什么IO操作,所以一直是0,但是我曾在处理拷贝大量数据(2-3T)的机器上看过可以达到140000/s,磁盘写入速度差不多140M每秒(读快设备,单位Blocks)
bo IO 块设备每秒发送的块数量,例如我们读取文件,bo就要大于0。bi和bo一般都要接近0,不然就是IO过于频繁,需要调整。(写快设备,单位Blocks)
in system 每秒CPU的中断次数,包括时间中断
cs system 每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。(上下文切换次数,值越大越消耗cpu)
us cpu百分比 用户CPU时间,我曾经在一个做加密解密很频繁的服务器上,可以看到us接近100,r运行队列达到80(机器在做压力测试,性能表现不佳)。
sy cpu百分比 系统CPU时间,如果太高,表示系统调用时间长,例如是IO操作频繁。
id cpu百分比 空闲 CPU时间,一般来说,id + us + sy = 100,一般我认为id是空闲CPU使用率,us是用户CPU使用率,sy是系统CPU使用率。
wt cpu百分比 等待IO CPU时间。

常见问题及解决方法
如果r经常大于4,且id经常少于40,表示cpu的负荷很重。
如果pi,po长期不等于0,表示内存不足。
如果disk经常不等于0,且在b中的队列大于3,表示io性能不好。
1.)如果在processes中运行的序列(process r)是连续的大于在系统中的CPU的个数表示系统现在运行比较慢,有多数的进程等待CPU。
2.)如果r的输出数大于系统中可用CPU个数的4倍的话,则系统面临着CPU短缺的问题,或者是CPU的速率过低,系统中有多数的进程在等待CPU,造成系统中进程运行过慢。
3.)如果空闲时间(cpu id)持续为0并且系统时间(cpu sy)是用户时间的两倍(cpu us)系统则面临着CPU资源的短缺。
当发生以上问题的时候请先调整应用程序对CPU的占用情况.使得应用程序能够更有效的使用CPU.同时可以考虑增加更多的CPU. 关于CPU的使用情况还可以结合mpstat, ps aux top prstat –a等等一些相应的命令来综合考虑关于具体的CPU的使用情况,和那些进程在占用大量的CPU时间.一般情况下,应用程序的问题会比较大一些.比如一些sql语句不合理等等都会造成这样的现象.

内存问题现象:

内存的瓶颈是由scan rate (sr)来决定的.scan rate是通过每秒的始终算法来进行页扫描的.如果scan rate(sr)连续的大于每秒200页则表示可能存在内存缺陷.同样的如果page项中的pi和po这两栏表示每秒页面的调入的页数和每秒调出的页数.如果该值经常为非零值,也有可能存在内存的瓶颈,当然,如果个别的时候不为0的话,属于正常的页面调度这个是虚拟内存的主要原理.

解决办法
1.调节applications & servers使得对内存和cache的使用更加有效.
2.增加系统的内存.
3. Implement priority paging in s in pre solaris 8 versions by adding line “set priority paging=1” in /etc/system. Remove this line if upgrading from Solaris 7 to 8 & retaining old /etc/system file.

关于内存的使用情况还可以结ps aux top prstat –a等等一些相应的命令来综合考虑关于具体的内存的使用情况,和那些进程在占用大量的内存.一般情况下,如果内存的占用率比较高,但是,CPU的占用很低的时候,可以考虑是有很多的应用程序占用了内存没有释放,但是,并没有占用CPU时间,可以考虑应用程序,对于未占用CPU时间和一些后台的程序,释放内存的占用。

r 表示运行队列(就是说多少个进程真的分配到CPU),我测试的服务器目前CPU比较空闲,没什么程序在跑,当这个值超过了CPU数目,就会出现CPU瓶颈了。这个也和top的负载有关系,一般负载超过了3就比较高,超过了5就高,超过了10就不正常了,服务器的状态很危险。top的负载类似每秒的运行队列。如果运行队列过大,表示你的CPU很繁忙,一般会造成CPU使用率很高。

常见性能问题分析
IO/CPU/men连锁反应

1.free急剧下降
2.buff和cache被回收下降,但也无济于事
3.依旧需要使用大量swap交换分区swpd
4.等待进程数,b增多
5.读写IO,bi bo增多
6.si so大于0开始从硬盘中读取
7.cpu等待时间用于 IO等待,wa增加

内存不足

1.开始使用swpd,swpd不为0
2.si so大于0开始从硬盘中读取

io瓶颈

1.读写IO,bi bo增多超过2000
2.cpu等待时间用于 IO等待,wa增加 超过20
3.sy 系统调用时间长,IO操作频繁会导致增加 >30%
4.wa io等待时间长
iowait% <20% 良好
iowait% <35% 一般
iowait% >50%
5.进一步使用iostat观察

CPU瓶颈:load,vmstat中r列
1.反应为CPU队列长度
2.一段时间内,CPU正在处理和等待CPU处理的进程数之和,直接反应了CPU的使用和申请情况。
3.理想的load average:核数CPU数0.7
CPU个数:grep ‘physical id’ /proc/cpuinfo | sort -u
核数:grep ‘core id’ /proc/cpuinfo | sort -u | wc -l
4.超过这个值就说明已经是CPU瓶颈了

CPU瓶颈

1.us 用户CPU时间高超过90%
涉及到web服务器,cs 每秒上下文切换次数
例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。
1.cs可以对apache和nginx线程和进程数限制起到一定的参考作用
2.我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了
较好的趋势:主要是 swap使用少,swpd数值低。si so分页读取写入数值趋近于零

6.其他说明:

b 表示阻塞的进程,这个不多说,进程阻塞,大家懂的。

swpd 虚拟内存已使用的大小,如果大于0,表示你的机器物理内存不足了,如果不是程序内存泄露的原因,那么你该升级内存了或者把耗内存的任务迁移到其他机器。

free 空闲的物理内存的大小,我的机器内存总共8G,剩余3415M。

buff Linux/Unix系统是用来存储,目录里面有什么内容,权限等的缓存,我本机大概占用300多M

cache cache直接用来记忆我们打开的文件,给文件做缓冲,我本机大概占用300多M(这里是Linux/Unix的聪明之处,把空闲的物理内存的一部分拿来做文件和目录的缓存,是为了提高 程序执行的性能,当程序使用内存时,buffer/cached会很快地被使用。)

si 每秒从磁盘读入虚拟内存的大小,如果这个值大于0,表示物理内存不够用或者内存泄露了,要查找耗内存进程解决掉。我的机器内存充裕,一切正常。

so 每秒虚拟内存写入磁盘的大小,如果这个值大于0,同上。

bi 块设备每秒接收的块数量,这里的块设备是指系统上所有的磁盘和其他块设备,默认块大小是1024byte,我本机上没什么IO操作,所以一直是0,但是我曾在处理拷贝大量数据(2-3T)的机器上看过可以达到140000/s,磁盘写入速度差不多140M每秒

bo 块设备每秒发送的块数量,例如我们读取文件,bo就要大于0。bi和bo一般都要接近0,不然就是IO过于频繁,需要调整。

in 每秒CPU的中断次数,包括时间中断

cs 每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。

us 用户CPU时间,我曾经在一个做加密解密很频繁的服务器上,可以看到us接近100,r运行队列达到80(机器在做压力测试,性能表现不佳)。

sy 系统CPU时间,如果太高,表示系统调用时间长,例如是IO操作频繁。

id 空闲 CPU时间,一般来说,id + us + sy = 100,一般我认为id是空闲CPU使用率,us是用户CPU使用率,sy是系统CPU使用率。

wt 等待IO CPU时间。

1.1.5 du

1.1.6 sar

语法格式

sar [ 选项 ] [ <时间间隔> [ <次数> ] ]

sar -h 显示:
[root@xiyu_master ~]# sar -h
-A:所有报告的总和
-b:显示I/O和传递速率的统计信息
-B:显示换页状态
-d:输出每一块磁盘的使用信息
-e:设置显示报告的结束时间
-f:从制定的文件读取报告
-i:设置状态信息刷新的间隔时间
-P:报告每个CPU的状态
-R:显示内存状态
–u:输出cpu使用情况和统计信息
–v:显示索引节点、文件和其他内核表的状态
-w:显示交换分区的状态
-x:显示给定进程的装
-r:报告内存利用率的统计信息

1.查看CPU使用情况 sar -u

sar 1 3 或 sar -u 1 3
%user 用户空间的CPU使用
%nice 改变过优先级的进程的CPU使用率
%system 内核空间的CPU使用率
%iowait CPU等待IO的百分比
%steal 虚拟机的虚拟机CPU使用的CPU
%idle 空闲的CPU
在以上的显示当中,主要看%iowait和%idle,%iowait过高表示存在I/O瓶颈,即磁盘IO无法满足业务需求,如果%idle过低表示CPU使用率比较严重,需要结合内存使用等情况判断CPU是否瓶颈。

2.将统计结果保存到文件 sar -o & sar -f

sar -o test 1 3 #保存
sar -f test #查看

3.查看平均负载 sar -q

sar -q 1 3
runq-sz 运行队列的长度(等待运行的进程数,每核的CP不能超过3个)
plist-sz 进程列表中的进程(processes)和线程数(threads)的数量
ldavg-1 最后1分钟的CPU平均负载,即将多核CPU过去一分钟的负载相加再除以核心数得出的平均值,5分钟和15分钟以此类推
ldavg-5 最后5分钟的CPU平均负载
ldavg-15 最后15分钟的CPU平均负载
blocked

4.查看内存使用情况 sar -r

sar -r 1 3
kbmemfree 空闲的物理内存大小
kbmemused 使用中的物理内存大小
%memused 物理内存使用率
kbbuffers 内核中作为缓冲区使用的物理内存大小,kbbuffers和kbcached:这两个值就是free命令中的buffer和cache.
kbcached 缓存的文件大小
kbcommit 保证当前系统正常运行所需要的最小内存,即为了确保内存不溢出而需要的最少内存(物理内存+Swap分区)
commit 这个值是kbcommit与内存总量(物理内存+swap分区)的一个百分比的值
kbactive
kbinact
kbdirty

5.查看系统swap分区统计情况 sar -W

sar -W 1 3
pswpin/s 每秒从交换分区到系统的交换页面(swap page)数量
pswpott/s 每秒从系统交换到swap的交换页面(swap page)的数量

6.查看IO和传递速率 sar -b

sar -b 1 3
tps 磁盘每秒钟的IO总数,等于iostat中的tps
rtps 每秒钟从磁盘读取的IO总数
wtps 每秒钟从写入到磁盘的IO总数
bread/s 每秒钟从磁盘读取的块总数
bwrtn/s 每秒钟此写入到磁盘的块总数

7.查看磁盘使用情况 sar -d

sar -d
DEV 磁盘设备的名称,如果不加-p,会显示dev253-0类似的设备名称,因此加上-p显示的名称更直接
tps 每秒I/O的传输总数
rd_sec/s 每秒读取的扇区的总数
wr_sec/s 每秒写入的扇区的总数
avgrq-sz 平均每次次磁盘I/O操作的数据大小(扇区)
avgqu-sz 磁盘请求队列的平均长度
await 从请求磁盘操作到系统完成处理,每次请求的平均消耗时间,包括请求队列等待时间,单位是毫秒(1秒等于1000毫秒),等于寻道时间+队列时间+服务时间
svctm I/O的服务处理时间,即不包括请求队列中的时间
%util I/O请求占用的CPU百分比,值越高,说明I/O越慢

  1. 统计网络信息 sar -n

-n { <关键词> [,…] | ALL }
关键词可以是:
DEV 网卡
EDEV 网卡 (错误)
NFS NFS 客户端
NFSD NFS 服务器
SOCK Sockets (套接字) (v4)
IP IP 流 (v4)
EIP IP 流 (v4) (错误)
ICMP ICMP 流 (v4)
EICMP ICMP 流 (v4) (错误)
TCP TCP 流 (v4)
ETCP TCP 流 (v4) (错误)
UDP UDP 流 (v4)
SOCK6 Sockets (套接字) (v6)
IP6 IP 流 (v6)
EIP6 IP 流 (v6) (错误)
ICMP6 ICMP 流 (v6)
EICMP6 ICMP 流 (v6) (错误)
UDP6 UDP 流 (v6)

8.1 网络接口信息 sar -n DEV

sar -n DEV 1 1
IFACE 本地网卡接口的名称
rxpck/s 每秒钟接受的数据包
txpck/s 每秒钟发送的数据库
rxKB/S 每秒钟接受的数据包大小,单位为KB
txKB/S 每秒钟发送的数据包大小,单位为KB
rxcmp/s 每秒钟接受的压缩数据包
txcmp/s 每秒钟发送的压缩包
rxmcst/s 每秒钟接收的多播数据包

8.2 网络设备通信失败信息 sar -n EDVE

sar -n EDEV 1 1
IFACE 网卡名称
rxerr/s 每秒钟接收到的损坏的数据包
txerr/s 每秒钟发送的数据包错误数
coll/s 当发送数据包时候,每秒钟发生的冲撞(collisions)数,这个是在半双工模式下才有
rxdrop/s 当由于缓冲区满的时候,网卡设备接收端每秒钟丢掉的网络包的数目
txdrop/s 当由于缓冲区满的时候,网络设备发送端每秒钟丢掉的网络包的数目
txcarr/s 当发送数据包的时候,每秒钟载波错误发生的次数
rxfram/s 在接收数据包的时候,每秒钟发生的帧对其错误的次数
rxfifo/s 在接收数据包的时候,每秒钟缓冲区溢出的错误发生的次数
txfifo/s 在发生数据包 的时候,每秒钟缓冲区溢出的错误发生的次数

8.3统计socket连接信息 sar -n SOCK

sar -n SOCK 1 1
totsck 当前被使用的socket总数
tcpsck 当前正在被使用的TCP的socket总数
udpsck 当前正在被使用的UDP的socket总数
rawsck 当前正在被使用于RAW的skcket总数
if-frag 当前的IP分片的数目
tcp-tw TCP套接字中处于TIME-WAIT状态的连接数量

8.4 TCP连接的统计 sar -n TCP

sar -n TCP 1 1
active/s 新的主动连接
passive/s 新的被动连接
iseg/s 接受的段
oseg/s 输出的段

使用总结
默认监控: sar 1 1 // CPU和IOWAIT统计状态
(1) sar -b 1 1 // IO传送速率
(2) sar -B 1 1 // 页交换速率
(3) sar -c 1 1 // 进程创建的速率
(4) sar -d 1 1 // 块设备的活跃信息
(5) sar -n DEV 1 1 // 网路设备的状态信息
(6) sar -n SOCK 1 1 // SOCK的使用情况
(7) sar -n ALL 1 1 // 所有的网络状态信息
(8) sar -P ALL 1 1 // 每颗CPU的使用状态信息和IOWAIT统计状态
(9) sar -q 1 1 // 队列的长度(等待运行的进程数)和负载的状态
(10) sar -r 1 1 // 内存和swap空间使用情况
(11) sar -R 1 1 // 内存的统计信息(内存页的分配和释放、系统每秒作为BUFFER使用内存页、每秒被cache到的内存页)
(12) sar -u 1 1 // CPU的使用情况和IOWAIT信息(同默认监控)
(13) sar -v 1 1 // inode, file and other kernel tablesd的状态信息
(14) sar -w 1 1 // 每秒上下文交换的数目
(15) sar -W 1 1 // SWAP交换的统计信息(监控状态同iostat 的si so)
(16) sar -x 2906 1 1 // 显示指定进程(2906)的统计信息,信息包括:进程造成的错误、用户级和系统级用户CPU的占用情况、运行在哪颗CPU上
(17) sar -y 1 1 // TTY设备的活动状态
(18) 将输出到文件(-o)和读取记录信息(-f)

1.2 文本处理

1.2.1 grep

1、介绍
grep(global regular expression print,全局正则表达式输出)是每个Linux发行版都预装的一个强有力的文件模式搜索工具,用于查找文件里符合条件的字符串,当命令匹配到执行命令时指定的模式时,grep会将包含模式的一行输出,但是并不对原文件内容进行修改。

2、用法
grep [options] ‘关键字’ filename

3、选项和参数
a.选项说明

1)–version or -V:查看版本
2)-A 数字N:找到所有的匹配行,并显示匹配行后N行
3)-B数字N:找到所有的匹配行,并显示匹配行前面N行
4)-C数字N:找到所有的匹配行,并显示匹配行前后N行
4)-b:显示匹配到的字符在文件中的偏移地址
5)-c:显示有多少行被匹配到
6)–color:把匹配到的字符用颜色显示出来
7)-e:可以使用多个正则表达式
8)-f FILEA FILEB:FILEA在FILEAB中的匹配
9)-i:不区分大小写针对单个字符
10)-m数字N:最多匹配N个后停止
11)-n:打印行号
12)-o:只打印出匹配到的字符
13)-R :搜索子目录(在当前目录和子目录查找字符)
14)-v:显示不包括查找字符的所有行

1.2.2 sed

1、介绍
sed是一种流编辑器,它是文本处理中非常好的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在 临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理 下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件,可以将数据行进行替换、删除、新增、选取等特定工作,简化对文件的反复操作,编写转换程序等

2、用法

sed的命令格式:sed [options] ‘command’ file(s);
sed的脚本格式:sed [options] -f scriptfile file(s);

3、选项和参数
3.1选项介绍

-e :直接在命令行模式上进行sed动作编辑,此为默认选项;
-f :将sed的动作写在一个文件内,用–f filename 执行filename内的sed动作;
-i :直接修改文件内容;
-n :只打印模式匹配的行;
-r :支持扩展表达式;
-h或–help:显示帮助;
-V或–version:显示版本信息

3.2参数详情
3.2.1、常用参数

a\ 在当前行下面插入文本;
i\ 在当前行上面插入文本;
c\ 把选定的行改为新的文本;
d 删除,删除选择的行; 例如:#sed ‘/^KaTeX parse error: Expected 'EOF', got '#' at position 18: …' file 删除空白行, #̲sed '2d' file 删…d’ file 删除最后一行
D 删除模板块的第一行;
s 替换指定字符;
h 拷贝模板块的内容到内存中的缓冲区;
H 追加模板块的内容到内存中的缓冲区;
g 获得内存缓冲区的内容,并替代当前模板块中的文本;
G 获得内存缓冲区的内容,并追加到当前模板块文本的后面;
l 列表不能打印字符的清单;
n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令;
N 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码;
p 打印模板块的行。 P(大写) 打印模板块的第一行;
q 退出Sed;
b lable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾;
r file 从file中读行;
t label if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾;
T label 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾;
w file 写并追加模板块到file末尾;
W file 写并追加模板块的第一行到file末尾;
! 表示后面的命令对所有没有被选定的行发生作用;
= 打印当前行号;
# 把注释扩展到下一个换行符以前;

**3.2.2、sed替换标记**g 表示行内全面替换;  sed 's/test/test1/g' file,将全部test替换成test1p 表示打印行;w 表示把行写入一个文件;x 表示互换模板块中的文本和缓冲区中的文本;y 表示把一个字符翻译为另外的字符(但是不用于正则表达式);\1 子串匹配标记;& 已匹配字符串标记;**3.2.3、元字符集**
^ 匹配行开始,如:/^sed/匹配所有以sed开头的行;
$ 匹配行结束,如:/sed$/匹配所有以sed结尾的行;
. 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d;
* 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行;
[] 匹配一个指定范围内的字符,如/[ss]ed/匹配sed和Sed;
[^] 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行;
\(..\) 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers;
& 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**;
\< 匹配单词的开始,如:/\
\> 匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行;
x\{m\} 重复字符x,m次,如:/0\{5\}/匹配包含5个0的行;
x\{m,\} 重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行;
x\{m,n\} 重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行;

特别说明:详细使用可参考 https://www.linuxprobe.com/linux-sed-command.html

1.2.3 awk

1.2.4 sort

1、介绍
Linux sort 命令用于将文本文件内容加以排序,sort 可针对文本文件的内容,以行为单位来排序。

2、用法
sort读取每一行输入,并按照指定的分隔符将每一行划分成多个字段,这些字段就是sort排序的对象。同时,sort可以指定按照何种排序规则进行排序,如按照当前字符集排序规则(这是默认排序规则)、按照字典排序规则、按照数值排序规则、按照月份排序规则、按照文件大小格式(k<M<G)。还可以去除重复行,指定降序或升序(默认)的排序方式。

默认的排序规则为字符集排序规则,通常几种常见字符的顺序为:“空字符串<空白字符<数值<a<A<b<B<…<z<Z”,字典排序规则也如此。

语法格式:

sort [OPTION]… [FILE]…

3、参数
选项说明:

-c:检测给定的文件是否已经已经排序。如未排序,则会输出诊断信息,提示从哪一行开始乱序。
-C:类似于"-c",只不过不输出任何诊断信息。可以通过退出状态码1判断出文件未排序。
-m:对给定的多个已排序文件进行合并。在合并过程中不做任何排序动作。
-b:忽略字段的前导空白字符。空格数量不固定时,该选项几乎是必须要使用的。“-n"选项隐含该选项。
-d:按照字典顺序排序,只支持字母、数值、空白。除了特殊字符,一般情况下基本等同于默认排序规则。
–debug:将显示排序的过程以及每次排序所使用的字段、字符。同时还会在最前几行显示额外的信息。
-f:将所有小写字母当成大写字母。例如,“b"和"B"是相同的。
:在和”-u"选项一起使用时,如果排序字段的比较结果相等,则丢弃小写字母行。
-k:指定要排序的key,key由字段组成。key格式为"POS1[,POS2]”,POS1为key起始位置,POS2为key结束位置。
-n:按数值排序。空字符串"“或”\0"被当作空。该选项除了能识别负号"-“,其他所有非数字字符都不识别。
:当按数值排序时,遇到不识别的字符时将立即结束该key的排序。
-M:按字符串格式的月份排序。会自动转换成大写,并取缩写值。规则:unknown<JAN<FEB<…<NOV<DEC。
-o:将结果输出到指定文件中。
-r:默认是升序排序,使用该选项将得到降序排序的结果。
:注意:”-r"不参与排序动作,只是操作排序完成后的结果。
-s:禁止sort做"最后的排序"。
-t:指定字段分隔符。
:对于特殊符号(如制表符),可使用类似于-t$‘\t’或-t’ctrl+v,tab’(先按ctrl+v,然后按tab键)的方法实现。
-u:只输出重复行的第一行。结合"-f"使用时,重复的小写行被丢弃。

4、案例
此小节为sort的简单用法示例,也是平时最可能用上的示例。如果只是为了使用sort,而不是为了刨根问题,本小节已经足够。

假设当前已有文件system.txt,内容如下:其中空白部分为单个制表符。

[root@linuxidc tmp]# cat system.txt
1 mac 2000 500
2 winxp 4000 300
3 bsd 1000 600
4 linux 1000 200
5 SUSE 4000 300
6 Debian 600 200

(1).不加任何选项时,将对整行从第一个字符开始依次向后直到行尾按照默认的字符集排序规则做升序排序。

[root@linuxidc tmp]# sort system.txt
1 mac 2000 500
2 winxp 4000 300
3 bsd 1000 600
4 linux 1000 200
5 SUSE 4000 300
6 Debian 600 200

由于每行的第一个字符1<2<3<4<5<6,所以结果如上。

(2).以第三列为排序列进行排序。由于要划分字段,所以指定字段分隔符。指定制表符这种无法直接输入的特殊字符的方式是$‘\t’。

[root@linuxidc tmp]# sort -t $‘\t’ -k3 system.txt
4 linux 1000 200
3 bsd 1000 600
1 mac 2000 500
2 winxp 4000 300
5 SUSE 4000 300
6 Debian 600 200
结果中虽然1000<2000<4000的顺序是对了,但600却排在最后面,因为这是按照默认字符集排序规则进行排序的,字符6大于4,所以排最后一行。

(3).对第三列按数值排序规则进行排序。

[root@linuxidc tmp]# sort -t $‘\t’ -k3 -n system.txt
6 Debian 600 200
3 bsd 1000 600
4 linux 1000 200
1 mac 2000 500
2 winxp 4000 300
5 SUSE 4000 300

结果中600已经排在第一行。结果中第2行、第3行的第三列值均为1000,如何决定这两行的顺序?

(4).在对第3列按数值排序规则排序的基础上,使用第四列作为决胜属性,且是以数值排序规则对第四列排序。

[root@linuxidc tmp]# sort -t $‘\t’ -k3 -k4 -n system.txt
6 Debian 600 200
4 linux 1000 200
3 bsd 1000 600
1 mac 2000 500
2 winxp 4000 300
5 SUSE 4000 300
如果想在第3列按数值排序后,以第2列作为决胜列呢?由于第2列为字母而非数值,所以下面的语句是错误的,虽然得到了期望的结果。

[root@linuxidc tmp]# sort -t $‘\t’ -k3 -k2 -n system.txt
6 Debian 600 200
3 bsd 1000 600
4 linux 1000 200
1 mac 2000 500
2 winxp 4000 300
5 SUSE 4000 300

之所以最终得到了正确的结果,是因为默认情况下,在命令行中指定的排序行为结束后,sort还会做最后一次排序,这最后一次排序是对整行按照完全默认规则进行排序的,也就是按字符集、升序排序。由于1000所在的两行中的第一个字符3小于4,所以3排在前面。

之所以说上面的语句是错误的,是因为第2列第一个字符是字母而不是数值,在按数值排序时,字母是不可识别字符,一遇到不可识别字符就会立即结束该字段的排序行为。可以使用"–debug"选项来查看排序的过程和排序时所使用的列。注意,该选项只有CentOS 7上的sort才有。

[root@linuxidc tmp]# sort --debug -t $‘\t’ -k3 -k2 -n system.txt
sort: using ‘en_US.UTF-8’ sorting rules
sort: key 1 is numeric and spans multiple fields
sort: key 2 is numeric and spans multiple fields
6>Debian>600>200

(5).在对第3列按数值排序规则排序的基础上,使用第2列作为决胜属性,且以默认排序规则对此列降序排序。

[root@linuxidc tmp]# sort -t $‘\t’ -k3n -k2r system.txt
6 Debian 600 200
4 linux 1000 200
3 bsd 1000 600
1 mac 2000 500
2 winxp 4000 300
5 SUSE 4000 300

由于既要对第3列按数值升序排序,又要对第2列按默认规则降序排序,因此只能对每个字段单独分配选项。注意,虽然"r"选项是降序结果,但它不影响排序过程,只影响最终排序结果。也就是说,在按照升序排序结束得到最终结果后,再反转第2列顺序,也就是得到了降序的结果。同样也说明,sort在排序的时候,一定且只能按照升序排序,只有排序动作结束了"r"选项才开始工作。

紧跟在字段后的选项(如"-k3n"的"n"和"-k2r"的"r")称为私有选项,使用短横线写在字段外的选项(如"-n"、“-r”)为全局选项。当没有为字段分配私有选项时,该排序字段将继承全局选项。当然,只有像"-n"、“-r"这样的排序性的选项才能继承和分配给字段,”-t"这样的选项则无法分配。

因此,“-n -k3 -k4”、“-n -k3n -k4"和”-k3n -k4n"是等价的,“-r -k3n -k4"和”-k3nr -k4r"是等价的。

实际上,上面的命令写法并不严谨。更标准的写法应该如下:

sort -t $‘\t’ -k3n -k2,2r system.txt
“-k2,2"表示排序对象从第2个字段开始到第2个字段结束,也就是限定了只对第二个字段排序。它的格式为"POS1,POS2”,如果省略POS2,将自动扩展到行尾,即"-k2"等价于"-k2,4",也就是说,对整个第2列到第4列进行排序。

需要注意,由于上面的"-k2"继承了全局默认的排序规则,即按字符排序而非按数值排序,此时它能够等价于"-k2,4",但如果是"-k2n"按照数值排序的话,它不等价于"-k2,4n"或"-k2n,4n"或"-k2n,4"(这3者为等价写法),之所以不等价,是因为按数值排序时只能识别数字和负号"-“,当排序时遇到其他所有字符,都将立即结束此次排序。所以”-k2n"等价于"-k2,2n"或"-k2n,2"或"-k2n,2n"。

这些理论性的知识点,请参照下一小节sort的理论内容。后文也不再解释理论性的内容,只是介绍命令使用方法。

(6).在对第3列按数值排序规则排序的基础上,使用第2列的第2个字符作为决胜属性,且以默认排序规则对此列升序排序。

[root@linuxidc tmp]# sort -t $‘\t’ -k3n -k2.2,2.2 system.txt
6 Debian 600 200
4 linux 1000 200
3 bsd 1000 600
1 mac 2000 500
2 winxp 4000 300
5 SUSE 4000 300

其中"-k2.2,2.2"表示从第2个字段的第2个字符开始,到第2个字段的第2个字符结束,即严格限定为第2个字段第2个字符。如果需要对此字符降序排序,则"-k2.2,2.2r"。

(7).使用"-u"去除重复字段所在的行。例如第3列有两行1000,两行4000,去除字段重复的行时,将只保留排在前面的第一行。

[root@linuxidc tmp]# sort -t $‘\t’ -k3n -u system.txt
6 Debian 600 200
3 bsd 1000 600
1 mac 2000 500
2 winxp 4000 300

由于需要去除重复字段的行,因此使用"-u"时将禁止sort做"最后一次排序"。至于字段重复的行中,如何判断哪一行是排在最前面的行,需要搞懂sort的整个工作机制,请通读本文。

"sort -u"和"sort | uniq"是等价的,但是如果多指定几个选项,它们将不等价。例如,"sort -n -u"只会检查排序字段数值部分的唯一性,但"sort -n | uniq"在sort对行中字段按数值排序后,uniq将检查整个行的唯一性。

(8).将排序结果保存到文件中。即可以使用重定向,也可以使用"-o"选项,但使用重定向不可保存到原文件,因为在sort开始执行前,原文件先被重定向截断。而使用"-o"则没有这样的问题,因为sort在打开文件前先完成数据的读取。但"-o"和"-m"一起使用时,同样不安全。

[root@linuxidc tmp]# sort -t $‘\t’ -k3n -o system1.txt system.txt
(9).使用"-c"或"-C"检测文件是否排过序。如果已排序,则不返回任何信息,退出状态码为0。如果未排序,退出状态码为1,但"-c"会给出诊断信息,并指明从哪一行开始乱序,而"-C"不返回任何信息。

[root@linuxidc tmp]# sort -c -k3n system.txt ;echo $?
sort: system.txt:3: disorder: 3 bsd 1000 600
1

说明system.txt中的第3行开始出现乱序,且退出状态码为1。

[root@linuxidc tmp]# sort -C -k3n system.txt ;echo $?
1

1.3 深入研究sort
咋一看上去,sort的使用方法很简单,不就是"sort -t DELIMITER -k POS1,POS2 file"吗,确实如此,它的man文档也才100来行,连info文档加上一堆废话也才500多行。但事实上,sort命令很难,也可以说很简单,简单是因为不管是复杂功能还是简单功能,用来用去就那么几个选项,难是因为没搞懂它的工作机制和细节时,有些时候的结果会比较出人意料,也不知道为什么会如此。

本小节主要讲理论和工作机制的细节,偶尔给出几个示例,所以遇到疑惑时请自行测试,当然也欢迎在博客下方留言。另外,“–debug”(CentOS7才支持该选项)选项对排疑解惑有极大帮助,所以应该善用该选项。

(1).sort命令默认按照字符集的排序规则进行排序,可以指定"-d"选项按照字典顺序排序,指定"-n"按照数值排序,指定"-M"按照字符格式的月份规则排序,指定"-h"按照文件容量大小规则排序。

字符集排序规则和字典排序规则对能识别的字符来说,顺序一般是一致的,几种常见字符的顺序为:“空字符串<空白字符<数值<a<A<b<B<…<z<Z”。

指定不同的排序规则,不仅改变排序时的依据,还间接影响排序时的行为,因为不同排序规则能够识别的字符类型不同。至于如何影响,见下面的(4)。

(2).sort使用"-t"选项指定的分隔符对每行进行分割,得到多个字段,分隔符不作为字段的内容。默认的分隔符为空白字符和非空白字符之间的空字符,并非网上众多文章所说的空格或制表符(原文:By default, fields are separated by the empty string between a non-blank character and a blank character.)。

例如," foo bar"默认将分隔为两个字段" foo"和" bar",而使用空格作为分隔符时将分隔为三个字段:第一个字段为空,第二个字段和第三个字段为"foo"和"bar"。使用下面三个sort语句可以验证默认的分隔符并非空格。

[root@linuxidc ~]# echo -e " 234 bar\n 123 car" | sort -t ’ ’ -b -k3
234 bar
123 car
[root@linuxidc ~]# echo -e " 234 bar\n 123 car" | sort -b -k2
234 bar
123 car
[root@linuxidc ~]# echo -e " 234 bar\n 123 car" | sort -b -k3

-k3指定的字段超出了范围,所以key为空
123 car
234 bar
(3).使用"-k"选项指定排序的key。不指定排序key时,整行将成为排序key,即对整行进行排序。

key由字段组成,格式为"POS1,[POS2]“,表示每行排序的起始和终止位置。也就是说,key才是排序的对象。
POS的格式为"F[.C][OPTS]”,其中F表示字段的序号,C表示该字段中字符的序号。字段和字符的位置都从1开始计算。如果POS2的字符位置指定为0,则表示POS2字段中的最后一个字符。如果POS1中省略".C",则默认值为1(字段的起始字符),如果POS2中省略".C",默认值为0(字段的终止字符)。使用"-b"选项忽略前导空白字符时,C从第一个非空白字符开始计算。如果F或C超出了有效范围,则该key为空,例如一行只有3个字段,却指定了"-k4",或者第2字段只有3个字符,却指定了"-k2.5"。
如果省略POS2,则key将自动扩展到行尾,即等价于"POS1,line_end"。如果不省略POS2,则该key可能会跨越多个字段。无论那种情况,跨越多个字段时,key中会保留字段间的分隔符。
OPTS指定的是该key的选项,包括但不限于"bfnrhM",它们的作用和全局选项"-b"、“-f”、“-n”、“-r”、“-h”、“-M"相同。默认情况下,如果key中没有指定任何OPTS,则该key会继承全局选项。当key中单独指定了选项时,这些选项是该key的私有排序选项,将覆盖全局选项。除了"b"选项外,其余选项无论是指定在POS1还是POS2中都是等价的,对于"b"选项,指定在POS1则作用于POS1,指定在POS2则作用于POS2。如果继承了全局选项”-b",则作用于POS1和POS2。
字段前数量不固定的前导空白字符,将使得字段混乱,因此强烈建议总是忽略前导空白字符。数值排序时(即"n"选项)隐含"b"选项。
可以使用多个"-k"选项指定多个key,排序时将按照key的顺序进行排序。第一个key通常称为主排序key(primary key)。第二个key将在第一个key排序的基础上排序,同理,第三个key将在第二个key的排序基础上进行排序。
以下是几个例子:例子中出现了选项"n"的,描述暂不严谨,但目前只能如此描述,在稍后的(4)中解释。

“-k 2”: 因为没有指定POS2,所以key扩展到了行尾。因此该key从第2字段第一个字符开始,到行尾结束。

“-k 2,3” :该key从第2字段第一个字符开始到第3字段最后一个字符结束。

“-k 2,2”: 该key仅拥有第2字段。

“-k 2,3n"和”-k 2n,3"和"-k 2n,3n" :这三者等价,因为除了"b"选项,OPTS指定在POS1或POS2的结果是一样的。

“-k 2,3b"和”-k 2b,3"和"-k 2b,3b" :这三者互不等价。

“-k 2n”: 该key从第2字段开始直到行尾,都按数值排序。

“-k 2.2b,3.2n”: 该key从第2字段的第2个非空白字符开始,到第3字段第2字符(可能包含空白字符)结束,且该key按照数值排序。其实此处的b选项是多余的,因为n隐含了b选项。

“-k 5b,5 -k 3,3n”: 定义了两个排序key,主排序key为第5字段不包含空白字符的部分,副key为第三个字段。主key按照默认规则排序,副key按照数值排序。副key在主key排序后的基础上再排序。

“-k 5,5n -k 3b,6b”: 主key为第5字段,按照数值排序,副key从第3字段到第六字段,忽略前导空白字符,但是按照默认规则排序。副key在主key排序后的基础上再排序。

(4).当排序规则选项(例如"n"、“d”、“M”、“h”)发现不识别的符号时,将立即结束当前key的排序。默认排序规则是字符集的排序规则,通常能识别所有字符,所以总会对整个key进行完整的排序。这是"何时跨字段、跨key比较?"的问题。

例如,指定n选项按数值排序时,由于"n"选项只能识别数字和负号"-“,当排序时遇到无法识别字符时,将导致该key的排序立即结束。也就是说,对于"abc 123 456 abc"这样的输入,分隔符为空格,当指定”-k 2,3n"时,虽然排序key包括"123 456",但由于中间的空白字符无法被n识别,使得在排完第2字段"123"时就立即结束该key的排序。

正因如此,使得n选项绝对不会跨字段、跨key进行比较。因此,“-k 2,3n"和”-k 2n"、“-k 2,2n”、“-k 2,4n"的结果是等价的,都只对第2字段按照数值进行排序。但默认的排序规则不会有这样的问题,因为默认排序规则能识别所有字符,也就是说”-k 2,3"、“-k 2”、“-k 2,2”、"-k 2,4"是互不等价的。

同理,“-d"的字典排序规则只能识别字母、数字和空白字符,所以遇到非这3类字符时也将立即结束当前key的排序。”-h"和"-M"也都有字符的识别限制,处理方式也一样。关于"-h"和"-M"选项的说明,见info sort。

需要特意说明的是:n同样不识别空字符串,发现空字符串时也结束排序。这可能会适得按数值排序的结果出人意料。例如:

[root@linuxidc ~]# echo -e “b 100:200 200\na 110 300” | tr ‘:’ ‘\0’|sort -t ’ ’ -k2n
b 100200 200
a 110 300
对于"b 100\0200 200"这样的行,“-k 2n"使得该key为"100\0200”。虽然结果看上去是100200,但却只对100进行排序,也就是说它小于110。这就造成了数值排序的假象,100200竟然比110小。

(5).默认情况下,sort会进行一次"最后的排序"。使用"-s"选项将禁止"最后的排序",“-u"选项隐含”-s"选项。

考虑这样一种情况:两行在所有key的排序结果上都完全相同,应该如何决定这两行的先后顺序?

例如:

[root@linuxidc ~]# echo -e “b 100 200\na 100 300” | sort -t ’ ’ -k2n
a 100 300
b 100 200

第一行为"b 100 200",第二行为"a 100 300"。由于第2字段都是100,所以这两行在该key上的数值排序的结果相同,于是sort采取最后的手段,完全按照默认规则(即按字符集排序规则升序排序)对整行进行一次排序,这次排序称为"最后的排序"(info sort中称为last-resort comparison)。由于最后的排序过程中,第一个字符a<b,所以最终结果将是第二行"a 100 300"在第一行"b 100 200"的前面。

禁止"最后的排序"后,对那些排序key相同的行,将保留被读取时相对顺序。即,先读取的排在前面。

如果上面的例子中,第二字段不采用数值排序,而是默认排序规则排序呢?如下:

[root@linuxidc ~]# echo -e “b 100 200\na 100 300” | sort -t ’ ’ -k2
b 100 200
a 100 300

由于默认的排序规则是按照字符集排序规则进行排序,它能识别所有的字符,所以会对"-k2"整个key进行排序,该key会自动扩展为第2字段和第3字段,由于第三字段的2小于3,所以结果中第一行排在第二行的前面。即使如此,sort还是进行了"最后的排序",只不过"最后的排序"不影响排序结果。

如果未指定任何排序选项,其本身就是完全默认的,因此没必要再做最后的排序,所以将不会进行"最后的排序"。如果指定的是"-r"选项,由于"-r"是对最终结果进行反转排序,因此会影响这次的"最后的排序"的结果。

(6).sort的使用建议。

搞清楚了以上几点,是否感觉sort能实现几乎所有的排序需求呢?只要文件够规则,sort就能控制任何一列或多列的排序方式,并且可以设置出是否跨列、跨字符、跨key排序。

这里有几个sort使用建议,算是最后的补充。

任何时候想对单个字段或单个字符排序时,都建议写出POS2,且POS2=POS1,这样能严格排序key的范围只为那个字段或字符。例如,使用"-k2,2"取代"-k2"。
想对多个字段或字符排序时,建议使用多个"-k"选项指定多个key,并按需求为每个key分配私有选项。之所以要如此,是防止无意中忽视了扩展到行尾或者范围。例如,相对第2列、第3列按数值排序,应该指定"-k2n -k3n",而不应该写成"-k2,3n"。
应该总是使用"-b"选项去掉前导空白字符面,防止字段分割时混乱。“-n"隐含了”-b",所以对数值排序时,可以省略"-b"。
对于大文件,建议写出满足需求的所有排序命令,然后使用"-s"关闭"最后的排序"。因为"最后的排序"对每个整行进行排序,性能非常低。
最后,给出一个测试题:假设一些待排序的日志文件中的内容格式如下:

4.150.156.3 - - [01/Apr/2004:06:31:51 +0000] message 1

211.24.3.231 - - [24/Apr/2004:20:17:39 +0000] message 2

能否理解下面两条等价的命令?

sort -s -t ’ ’ -k 4.9n -k 4.5M -k 4.2n -k 4.14,4.21 file*.log | sort -s -t ‘.’ -k 1,1n -k 2,2n -k 3,3n -k 4,4n
sort -s -t ’ ’ -k 4.9n -k 4.5M -k 4.2n -k 4.14,4.21 file*.log | sort -s -t ‘.’ -n -k1 -k2 -k3 -k4

1.2.5 cut

1.3 IO性能工具

1.3.1 iostat

iostat用于输出CPU和磁盘I/O相关的统计信息,详细的io统计信息分析IO瓶颈

安装

yum install -y sysstat

参数

-x 选项:查看详细信息
-c 选项:查看CPU使用情况
-d 选项:查看磁盘使用情况


重点关注%util(采用周期内用于IO操作的时间比率,即IO队列非空的时间比率,如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。)

1.3.2 iotop

用来监视磁盘I/O使用状况的top类工具

安装:

yum install -y iotop

选项:

-o:只显示有io操作的进程
-b:批量显示,无交互,主要用作记录到文件。
-n NUM:显示NUM次,主要用于非交互式模式。
-d SEC:间隔SEC秒显示一次。
-p PID:监控的进程pid。
-u USER:监控的进程用户。
常用选项:
左右箭头:改变排序方式,
默认是按IO排序。
r:改变排序顺序。
o:只显示有IO输出的进程。
p:进程/线程的显示方式的切换。
a:显示累积使用量。
q:退出。


常用命令:

iotop -oP  //查看目前占用IO的进程

二、查看硬件信息

2.1 物理机型号

dmidecode |less 过滤 Product 可以看到型号(或者 dmidecode -t system |grep Serial) 或者ipmitool fru list

2.2 cpu信息

cat /proc/cpuinfo | grep physical | sort -rn| uniq -c (查看到物理cpu为2颗,每颗20核的逻辑核心)

#cat /proc/cpuinfo |grep cores |sort -rn |uniq (查看单颗cpu物理核数)

cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c (查看cpu的型号和逻辑cpu核数,40个逻辑cpu)

2.3 磁盘阵列

MegaCli64 -LdPdInfo -aall -NoLog | egrep ‘RAID Level’

2.4 ipmitool

2.4.1 安装和启用

#yum install ipmitool -y //yum安装
#service ipmi start //启动服务
#ipmitool -I open shell //直接进入本地BMC sh

2.4.2 常用命令

命令格式

ipmitool -H (BMC的管理IP地址) -I lanplus -U (BMC登录用户名) -P (BMC 登录用户名的密码) 相关命令

电源管理

ipmitool -H 10.120.12.10 -I lanplus -U taobao -P 123456 power status //查看开机状态
ipmitool -H 10.120.12.10 -I lanplus -U taobao -P 123456 power on //开机
ipmitool -H 10.120.12.10 -I lanplus -U taobao -P 123456 power off //关机
ipmitool -H 10.120.12.10 -I lanplus -U taobao -P 123456 power reset //重庆
ipmitool -H 10.120.12.10 -I lanplus -U taobao -P 123456 power on

用户管理

ipmitool -H 10.120.12.10 -I lanplus -U taobao -P 123456 user list [ChannelNo] //查看用户信息
ipmitool -H 10.120.12.10 -I lanplus -U taobao -P 123456 user set name < user id> < username> //增加用户
ipmitool -H 10.120.12.10 -I lanplus -U taobao -P 123456 user set password < user id> < password> //设置密码
ipmitool -H 10.120.12.10 -I lanplus -U taobao -P 123456 user priv < user id> < privilege level> [ChannelNo] //设置用户权限
ipmitool -H 10.120.12.10 -I lanplus -U taobao -P 123456 user enable/disable < user id> //启用/禁用用户

IP网络设置
说明:[ChannelNo] 字段是可选的,ChannoNo为1(Share Nic网络)或者8(BMC独立管理网络);设置网络参数,必须首先设置IP为静态,然后再进行其他设置;

ipmitool -H (BMC的管理IP地址) -I lanplus -U (BMC登录用户名) -P (BMC 登录用户名的密码) lan print [ChannelNo] //查看网络信息
ipmitool -H (BMC的管理IP地址) -I lanplus -U (BMC登录用户名) -P (BMC 登录用户名的密码) lan set < ChannelNo> ipsrc <static/dhcp> //修改IP为静态还是DHCP模式
ipmitool -H (BMC的管理IP地址) -I lanplus -U (BMC登录用户名) -P (BMC 登录用户名的密码) lan set < ChannelNo> ipaddr < IPAddress> //修改IP地址
ipmitool -H (BMC的管理IP地址) -I lanplus -U (BMC登录用户名) -P (BMC 登录用户名的密码) lan set < ChannelNo> netmask < NetMask> //修改子网掩码
ipmitool -H (BMC的管理IP地址) -I lanplus -U (BMC登录用户名) -P (BMC 登录用户名的密码) lan set defgw ipaddr <默认网关> //修改默认网关

SOL功能
说明:<9.6/19.2/38.4/57.6/115.2>其中115.2代表115200,即*1000是表示的波特率。

ipmitool -H (BMC的管理IP地址) -I lanplus -U (BMC登录用户名) -P (BMC 登录用户名的密码) sol set volatile-bit-rate <9.6/19.2/38.4/57.6/115.2> //设置SOL串口波特率
ipmitool -H (BMC的管理IP地址) -I lanplus -U (BMC登录用户名) -P (BMC 登录用户名的密码) sol activate //打开SOL功能
ipmitool -H (BMC的管理IP地址) -I lanplus -U (BMC登录用户名) -P (BMC 登录用户名的密码) sol deactivate //关闭SOL功能

SEL日志查看

ipmitool -H (BMC的管理IP地址) -I lanplus -U (BMC登录用户名) -P (BMC 登录用户名的密码) sel list //查看SEL日志

FRU信息查看

ipmitool -H (BMC的管理IP地址) -I lanplus -U (BMC登录用户名) -P (BMC 登录用户名的密码) fru list //查看FRU信息

如遇报错 Could not open device at /dev/ipmi0 or /dev/ipmi/0 or /dev/ipmidev/0: No such file or directory 需要加载相关模块 #lsmod |grep ^ipmi

#modprobe ipmi_watchdog
#modprobe ipmi_poweroff
#modprobe ipmi_devintf
#modprobe ipmi_si 加载该模块如果没有不影响ipmi的使用(与系统版本有关)
modprobe ipmi_msghandler 加载该模块如果没有不影响ipmi的使用

三、网络分析工具

3.1 netstat工具

1)介绍
Netstat是控制台命令,是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。

2)输出信息描述
执行netstat后输出如下:

[root@sy-suz-srv51 ~]# netstat
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 k8sdev.sui:sun-sr-https k8sdev.suiyi.com.:34880 SYN_RECV
tcp        0      0 k8sdev.suiyi.com.c:2379 10.1.62.21:47910        ESTABLISHED
tcp        0      0 k8sdev.suiyi.com.c:2379 k8sdev.suiyi.com.:37790 ESTABLISHED
tcp        0      0 sy-suz-srv:pcsync-https 10.1.62.162:49200       ESTABLISHED
tcp        0      0 k8sdev.suiyi.com.:52866 k8sdev.sui:sun-sr-https ESTABLISHED
tcp        0      0 k8sdev.suiyi.com.:37728 k8sdev.suiyi.com.c:2379 ESTABLISHED
tcp        0      0 k8sdev.sui:sun-sr-https k8sdev.suiyi.com.:52852 ESTABLISHED
tcp        0      0 k8sdev.sui:sun-sr-https 10.1.62.162:32841       ESTABLISHED
tcp        0      0 sy-suz-srv:pcsync-https sy-suz-srv51:60094      ESTABLISHED
tcp        0      0 localhost:webcache      localhost:40136         ESTABLISHED
tcp        0      0 k8sdev.suiyi.com.:35466 10.1.62.21:sun-sr-https ESTABLISHED
tcp        0      0 k8sdev.suiyi.com.:34358 10.1.62.21:sun-sr-https ESTABLISHED
Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags       Type       State         I-Node   Path
unix  3      [ ]         DGRAM                    18442    /run/systemd/notify
unix  2      [ ]         DGRAM                    18444    /run/systemd/cgroups-agent
unix  2      [ ]         DGRAM                    23822    /var/run/chrony/chronyd.sock
unix  8      [ ]         DGRAM                    18455    /run/systemd/journal/socket
unix  18     [ ]         DGRAM                    18457    /dev/log
unix  2      [ ]         DGRAM                    14151    /var/run/nscd/socket
unix  2      [ ]         DGRAM                    584      /run/systemd/shutdownd
unix  3      [ ]         STREAM     CONNECTED     124439388 /run/dbus/system_bus_socket
unix  3      [ ]         STREAM     CONNECTED     42312    /run/systemd/journal/stdout
unix  3      [ ]         STREAM     CONNECTED     39909
unix  3      [ ]         STREAM     CONNECTED     21675
unix  3      [ ]         STREAM     CONNECTED     47538
unix  3      [ ]         STREAM     CONNECTED     124585242 /var/run/docker/containerd/docker-containerd.sock
unix  3      [ ]         STREAM     CONNECTED     21658
unix  2      [ ]         STREAM     CONNECTED     30160
unix  3      [ ]         STREAM     CONNECTED     33750    /run/systemd/journal/stdout
unix  3      [ ]         STREAM     CONNECTED     124614293 @/containerd-shim/moby/c44e49ee0f86d8a4109afb176701795c64f44655abb1861275bbd3b2a9f76394/shim.sock
unix  3      [ ]         STREAM     CONNECTED     124609611 @/containerd-shim/moby/a736ba153c07f0bbf099ae1a1069530e35bfa28ae93f8f235d6c35a6c5ed9ce7/shim.sock
unix  3      [ ]         STREAM     CONNECTED     124601653 @/containerd-shim/moby/20d3fd59d03455d45b1da2636fca25d0edd79dac1947c17045a797eb8506157c/shim.sock

netstat的输出结果可以分为两个部分

1、Active Internet connections 有源TCP连接,其中"Recv-Q"和"Send-Q"指接收队列和发送队列。这些数字一般都应该是0。如果不是则表示软件包正在队列中堆积。这种情况只能在非常少的情况见到。

2、Active UNIX domain sockets 有源Unix域套接口(和网络套接字一样,但是只能用于本机通信,性能可以提高一倍)。

列名解释:

Proto:显示连接使用的协议。

RefCnt:表示连接到本套接口上的进程号。

Types:显示套接口的类型。

State:显示套接口当前的状态。

Path:表示连接到套接口的其它进程使用的路径名。

3)netstat常见参数
-a (all) 显示所有选项,默认不显示LISTEN相关。
-t (tcp) 仅显示tcp相关选项。
-u (udp) 仅显示udp相关选项。
-n 拒绝显示别名,能显示数字的全部转化成数字。
-l 仅列出有在 Listen (监听) 的服务状态。

-p 显示建立相关链接的程序名
-r 显示路由信息,路由表
-e 显示扩展信息,例如uid等
-s 按各个协议进行统计
-c 每隔一个固定时间,执行该netstat命令。

LISTEN和LISTENING的状态只有用-a或者-l才能看到。

4)netstat网络状态详解
一个正常的TCP连接,都会有三个阶段:1、TCP三次握手;2、数据传送;3、TCP四次挥手

如图:

SYN:(同步序列编号,Synchronize Sequence Numbers)该标志仅在三次握手建立TCP连接时有效。表示一个新的TCP连接请求。

ACK:(确认编号,Acknowledgement Number)是对TCP请求的确认标志,同时提示对端系统已经成功接收所有数据。

FIN:(结束标志,FINish)用来结束一个TCP回话.但对应端口仍处于开放状态,准备接收后续数据。

LISTEN:首先服务端需要打开一个socket进行监听,状态为LISTEN, The socket is listening for incoming connections. 侦听来自远方TCP端口的连接请求 。

SYN_SENT:客户端通过应用程序调用connect进行active open.于是客户端tcp发送一个SYN以请求建立一个连接,之后状态置为SYN_SENT,The socket is actively attempting to establish a connection. 在发送连接请求后等待匹配的连接请求。

SYN_RECV:服务端应发出ACK确认客户端的SYN,同时自己向客户端发送一个SYN, 之后状态置为SYN_RECV ,

A connection request has been received from the network. 在收到和发送一个连接请求后等待对连接请求的确认 。

ESTABLISHED:代表一个打开的连接,双方可以进行或已经在数据交互了, The socket has an established connection. 代表一个打开的连接,数据可以传送给用户。

FIN_WAIT1:主动关闭(active close)端应用程序调用close,于是其TCP发出FIN请求主动关闭连接,之后进入FIN_WAIT1状态。 The socket is closed, and the connection is shutting down. 等待远程TCP的连接中断请求,或先前的连接中断请求的确认。

CLOSE_WAIT:被动关闭(passive close)端TCP接到FIN后,就发出ACK以回应FIN请求(它的接收也作为文件结束符传递给上层应用程序),并进入CLOSE_WAIT, The remote end has shut down, waiting for the socket to close. 等待从本地用户发来的连接中断请求 。

FIN_WAIT2:主动关闭端接到ACK后,就进入了FIN-WAIT-2 , Connection is closed, and the socket is waiting for a shutdown from the remote end. 从远程TCP等待连接中断请求。

LAST_ACK:被动关闭端一段时间后,接收到文件结束符的应用程序将调用CLOSE关闭连接。这导致它的TCP也发送一个 FIN,等待对方的ACK.就进入了LAST-ACK , The remote end has shut down, and the socket is closed. Waiting for acknowledgement. 等待原来发向远程TCP的连接中断请求的确认。

TIME_WAIT:在主动关闭端接收到FIN后,TCP就发送ACK包,并进入TIME-WAIT状态。 The socket is waiting after close to handle packets still in the network.等待足够的时间以确保远程TCP接收到连接中断请求的确认。

CLOSING:比较少见, Both sockets are shut down but we still don’t have all our data sent. 等待远程TCP对连接中断的确认。

CLOSED: 被动关闭端在接受到ACK包后,就进入了closed的状态。连接结束, The socket is not being used. 没有任何连接状态。

TIME_WAIT状态的形成只发生在主动关闭连接的一方。
主动关闭方在接收到被动关闭方的FIN请求后,发送成功给对方一个ACK后,将自己的状态由FIN_WAIT2修改为TIME_WAIT,而必须再等2倍 的MSL(Maximum Segment Lifetime,MSL是一个数据报在internetwork中能存在的时间)时间之后双方才能把状态 都改为CLOSED以关闭连接。目前RHEL里保持TIME_WAIT状态的时间为60秒。

Linux的相关keepalive参数
1、tcp_keepalive_time – INTEGER

How often TCP sends out keepalive messages when keepalive is enabled.(Default: 2hours)

一个连接需要TCP开始发送keepalive探测数据包之前的空闲时间,以秒为单位。

2、tcp_keepalive_probes – INTEGER

How many keepalive probes TCP sends out, until it decides that the connection is broken. (Default value: 9)

发送TCP keepalive探测数据包的最大数量,默认是9.如果发送9个keepalive探测包后对端仍然没有响应,就关掉这个连接。

3、tcp_keepalive_intvl – INTEGER

How frequently the probes are send out. Multiplied by tcp_keepalive_probes it is time to kill not responding connection,
after probes started. Default value: 75sec i.e. connection will be aborted after ~11 minutes of retries.

发送两个TCP keepalive探测数据包的间隔时间,默认是75秒。

5)常用netstat相关命令
1、列出所有端口 #netstat -a
2、列出所有 tcp 端口 #netstat -at
3、列出所有 udp 端口 #netstat -au
4、只显示监听端口 #netstat -l
5、只列出所有监听 tcp 端口 #netstat -lt
6、只列出所有监听 udp 端口 #netstat -lu
7、列出所有监听 UNIX 端口 #netstat -lx
8、显示所有端口的统计信息 #netstat -s
9、显示 TCP 或 UDP 端口的统计信息 #netstat -st 或 -su
10、 输出中显示 PID 和进程名称 #netstat -p
11、netstat 输出中不显示主机,端口和用户名 (host, port or user)
当你不想让主机,端口和用户名显示,使用 netstat -n。将会使用数字代替那些名称。同样可以加速输出,因为不用进行比对查询。

#netstat -an
如果只是不想让这三个名称中的一个被显示,使用以下命令
#netsat -a --numeric-ports
#netsat -a --numeric-hosts
#netsat -a --numeric-users
12、持续输出 netstat 信息 #netstat -c
13、找出程序运行的端口 #netstat -ap | grep ‘:80’
14、查看连接某服务端口最多的的IP地址(前20个)
#netstat -nat | grep “10.1.62.23:443” |awk ‘{print $5}’|awk -F: ‘{print $1}’|sort|uniq -c|sort -nr|head -20
15、TCP各种状态列表
#netstat -nat |awk ‘{print $6}’ 统计数量
#netstat -nat |awk ‘{print $6}’|sort|uniq -c 排序
#netstat -nat |awk ‘{print KaTeX parse error: Expected 'EOF', got '}' at position 2: 6}̲'|sort|uniq -c|…NF]} END {for(a in S) print a, S[a]}’
16、直接统计tcp数量监听的数量
#netstat -ant | wc -l

参考文献:https://www.cnblogs.com/ggjucheng/p/2316661.html
https://www.cnblogs.com/jackhub/p/3782598.html
原文链接:https://blog.csdn.net/dongl890426/article/details/86981901

3.2 tcpdump

1)介绍
tcpdump命令是基于unix系统的命令行的数据报嗅探工具,可以抓取流动在网卡上的数据包。它的原理大概如下:linux抓包是通过注册一种虚拟的底层网络协议来完成对网络报文(准确的是网络设备)消息的处理权。当网卡接收到一个网络报文之后,它会遍历系统中所有已经注册的网络协议,如以太网协议、x25协议处理模块来尝试进行报文的解析处理。当抓包模块把自己伪装成一个网络协议的时候,系统在收到报文的时候就会给这个伪协议一次机会,让它对网卡收到的保温进行一次处理,此时该模块就会趁机对报文进行窥探,也就是啊这个报文完完整整的复制一份,假装是自己接收的报文,汇报给抓包模块。

2)常用参数

host: 主机地址
tcp: 协议
port: 端口

-i: 指定网口
-c: 指定抓包个数
-n: 对地址以数字方式显式,否则为主机名,也就是说-n选项不做主机名解析
-v: 当分析和打印的时候,产生详细的输出
-vv: 产生比-v更详细的输出
-vvv: 产生比-vv更详细的输出
-P: 指定要抓取的包是流入还是流出的包。可以给定的值为"in" out"和"inout”,默认为"inout"
-S : 将tcp的序列号以绝对值形式输出,而不是相对值
-r: 保存输出到文件中 #tcpdump -r /tmp/a.txt

例如:tcpdump host 42.120.75.148 and tcp and port 8000 -vnn -S
例如:tcpdump -i eth0 host 42.120.75.148 and tcp and port 8000 -vnn -S

3)其他详细参数
-A 以ASCII格式打印出所有分组,并将链路层的头最小化。
-c 在收到指定的数量的分组后,tcpdump就会停止。
-C 在将一个原始分组写入文件之前,检查文件当前的大小是否超过了参数file_size 中指定的大小。如果超过了指定大小,则关闭当前文件,然后在打开一个新的文件。参数 file_size 的单位是兆字节(是1,000,000字节,而不是1,048,576字节)。
-d 将匹配信息包的代码以人们能够理解的汇编格式给出。
-dd 将匹配信息包的代码以c语言程序段的格式给出。
-ddd 将匹配信息包的代码以十进制的形式给出。
-D 打印出系统中所有可以用tcpdump截包的网络接口。
-e 在输出行打印出数据链路层的头部信息。
-E 用spi@ipaddr algo:secret解密那些以addr作为地址,并且包含了安全参数索引值spi的IPsec ESP分组。
-f 将外部的Internet地址以数字的形式打印出来。
-F 从指定的文件中读取表达式,忽略命令行中给出的表达式。
-i 指定监听的网络接口。
-l 使标准输出变为缓冲行形式,可以把数据导出到文件。
-L 列出网络接口的已知数据链路。
-m 从文件module中导入SMI MIB模块定义。该参数可以被使用多次,以导入多个MIB模块。
-M 如果tcp报文中存在TCP-MD5选项,则需要用secret作为共享的验证码用于验证TCP-MD5选选项摘要(详情可参考RFC 2385)。
-b 在数据-链路层上选择协议,包括ip、arp、rarp、ipx都是这一层的。
-n 不把网络地址转换成名字。
-nn 不进行端口名称的转换。
-N 不输出主机名中的域名部分。例如,‘nic.ddn.mil‘只输出’nic‘。
-t 在输出的每一行不打印时间戳。
-O 不运行分组分组匹配(packet-matching)代码优化程序。
-P 不将网络接口设置成混杂模式。
-q 快速输出。只输出较少的协议信息。
-r 从指定的文件中读取包(这些包一般通过-w选项产生)。
-S 将tcp的序列号以绝对值形式输出,而不是相对值。
-s 从每个分组中读取最开始的snaplen个字节,而不是默认的68个字节。
-T 将监听到的包直接解释为指定的类型的报文,常见的类型有rpc远程过程调用)和snmp(简单网络管理协议;)。
-t 不在每一行中输出时间戳。
-tt 在每一行中输出非格式化的时间戳。
-ttt 输出本行和前面一行之间的时间差。
-tttt 在每一行中输出由date处理的默认格式的时间戳。
-u 输出未解码的NFS句柄。
-v 输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息。
-vv 输出详细的报文信息。
-w 直接将分组写入文件中,而不是不分析并打印出来。

4)tcpdump的表达式介绍

表达式是一个正则表达式,tcpdump利用它作为过滤报文的条件,如果一个报文满足表达式的条件,则这个报文将会被捕获。如果没有给出任何条件,则网络上所有的信息包将会被截获。
在表达式中一般如下几种类型的关键字:

第一种是关于类型的关键字,主要包括host,net,port,例如 host 210.27.48.2,指明 210.27.48.2是一台主机,net 202.0.0.0指明202.0.0.0是一个网络地址,port 23 指明端口号是23。如果没有指定类型,缺省的类型是host。

第二种是确定传输方向的关键字,主要包括src,dst,dst or src,dst and src,这些关键字指明了传输的方向。举例说明,src 210.27.48.2 ,指明ip包中源地址是 210.27.48.2 , dst net 202.0.0.0 指明目的网络地址是202.0.0.0。如果没有指明方向关键字,则缺省是src or dst关键字。

第三种是协议的关键字,主要包括fddi,ip,arp,rarp,tcp,udp等类型。Fddi指明是在FDDI (分布式光纤数据接口网络)上的特定的网络协议,实际上它是”ether”的别名,fddi和ether 具有类似的源地址和目的地址,所以可以将fddi协议包当作ether的包进行处理和分析。其他的几个关键字就是指明了监听的包的协议内容。如果没有指定任何协议,则tcpdump 将会监听所有协议的信息包。

除了这三种类型的关键字之外,其他重要的关键字如下:gateway, broadcast,less, greater,还有三种逻辑运算,取非运算是 ‘not ' '! ‘,与运算是’and’,’&&';或运算是’or’ ,’||’;这些关键字可以组合起来构成强大的组合条件来满足人们的需要。

3.3 wireshark

命令:tshark
安装包 #yum install -y wireshark
查看当前http服务器访问的ip以及所访问的http链接

#tshark -n -t a -R http.request -T fields -e “frame.time” -e “ip.src” -e “http.host” -e “http.request.method” -e “http.request.uri”

3.4 nmap

Nmap (网络映射器)是Gordon Lyon最初编写的一种安全扫描器,用于发现计算机网络上的主机和服务,从而创建网络的“映射”。为了实现其目标,Nmap将特定数据包发送到目标主机,然后分析响应.NMAP强大的网络工具,用于枚举和测试网络。

1)安装

yum install nmap -y

2)参数

  • vv : 输出详情 如:nmap -vv 223.5.5.5
  • -p : 定义端口范围 如:nmap -p 1-100 223.5.5.5 nmap -p 80,8080,9090 223.5.5.5
  • -sP: sP开关(Arp ping)执行PING命令, 如:nmap -sP 223.5.5.5 nmap -sP 223.5.5.0/28
  • traceroute: 跟踪路由 如:nmap -traceroute 223.5.5.5
  • -O 探测目标IP的系统版本 如:nmap -O 127.0.0.1




3.5 curl 命令

curl(CommandLine Uniform Resource Locator),即在命令行中利用URL进行数据或者文件传输。
curl支持的各种协议(如HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S等

1)curl url(获取该网址的文本信息)

curl www.baidu.com

2)curl -i url(获取该网址的文本信息以及协议头部信息)

curl -i www.baidu.com

3)curl -x proxy url(使用代理获取网页文本信息)

curl -x www.baidu.com

4)curl -X POST --header"Content-Type:application/json" --data ‘{}’ url (使用post模拟json格式请求接口)

curl -X POST --header "Content-Type:application/json"  --data '{}'  127.0.0.1:8088/user/getAllUserInfo

POST 指定请求方式
–header 指定请求头部信息
–data 指定json请求体数据内容

5)curl -I url(仅返回请求头部信息)

curl -I www.baidu.com

四、jvm性能分析

4.1背景

1、OutOfMemoryError内存不足
2、内存泄露
3、线程死锁
4、锁争用(Lock Contention)
5、Java进程消耗CPU过高

以上问题出现时,常通过重启服务器或者调大内存来临时解决,实际情况,还需要尽量还原当时的业务场景,并分析内存、线程等数据,通过分析找到最终的解决方案,这就会涉及到性能分析工具

4.2 常用jvm工具

在进行java程序问题定位时,内存问题定位是很关键的一招。jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole、大名鼎鼎的VisualVM,IBM的Memory Analyzer等等,但是在生产环境出现问题的时候,工具的使用会有所限制。所有的工具几乎都是依赖于jdk的接口和底层的这些命令,研究和掌握这些命令的使用也让我们更能了解jvm构成和特性。JDK本身提供了很丰富的性能监控工具,除了集成式的visualVM和jConsole外,还有jstat,jstack,jps,jmap,jhat小工具,这些都是性能调优的常用工具,

Jconsole : jdk自带,功能简单,但是可以在系统有一定负荷的情况下使用。对垃圾回收算法有很详细的跟踪。
JProfiler:商业软件,功能强大。
VisualVM:JDK自带,功能强大,与JProfiler类似。
MAT:MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具。

4.2.1 VisualVM

VisualVM 是javajdk自带的调优工具,也是平时使用最多调优工具,几乎涉及了jvm调优的方方面面。启动起来后和jconsole 一样同样可以选择本地和远程,如果需要监控远程同样需要配置相关参数。
这个工具放在JDK安装目录的bin目录下,双击jvisualvm.exe即可打开,如下图所示

提供监视页面主要展示系统资源占用情况、展示java程序运行的时候占用的cpu资源、线程页面(主要展示程序中所有的线程运行状态)等

1)堆 :这里要说明下堆内存的组成部分,堆是由老年代和新生代组成,其中新生代有由”伊甸园”和”两个幸存区组成”三部分组成,堆视图看到的资源占用实际是”老年代”、”伊甸园(Eden)”、”两个幸存者(Survivor )”的一个综合情况。
2)PermGen :Perm 区用来存放java类以及其他虚拟机自己的静态数据,(常被称为持久代或者方法区)
3)类 :此视图 主要展示 当前程序加载了多少个类
4)线程: 当前程序的线程启动情况
5)堆Dump : 生产当前程序的内存快照hprof文件,对于分析内存溢出问题比较有帮助。
6)线程dump : 所有线程的快照(对分析线程死锁,比较有帮助)
7)时间线 : 展示每个线程的实时运行状态(不同颜色代表不同的状态)

VisualVM可以根据需要安装不同的插件,每个插件的关注点都不同,有的主要监控GC,有的主要监控内存,有的监控线程等。

4.2.2 Jconsole

JConsole是一个JMX(Java Management Extensions,即Java管理扩展)的JVM监控与管理工具,监控主要体现在:堆栈内存、线程、CPU、类、VM信息这几个方面,而管理主要是对JMX MBean(managed beans,被管理的beans,是一系列资源,包含对象、接口、设备等)的管理,不仅能查看bean的属性和方法信息,还能够在运行时修改属性或调用方法。
打开Jconsole直接在jdk/bin目录下点击jconsole.exe即可启动,界面如下:
1)内存,可以在内存页我们可以看到程序运行期间JVM各个部分的内存状况,右下角是对应各个分区的内存使用柱状图,点击对应柱可查看详情
2)线程,该页面可以查看当前JVM进程启动了多少个线程,并能查看每个线程的状态及堆栈信息,此外还有一个功能就是能够自动检测死锁
3)类,该页面其实和线程页有些相似,不过显示的是JVM加载类的信息
4)VM概述
5)MBean管理

4.2.3 MAT

MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的Java heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。

可以利用visualvm或者是 jmap命令生产堆文件在进行内存分析。

  1. 用jmap生成堆信息

    这样在E盘的jmap文件夹里会有一个map.bin的堆信息文件

  2. 将堆信息导入到mat中分析

  3. 生成分析报告
    可以利用visualvm或者是 jmap命令生产堆文件,导入eclipse mat中生成分析报告:

1)Histogram(直方图)视图

Class Name : 类名称,java类名
Objects : 类的对象的数量,这个对象被创建了多少个
Shallow Heap :一个对象内存的消耗大小,不包含对其他对象的引用
Retained Heap :是shallow Heap的总和,也就是该对象被GC之后所能回收到内存的总和
通过直方图视图可以很容易找到占用内存最多的几个类(通过Retained Heap排序),还可以通过其他方式进行分组(见下图)。

如果存在内存溢出,时间久了溢出类的实例数量或者内存占比会越来越多,排名也越来越靠前。

图标进行对比,通过多次对比不同时间点下的直方图对比就很容易把溢出的类找出来。

2)支配树(Dominator Tree)

MAT提供了一个称为支配树(Dominator Tree)的对象图。支配树体现了对象实例间的支配关系,在此视图中列出了每个对象(Object Instance)与其引用关系的树状结构,同时包含了占用内存的大小和百分比。

通过Dominator Tree视图可以很容易的找出占用内存最多的几个对象(根据Retained Heap或Percentage排序),和Histogram类似,可以通过不同的方式进行分组显示:

Histogram视图和Dominator Tree视图的角度不同,前者是基于类的角度,后者是基于对象实例的角度,并且可以更方便的看出其引用关系。

以上只是一个初步的介绍,mat还有更强大的使用,比如对比堆内存,在生产环境中往往为了定位问题,每隔几分钟dump出一下内存快照,随后在对比不同时间的堆内存的变化来发现问题。

4.3 其他工具

下面对jps jstat jmap jhat jstack jinfo做一一介绍

4.3.1 jps

JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程。

1)命令格式

jps [options] [hostid]

2)option参数

-l : 输出主类全名或jar路径
-q : 只输出LVMID
-m : 输出JVM启动时传递给main()的参数
-v : 输出JVM启动时显示指定的JVM参数

其中[option]、[hostid]参数也可以不写。

3)示例
$ jps -l -m

  28920 org.apache.catalina.startup.Bootstrap start11589 org.apache.catalina.startup.Bootstrap start25816 sun.tools.jps.Jps -l -m

4.3.2 jstat

jstat(JVM statistics Monitoring)是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译(Just In Time Compiler, 即时编译器)等运行数据。

1)命令格式

jstat [option] LVMID [interval] [count]

2)参数

[option] : 操作参数
LVMID : 本地虚拟机进程ID
[interval] : 连续输出的时间间隔
[count] : 连续输出的次数

3 )option 参数总览

|Option | Displays…|
|class|class loader的行为统计。Statistics on the behavior of the class loader.|

class class loader的行为统计。Statistics on the behavior of the class loader.
compiler HotSpt JIT编译器行为统计。Statistics of the behavior of the HotSpot Just-in-Time compiler.
gc 垃圾回收堆的行为统计。Statistics of the behavior of the garbage collected heap.
gccapacity 各个垃圾回收代容量(young,old,perm)和他们相应的空间统计。Statistics of the capacities of the generations and their corresponding spaces.
gcutil 垃圾回收统计概述。Summary of garbage collection statistics.
gccause 垃圾收集统计概述(同-gcutil),附加最近两次垃圾回收事件的原因。Summary of garbage collection statistics (same as -gcutil), with the cause of the last and
gcnew 新生代行为统计。Statistics of the behavior of the new generation.
gcnewcapacity 新生代与其相应的内存空间的统计。Statistics of the sizes of the new generations and its corresponding spaces.
gcold 年老代和永生代行为统计。Statistics of the behavior of the old and permanent generations.
gcoldcapacity 年老代行为统计。Statistics of the sizes of the old generation.
gcpermcapacity 永生代行为统计。Statistics of the sizes of the permanent generation.
printcompilation HotSpot编译方法统计。HotSpot compilation method statistics.
4 option 参数详解
-class
监视类装载、卸载数量、总空间以及耗费的时间

$ jstat -class 11589

 Loaded  Bytes  Unloaded  Bytes     Time   7035  14506.3     0     0.0       3.67

Loaded : 加载class的数量
Bytes : class字节大小
Unloaded : 未加载class的数量
Bytes : 未加载class的字节大小
Time : 加载时间
-compiler
输出JIT编译过的方法数量耗时等

$ jstat -compiler 1262

Compiled Failed Invalid   Time   FailedType FailedMethod2573      1       0    47.60          1 org/apache/catalina/loader/WebappClassLoader findResourceInternal

Compiled : 编译数量
Failed : 编译失败数量
Invalid : 无效数量
Time : 编译耗时
FailedType : 失败类型
FailedMethod : 失败方法的全限定名
-gc
垃圾回收堆的行为统计,常用命令

$ jstat -gc 1262

 S0C    S1C     S0U     S1U   EC       EU        OC         OU        PC       PU         YGC    YGCT    FGC    FGCT     GCT
26112.0 24064.0 6562.5  0.0   564224.0 76274.5   434176.0   388518.3  524288.0 42724.7    320    6.417   1      0.398    6.815

C即Capacity 总容量,U即Used 已使用的容量

S0C : survivor0区的总容量
S1C : survivor1区的总容量
S0U : survivor0区已使用的容量
S1U : survivor1区已使用的容量
EC : Eden区的总容量
EU : Eden区已使用的容量
OC : Old区的总容量
OU : Old区已使用的容量
PC 当前perm的容量 (KB)
PU perm的使用 (KB)
YGC : 新生代垃圾回收次数
YGCT : 新生代垃圾回收时间
FGC : 老年代垃圾回收次数
FGCT : 老年代垃圾回收时间
GCT : 垃圾回收总消耗时间
$ jstat -gc 1262 2000 20

这个命令意思就是每隔2000ms输出1262的gc情况,一共输出20次

-gccapacity
同-gc,不过还会输出Java堆各区域使用到的最大、最小空间

$ jstat -gccapacity 1262

 NGCMN    NGCMX     NGC    S0C   S1C       EC         OGCMN      OGCMX      OGC        OC       PGCMN    PGCMX     PGC      PC         YGC    FGC
614400.0 614400.0 614400.0 26112.0 24064.0 564224.0   434176.0   434176.0   434176.0   434176.0 524288.0 1048576.0 524288.0 524288.0    320     1

NGCMN : 新生代占用的最小空间
NGCMX : 新生代占用的最大空间
OGCMN : 老年代占用的最小空间
OGCMX : 老年代占用的最大空间
OGC:当前年老代的容量 (KB)
OC:当前年老代的空间 (KB)
PGCMN : perm占用的最小空间
PGCMX : perm占用的最大空间
-gcutil
同-gc,不过输出的是已使用空间占总空间的百分比

$ jstat -gcutil 28920

S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
12.45   0.00  33.85   0.00   4.44  4       0.242     0    0.000    0.242

-gccause
垃圾收集统计概述(同-gcutil),附加最近两次垃圾回收事件的原因

$ jstat -gccause 28920

S0     S1     E      O      P       YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC
12.45   0.00  33.85   0.00   4.44      4    0.242     0    0.000    0.242   Allocation Failure   No GC

LGCC:最近垃圾回收的原因
GCC:当前垃圾回收的原因
-gcnew
统计新生代的行为

$ jstat -gcnew 28920

 S0C      S1C      S0U        S1U  TT  MTT  DSS      EC        EU         YGC     YGCT  419392.0 419392.0 52231.8    0.0  6   6    209696.0 3355520.0 1172246.0  4       0.242

TT:Tenuring threshold(提升阈值)
MTT:最大的tenuring threshold
DSS:survivor区域大小 (KB)
-gcnewcapacity
新生代与其相应的内存空间的统计

$ jstat -gcnewcapacity 28920

 NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC        YGC   FGC
4194304.0  4194304.0  4194304.0 419392.0 419392.0 419392.0 419392.0  3355520.0  3355520.0     4     0

NGC:当前年轻代的容量 (KB)
S0CMX:最大的S0空间 (KB)
S0C:当前S0空间 (KB)
ECMX:最大eden空间 (KB)
EC:当前eden空间 (KB)
-gcold
统计旧生代的行为

$ jstat -gcold 28920

  PC       PU        OC           OU       YGC    FGC    FGCT     GCT
1048576.0  46561.7   6291456.0     0.0      4      0      0.000    0.242

-gcoldcapacity
统计旧生代的大小和空间

$ jstat -gcoldcapacity 28920

 OGCMN       OGCMX        OGC         OC         YGC   FGC    FGCT     GCT
6291456.0   6291456.0   6291456.0   6291456.0     4     0    0.000    0.242

-gcpermcapacity
永生代行为统计

$ jstat -gcpermcapacity 28920

  PGCMN      PGCMX       PGC         PC      YGC   FGC    FGCT     GCT
1048576.0  2097152.0  1048576.0  1048576.0     4     0    0.000    0.242

-printcompilation
hotspot编译方法统计

$ jstat -printcompilation 28920

  Compiled  Size  Type Method1291      78     1    java/util/ArrayList indexOf

Compiled:被执行的编译任务的数量
Size:方法字节码的字节数
Type:编译类型
Method:编译方法的类名和方法名。类名使用”/” 代替 “.” 作为空间分隔符. 方法名是给出类的方法名. 格式是一致于HotSpot - XX:+PrintComplation 选项

4.3.3 jmap

jmap(JVM Memory Map)命令用于生成heap dump文件,如果不使用这个命令,还阔以使用-XX:+HeapDumpOnOutOfMemoryError参数来让虚拟机出现OOM的时候·自动生成dump文件。 jmap不仅能生成dump文件,还阔以查询finalize执行队列、Java堆和永久代的详细信息,如当前使用率、当前使用的是哪种收集器等。

命令格式
jmap [option] LVMID

option参数
dump : 生成堆转储快照
finalizerinfo : 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象
heap : 显示Java堆详细信息
histo : 显示堆中对象的统计信息
permstat : to print permanent generation statistics
F : 当-dump没有响应时,强制生成dump快照
示例
-dump
常用格式

-dump::live,format=b,file= pid
dump堆到文件,format指定输出格式,live指明是活着的对象,file指定文件名

$ jmap -dump:live,format=b,file=dump.hprof 28920
Dumping heap to /home/xxx/dump.hprof …
Heap dump file created

dump.hprof这个后缀是为了后续可以直接用MAT(Memory Anlysis Tool)打开。

-finalizerinfo
打印等待回收对象的信息

$ jmap -finalizerinfo 28920

 Attaching to process ID 28920, please wait...Debugger attached successfully.Server compiler detected.JVM version is 24.71-b01Number of objects pending for finalization: 0

可以看到当前F-QUEUE队列中并没有等待Finalizer线程执行finalizer方法的对象。

-heap
打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况,可以用此来判断内存目前的使用情况以及垃圾回收情况

$ jmap -heap 28920

Attaching to process ID 28920, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.71-b01

using thread-local object allocation.
Parallel GC with 4 thread(s)//GC 方式

Heap Configuration: //堆内存初始化配置
MinHeapFreeRatio = 0 //对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)
MaxHeapFreeRatio = 100 //对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)
MaxHeapSize = 2082471936 (1986.0MB) //对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小
NewSize = 1310720 (1.25MB)//对应jvm启动参数-XX:NewSize=设置JVM堆的‘新生代’的默认大小
MaxNewSize = 17592186044415 MB//对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小
OldSize = 5439488 (5.1875MB)//对应jvm启动参数-XX:OldSize=:设置JVM堆的‘老生代’的大小
NewRatio = 2 //对应jvm启动参数-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
SurvivorRatio = 8 //对应jvm启动参数-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值
PermSize = 21757952 (20.75MB) //对应jvm启动参数-XX:PermSize=:设置JVM堆的‘永生代’的初始大小
MaxPermSize = 85983232 (82.0MB)//对应jvm启动参数-XX:MaxPermSize=:设置JVM堆的‘永生代’的最大大小
G1HeapRegionSize = 0 (0.0MB)

Heap Usage://堆内存使用情况

PS Young Generation
Eden Space://Eden区内存分布
capacity = 33030144 (31.5MB)//Eden区总容量
used = 1524040 (1.4534378051757812MB) //Eden区已使用
free = 31506104 (30.04656219482422MB) //Eden区剩余容量
4.614088270399305% used //Eden区使用比率
From Space: //其中一个Survivor区的内存分布
capacity = 5242880 (5.0MB)
used = 0 (0.0MB)
free = 5242880 (5.0MB)
0.0% used
To Space: //另一个Survivor区的内存分布
capacity = 5242880 (5.0MB)
used = 0 (0.0MB)
free = 5242880 (5.0MB)
0.0% used
PS Old Generation //当前的Old区内存分布
capacity = 86507520 (82.5MB)
used = 0 (0.0MB)
free = 86507520 (82.5MB)
0.0% used
PS Perm Generation//当前的 “永生代” 内存分布
capacity = 22020096 (21.0MB)
used = 2496528 (2.3808746337890625MB)
free = 19523568 (18.619125366210938MB)
11.337498256138392% used

670 interned Strings occupying 43720 bytes.

可以很清楚的看到Java堆中各个区域目前的情况。

-histo
打印堆的对象统计,包括对象数、内存大小等等 (因为在dump:live前会进行full gc,如果带上live则只统计活对象,因此不加live的堆大小要大于加live堆的大小 )

$ jmap -histo:live 28920 | more

 num     #instances         #bytes  class name1:         83613       12012248  <constMethodKlass>2:         23868       11450280  [B3:         83613       10716064  <methodKlass>4:         76287       10412128  [C5:          8227        9021176  <constantPoolKlass>6:          8227        5830256  <instanceKlassKlass>7:          7031        5156480  <constantPoolCacheKlass>8:         73627        1767048  java.lang.String9:          2260        1348848  <methodDataKlass>10:          8856         849296  java.lang.Class....

仅仅打印了前10行

xml class name是对象类型,说明如下:

B byte
C char
D double
F float
I int
J long
Z boolean
[ 数组,如[I表示int[]
[L+类名 其他对象

-permstat
打印Java堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。

$ jmap -permstat 28920

 Attaching to process ID 28920, please wait...Debugger attached successfully.Server compiler detected.JVM version is 24.71-b01finding class loader instances ..done.computing per loader stat ..done.please wait.. computing liveness.liveness analysis may be inaccurate ...class_loader            classes bytes   parent_loader           alive?  type  <bootstrap>             3111    18154296          null          live    <internal>0x0000000600905cf8      1       1888    0x0000000600087f08      dead    sun/reflect/DelegatingClassLoader@0x00000007800500a00x00000006008fcb48      1       1888    0x0000000600087f08      dead    sun/reflect/DelegatingClassLoader@0x00000007800500a00x00000006016db798      0       0       0x00000006008d3fc0      dead    java/util/ResourceBundle$RBClassLoader@0x0000000780626ec00x00000006008d6810      1       3056      null          dead    sun/reflect/DelegatingClassLoader@0x00000007800500a0

-F
强制模式。如果指定的pid没有响应,请使用jmap -dump或jmap -histo选项。此模式下,不支持live子选项。

4.3.4 jhat

jhat(JVM Heap Analysis Tool)命令是与jmap搭配使用,用来分析jmap生成的dump,jhat内置了一个微型的HTTP/HTML服务器,生成dump的分析结果后,可以在浏览器中查看。在此要注意,一般不会直接在服务器上进行分析,因为jhat是一个耗时并且耗费硬件资源的过程,一般把服务器生成的dump文件复制到本地或其他机器上进行分析。

1 命令格式
jhat [dumpfile]
1
2 参数
-stack false|true 关闭对象分配调用栈跟踪(tracking object allocation call stack)。 如果分配位置信息在堆转储中不可用. 则必须将此标志设置为 false. 默认值为 true.>
-refs false|true 关闭对象引用跟踪(tracking of references to objects)。 默认值为 true. 默认情况下, 返回的指针是指向其他特定对象的对象,如反向链接或输入引用(referrers or incoming references), 会统计/计算堆中的所有对象。>
-port port-number 设置 jhat HTTP server 的端口号. 默认值 7000.>
-exclude exclude-file 指定对象查询时需要排除的数据成员列表文件(a file that lists data members that should be excluded from the reachable objects query)。 例如, 如果文件列列出了 java.lang.String.value , 那么当从某个特定对象 Object o 计算可达的对象列表时, 引用路径涉及 java.lang.String.value 的都会被排除。>
-baseline exclude-file 指定一个基准堆转储(baseline heap dump)。 在两个 heap dumps 中有相同 object ID 的对象会被标记为不是新的(marked as not being new). 其他对象被标记为新的(new). 在比较两个不同的堆转储时很有用.>
-debug int 设置 debug 级别. 0 表示不输出调试信息。 值越大则表示输出更详细的 debug 信息.>
-version 启动后只显示版本信息就退出>
-J< flag > 因为 jhat 命令实际上会启动一个JVM来执行, 通过 -J 可以在启动JVM时传入一些启动参数. 例如, -J-Xmx512m 则指定运行 jhat 的Java虚拟机使用的最大堆内存为 512 MB. 如果需要使用多个JVM启动参数,则传入多个 -Jxxxxxx.
3 示例
$ jhat -J-Xmx512m dump.hprof
eading from dump.hprof…
Dump file created Fri Mar 11 17:13:42 CST 2016
Snapshot read, resolving…
Resolving 271678 objects…
Chasing references, expect 54 dots…
Eliminating duplicate references…
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

中间的-J-Xmx512m是在dump快照很大的情况下分配512M内存去启动HTTP服务器,运行完之后就可在浏览器打开Http://localhost:7000进行快照分析 堆快照分析主要在最后面的Heap Histogram里,里面根据class列出了dump的时候所有存活对象。

分析同样一个dump快照,MAT需要的额外内存比jhat要小的多的多,所以建议使用MAT来进行分析,当然也看个人偏好。

4 分析
打开浏览器Http://localhost:7000,该页面提供了几个查询功能可供使用:

All classes including platform
Show all members of the rootset
Show instance counts for all classes (including platform)
Show instance counts for all classes (excluding platform)
Show heap histogram
Show finalizer summary
Execute Object Query Language (OQL) query

一般查看堆异常情况主要看这个两个部分: Show instance counts for all classes (excluding platform),平台外的所有对象信息。如下图:
Show heap histogram 以树状图形式展示堆情况。如下图:
具体排查时需要结合代码,观察是否大量应该被回收的对象在一直被引用或者是否有占用内存特别大的对象无法被回收。
一般情况,会down到客户端用工具来分析

4.3.5 jstack

jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

1 命令格式
jstack [option] LVMID
1
2 option参数
-F : 当正常输出请求不被响应时,强制输出线程堆栈
-l : 除堆栈外,显示关于锁的附加信息
-m : 如果调用到本地方法的话,可以显示C/C++的堆栈
3 示例

$ jstack -l 11494|more

2016-07-28 13:40:04
Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.71-b01 mixed mode):"Attach Listener" daemon prio=10 tid=0x00007febb0002000 nid=0x6b6f waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None"http-bio-8005-exec-2" daemon prio=10 tid=0x00007feb94028000 nid=0x7b8c waiting on condition [0x00007fea8f56e000]java.lang.Thread.State: WAITING (parking)at sun.misc.Unsafe.park(Native Method)- parking to wait for  <0x00000000cae09b80> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)at java.lang.Thread.run(Thread.java:745)Locked ownable synchronizers:- None.....

4 分析
这里有一篇文章解释的很好 分析打印出的文件内容

jinfo
jinfo(JVM Configuration info)这个命令作用是实时查看和调整虚拟机运行参数。 之前的jps -v口令只能查看到显示指定的参数,如果想要查看未被显示指定的参数的值就要使用jinfo口令

1 命令格式
jinfo [option] [args] LVMID
1
2 option参数
-flag : 输出指定args参数的值
-flags : 不需要args参数,输出所有JVM参数的值
-sysprops : 输出系统属性,等同于System.getProperties()
3 示例
$ jinfo -flag 11494
-XX:CMSInitiatingOccupancyFraction=80

总结
本篇文章较为系统的总结了JVM自带的分析工具,但是要把这些工具命令全部使用或者是熟悉还是有难度的,只是选择一种比较熟悉的作为主要工具,其他工具可以作为定位问题的参考,另外说一句,其实jconsole还是比较好用,可以实时显示同时可以对内存进行dump操作。

特别说明:详细使用可参考 https://blog.csdn.net/wangxiaotongfan/article/details/82560739

五、日常辅助工具

5.1 screen

1)背景和介绍
系统管理员经常需要SSH 或者telent 远程登录到Linux 服务器,经常运行一些需要很长时间才能完成的任务,比如系统备份、ftp 传输等等。通常情况下我们都是为每一个这样的任务开一个远程终端窗口,因为它们执行的时间太长了。必须等待它们执行完毕,在此期间不能关掉窗口或者断开连接,否则这个任务就会被杀掉,一切半途而废了。

GNU Screen是一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换。

GNU Screen可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能。

会话恢复
只要Screen本身没有终止,在其内部运行的会话都可以恢复。这一点对于远程登录的用户特别有用——即使网络连接中断,用户也不会失去对已经打开的命令行会话的控制。只要再次登录到主机上执行screen -r就可以恢复会话的运行。同样在暂时离开的时候,也可以执行分离命令detach,在保证里面的程序正常运行的情况下让Screen挂起(切换到后台)。这一点和图形界面下的VNC很相似。
多窗口
在Screen环境下,所有的会话都独立的运行,并拥有各自的编号、输入、输出和窗口缓存。用户可以通过快捷键在不同的窗口下切换,并可以自由的重定向各个窗口的输入和输出。Screen实现了基本的文本操作,如复制粘贴等;还提供了类似滚动条的功能,可以查看窗口状况的历史记录。窗口还可以被分区和命名,还可以监视后台窗口的活动。
会话共享
Screen可以让一个或多个用户从不同终端多次登录一个会话,并共享会话的所有特性(比如可以看到完全相同的输出)。它同时提供了窗口访问权限的机制,可以对窗口进行密码保护。

安装方法:

yum install screen

2)语法
#screen [-AmRvx -ls -wipe][-d <作业名称>][-h <行数>][-r <作业名称>][-s ][-S <作业名称>]

参数说明

-A  将所有的视窗都调整为目前终端机的大小。
-d <作业名称>  将指定的screen作业离线。
-h <行数>  指定视窗的缓冲区行数。
-m  即使目前已在作业中的screen作业,仍强制建立新的screen作业。
-r <作业名称>  恢复离线的screen作业。
-R  先试图恢复离线的作业。若找不到离线的作业,即建立新的screen作业。
-s  指定建立新视窗时,所要执行的shell。
-S <作业名称>  指定screen作业的名称。
-v  显示版本信息。
-x  恢复之前离线的screen作业。
-ls或–list  显示目前所有的screen作业。
-wipe  检查目前所有的screen作业,并删除已经无法使用的screen作业。

3)案例

screen -S xiyu -> 新建一个叫xiyu的session
screen -ls -> 列出当前所有的session
screen -r xiyu -> 回到xiyu这个session
screen -d xiyu -> 远程detach某个session
screen -d -r xiyu -> 结束当前session并回到xiyu这个session
Ctrl + a +d //退出但不关闭当前session

4)常见问题

如果登录过程中遇到There is no screen to be resumed matching 4307.xiyu.报错,如下图:

解决方法:先使用-d退出一次,再使用-r 进入,因为突然断网,虽然重新连接,但之前的screen还是处于打开状态(1个screen无法同时打开2次),所以无法重新打开screen。

[root@elk-01 ~]# screen -d xiyu
[root@elk-01 ~]# screen -r xiyu

5.2 vim

1)介绍
Vim是从 vi 发展出来的一个文本编辑器。代码补全、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用,和Emacs并列成为类Unix系统用户最喜欢的文本编辑器

2)常用命令

编辑

序号 参数或命令 解释
1 i 进入编辑模式
2 ecs 退出编辑模式
3 I 编辑模式,行首开始插入
4 a 编辑模式,自动进入下一字符开始插入
5 A 编辑模式,自动进入行末符开始插入
6 o 编辑模式,自动进入下一行开始插入
7 u 撤销上一步操作

移动

序号 参数或命令 解释
1 gg 正常模式下,切换到首行
2 G 正常模式下,切换到尾行
3 h j k l 上下左右移动
4 ^和$ ^代表行首,$代表行末

选中和删除

序号 参数或命令 解释
1 s 删除光标所在的一个字符, 光标还在当行
2 S 删除光标所在的一行,光标还在当行,不同于dd
3 D 删除光标以后的内容
3 v 选中一个
4 V 选中一行
5 dd 删除所在行的一行

替换和回滚

序号 参数或命令 解释
1 r 单个替换
2 u 代表回滚一次
3 J 合并下一行到上一行

复制和粘贴

序号 参数或命令 解释
1 yy 复制,5yy,意思是复制光标下5行
2 p 粘贴

关闭

序号 参数或命令 解释
1 w 保存
2 wq, :x 保存并关闭
3 q 关闭(已保存)
4 q! 强制关闭

visual模式

序号 参数或命令 解释 备注
1 v visual模式 进入visual模式后,按住shift键就可以上下左右移动选择文本,也可以使用数字+h/j/k/l来移动选择文本块;使用"$“和”^"可以将选择扩展到行尾或者行首。
2 V visual line模式
3 Ctrl-V visual block模式

5.3 pstree

pstree命令以树状图显示进程间的关系(display a tree of processes)。ps命令可以显示当前正在运行的那些进程的信息,但是对于它们之间的关系却显示得不够清晰。在Linux系统中,系统调用fork可以创建子进程,通过子shell也可以创建子进程,Linux系统中进程之间的关系天生就是一棵树,树的根就是进程PID为1的init进程。以树状图只显示进程的名字,且相同进程合并显示

  1. pstree

  2. pstree -p //以树状图显示进程PID为的进程以及子孙进程,如果有-p参数则同时显示每个进程的PID:

  3. pstree -sp //显示所有父进程及其PID

  4. pstree -asp //显示出所有父进程、显示它们的PID、显示它们启动时所使用的命令

5.4 lsof

lsof(list open files)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。
lsof几乎可以完成netstat ps的所有功能

  • 基础用法:
默认 : 没有选项,lsof列出活跃进程的所有打开文件
组合 : 可以将选项组合到一起,如-abc,但要当心哪些选项需要参数
-a : 结果进行“与”运算(而不是“或”)
-l : 在输出显示用户ID而不是用户名
-h : 获得帮助
-t : 仅获取进程ID
-U : 获取UNIX套接口地址
-F : 格式化输出结果,用于其它命令。可以通过多种方式格式化,如-F pcfn(用于进程id、命令名、文件描述符、文件名,并以空终止)
  • 指令用法:
lsof -l 列出全部的系统打开的文件,如PID、用户等,可以搭配grep、more使用lsof -i 显示ipv4相关的所有连接信息,如服务名、PID、用户等,可以搭配grep使用lsof -i 6 显示ipv6相关的所有连接信息,如服务名、PID、用户等lsof -itcp  显示tcp相关的所有连接信息,如服务名、PID、用户等lsof -iucp  显示ucp相关的所有连接信息,如服务名、PID、用户等lsof abc.txt 显示开启文件abc.txt的进程lsof -p 22  显示与22端口相关的所有信息lsof -i :22 知道22端口现在运行什么程序lsof -c abc 显示abc进程现在打开的文件lsof -g gid 显示归属gid的进程情况lsof +d /usr/local/ 显示目录下被进程开启的文件lsof +D /usr/local/ 同上,但是会搜索目录下的目录,时间较长lsof -d 4 显示使用fd为4的进程 www.2cto.com
  • 用法进阶
lsof -i 用以显示符合条件的进程情况语法: lsof -i[46] [protocol][@hostname|hostaddr][:service|port]46 --> IPv4 or IPv6protocol --> TCP or UDPhostname --> Internet host namehostaddr --> IPv4位置service --> /etc/service中的 service name (可以不只一个)port --> 端口号 (可以不只一个)例子: TCP:25 - TCP and port 25
@1.2.3.4 - Internet IPv4 host address 1.2.3.4
tcp@ohaha.ks.edu.tw:ftp - TCP protocol hosthaha.ks.edu.tw service name:ftplsof -n 不将IP转换为hostname,缺省是不加上-n参数例子: lsof -i tcp@ohaha.ks.edu.tw:ftp -nlsof -p 12 看进程号为12的进程打开了哪些文件lsof +|-r [t] 控制lsof不断重复执行,缺省是15s刷新-r,lsof会永远不断的执行,直到收到中断信号+r,lsof会一直执行,直到没有档案被显示例子:不断查看目前ftp连接的情况:lsof -i tcp@ohaha.ks.edu.tw:ftp -rlsof -s 列出打开文件的大小,如果没有大小,则留下空白lsof -u username 以UID,列出打开的文件 www.2cto.com

Linux SRE工程师常用提效工具相关推荐

  1. Web前端技术分享:全栈工程师常用的开发工具

    全栈工程师,也叫全端工程师,是指掌握多种技能,并能利用多种技能独立完成产品的人.全栈工程师熟悉多种开发语言,同时具备前端和后台开发能力,从需求分析,原型设计到产品开发,测试,部署,发布全流程都十分熟悉 ...

  2. Linux下Shell常用命令与工具

    文章目录 Shell常用命令与工具 1.ls 2.echo 3.printf 4.cat 5.tac 6 .rev 7.wc 8.cp 9.mkdir 10.mv 11.rename 12.dirna ...

  3. linux系统里常用的抓图工具,Linux系统下屏幕截图常用方法

    电脑操作系统中一般都有自带截图快捷键,而很多软件业有截图的功能,那么Linux操作系统要如何截图呢?下面小编就给大家介绍下Ubuntu下如何截图. 在linux系统上怎么截图: 键盘上的截图键还可以用 ...

  4. 运维工程师常用平台及工具

    运维工程师使用的运维平台和工具包括: Web服务器:apache.tomcat.nginx.lighttpd 监控:nagios.ganglia.cacti.zabbix 自动部署:ansible.s ...

  5. Mac(Alfred) 办公提效工具

    Alfred简介 Alfred 是 Mac 上一款著名的效率应用,强大的功能和众多的扩展能让你在实际操作中大幅提升工作效率. Alfred 是一个用键盘通过热键.关键字.自定义插件来加快操作效率的工具 ...

  6. Linux运维常用检查网络工具

    一.Ping ping可以检查网络是否连通,可以很好地帮助我们分析和判定网络故障. ping ip 二.Telnet telnet通常用来查看某个端口是否可访问. telnet ip port 三.C ...

  7. Java程序员日常开发提效工具(谷歌,Idea)-长期更新

    谷歌 1. Adblock Plus 广告拦截工具 Adblock Plus 是 Firefox.Chrome.Safari.Android 和 iOS 上最受欢迎的广告拦截程序.拦截 Faceboo ...

  8. linux系统里常用的抓图工具,linux下很棒的抓图工具——scrot

    这次重装FC5,很谨慎了.对欲安装的每件工具都仔细斟酌了一番.在屏幕抓取工具的选择上,我首选gimp,颇研究了一番,但gimp用于抓图总觉得大材小用,而且也不很方便,譬如无法进行区域交互抓取,只能抓窗 ...

  9. 提效工具git的基本使用

    安装就不废话了,各种操作平台安装见官网就行. 图片引用自菜鸟教程 以windows为例,首先打开git bash(即git的终端) 首先创建一个文件夹作为仓库(或者其他的想作为代码库的文件夹) 这里我 ...

最新文章

  1. 《HTML 5与CSS 3权威指南(第3版·下册)》——19.4.2 E:enabled伪类选择器与E:disabled伪类选择器...
  2. iOS 动画绘制线条颜色渐变的折线图
  3. 电脑小白用Linux,linux小白说说用linux的感受
  4. 安卓案例:使用AChartEngine绘制折线图
  5. 用RtlAdjustPrivilege来调整进程权限(VB6.0代码)
  6. 同步异步、阻塞非阻塞
  7. 【干货】史上最全的Tensorflow学习资源汇总(转)
  8. gtest简短,简单易用
  9. cmos逻辑门传输延迟时间_MOS管以及简单CMOS逻辑门电路原理图解析
  10. 宋维刚老师词霸天下38000词汇思维导图
  11. 他拥有当今世界最高智商,从出生就一路开挂,然而,获得数学最高奖的他却说自己只是个热爱数学的普通人...
  12. Vue后台--Ele组件表格根据数字展示数值
  13. 王卫,零售风口练习生
  14. Verilog永无止境
  15. linux下repo是什么文件夹,yum的repo文件详解、以及epel简介、yum源的更换
  16. 迎难而上,阿里高频考点2023Java岗面试突击手册
  17. 日语二级语法汇总(part10/16)
  18. 编程Verilog四位全加器
  19. 全世界最著名的经济金融学网站
  20. java es 数据批量导入_elasticsearch批量数据导入和导出

热门文章

  1. vue项目中Des的加密解密
  2. 有赚一亿的欲望,却只有一天的耐心。
  3. tp5 自动加上html,【TP5.1】HTML标签自动转义,导致CKEditor保存内容无法正常显示!...
  4. 国赛ezpop题目复现(tp6)
  5. 大一计算机导论教程总结,计算机导论实验教程--详细介绍
  6. Linux 使用 Python 执行多线程命令
  7. 帧同步在竞技类网络游戏中的应用
  8. 【180927】美女拼图游戏源码
  9. 【滑动验证码 selenium】滑动验证码模拟滑动
  10. HP打印机同一路由(子网)下共享连接打印机