十二 lsof命令简介 lsof(list open files) 是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以 如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件 描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工 具能够查看这个列表对系统监测以及排错将是很有帮助的。 1.命令格式: lsof [参数][文件] 2.命令功能: 用于查看你进程开打的文件,打开文件的进程,进程打开的端口(TCP、UDP)。找回/恢复删除的文件。是十分方便的系统监视工具,因为 lsof 需要访问核心内存和各种文件,所以需要root用户执行。 lsof打开的文件可以是: 1.普通文件 2.目录 3.网络文件系统的文件 4.字符或设备文件 5.(函数)共享库 6.管道,命名管道 7.符号链接 8.网络文件(例如:NFS file、网络socket,unix域名socket) 9.还有其它类型的文件,等等 3.命令参数: -a 列出打开文件存在的进程 -c<进程名> 列出指定进程所打开的文件 -g 列出GID号进程详情 -d<文件号> 列出占用该文件号的进程 +d<目录> 列出目录下被打开的文件 +D<目录> 递归列出目录下被打开的文件 -n<目录> 列出使用NFS的文件 -i<条件> 列出符合条件的进程。(4、6、协议、:端口、 @ip ) -p<进程号> 列出指定进程号所打开的文件 -u 列出UID号进程详情 -h 显示帮助信息 -v 显示版本信息 4.使用实例: 实例1:无任何参数 命令: lsof 输出: [root@localhost ~]# lsof COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME init 1 root cwd DIR 8,2 4096 2 / init 1 root rtd DIR 8,2 4096 2 / init 1 root txt REG 8,2 43496 6121706 /sbin/init init 1 root mem REG 8,2 143600 7823908 /lib64/ld-2.5.so init 1 root mem REG 8,2 1722304 7823915 /lib64/libc-2.5.so init 1 root mem REG 8,2 23360 7823919 /lib64/libdl-2.5.so init 1 root mem REG 8,2 95464 7824116 /lib64/libselinux.so.1 init 1 root mem REG 8,2 247496 7823947 /lib64/libsepol.so.1 init 1 root 10u FIFO 0,17 1233 /dev/initctl migration 2 root cwd DIR 8,2 4096 2 / migration 2 root rtd DIR 8,2 4096 2 / migration 2 root txt unknown /proc/2/exe ksoftirqd 3 root cwd DIR 8,2 4096 2 / ksoftirqd 3 root rtd DIR 8,2 4096 2 / ksoftirqd 3 root txt unknown /proc/3/exe migration 4 root cwd DIR 8,2 4096 2 / migration 4 root rtd DIR 8,2 4096 2 / migration 4 root txt unknown /proc/4/exe ksoftirqd 5 root cwd DIR 8,2 4096 2 / ksoftirqd 5 root rtd DIR 8,2 4096 2 / ksoftirqd 5 root txt unknown /proc/5/exe events/0 6 root cwd DIR 8,2 4096 2 / events/0 6 root rtd DIR 8,2 4096 2 / events/0 6 root txt unknown /proc/6/exe events/1 7 root cwd DIR 8,2 4096 2 / 说明: lsof输出各列信息的意义如下: COMMAND:进程的名称 PID:进程标识符 PPID:父进程标识符(需要指定-R参数) USER:进程所有者 PGID:进程所属组 FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等 (1)cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改 (2)txt :该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序 (3)lnn:library references (AIX); (4)er:FD information error (see NAME column); (5)jld:jail directory (FreeBSD); (6)ltx:shared library text (code and data); (7)mxx :hex memory-mapped type number xx. (8)m86:DOS Merge mapped file; (9)mem:memory-mapped file; (10)mmap:memory-mapped device; (11)pd:parent directory; (12)rtd:root directory; (13)tr:kernel trace file (OpenBSD); (14)v86 VP/ix mapped file; (15)0:表示标准输出 (16)1:表示标准输入 (17)2:表示标准错误 一般在标准输出、标准错误、标准输入后还跟着文件状态模式:r、w、u等 (1)u:表示该文件被打开并处于读取/写入模式 (2)r:表示该文件被打开并处于只读模式 (3)w:表示该文件被打开并处于 (4)空格:表示该文件的状态模式为unknow,且没有锁定 (5)-:表示该文件的状态模式为unknow,且被锁定 同时在文件状态模式后面,还跟着相关的锁 (1)N:for a Solaris NFS lock of unknown type; (2)r:for read lock on part of the file; (3)R:for a read lock on the entire file; (4)w:for a write lock on part of the file;(文件的部分写锁) (5)W:for a write lock on the entire file;(整个文件的写锁) (6)u:for a read and write lock of any length; (7)U:for a lock of unknown type; (8)x:for an SCO OpenServer Xenix lock on part of the file; (9)X:for an SCO OpenServer Xenix lock on the entire file; (10)space:if there is no lock. TYPE:文件类型,如DIR、REG等,常见的文件类型 (1)DIR:表示目录 (2)CHR:表示字符类型 (3)BLK:块设备类型 (4)UNIX: UNIX 域套接字 (5)FIFO:先进先出 (FIFO) 队列 (6)IPv4:网际协议 (IP) 套接字 DEVICE:指定磁盘的名称 SIZE:文件的大小 NODE:索引节点(文件在磁盘上的标识) NAME:打开文件的确切名称 实例2:查看谁正在使用某个文件,也就是说查找某个文件相关的进程 命令: lsof /bin/bash 输出: [root@localhost ~]# lsof /bin/bash COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME bash 24159 root txt REG 8,2 801528 5368780 /bin/bash bash 24909 root txt REG 8,2 801528 5368780 /bin/bash bash 24941 root txt REG 8,2 801528 5368780 /bin/bash 实例3:递归查看某个目录的文件信息 命令: lsof test/test3 输出: [root@localhost ~]# cd /opt/soft/ [root@localhost soft]# lsof test/test3 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME bash 24941 root cwd DIR 8,2 4096 2258872 test/test3 vi 24976 root cwd DIR 8,2 4096 2258872 test/test3 说明: 使用了+D,对应目录下的所有子目录和文件都会被列出 实例4:不使用+D选项,遍历查看某个目录的所有文件信息的方法 命令: lsof |grep 'test/test3' 输出: [root@localhost soft]# lsof |grep 'test/test3' bash 24941 root cwd DIR 8,2 4096 2258872 /opt/soft/test/test3 vi 24976 root cwd DIR 8,2 4096 2258872 /opt/soft/test/test3 vi 24976 root 4u REG 8,2 12288 2258882 /opt/soft/test/test3/.log2013.log.swp 实例5:列出某个用户打开的文件信息 命令: lsof -u username 说明: -u 选项,u其实是user的缩写 实例6:列出某个程序进程所打开的文件信息 命令: lsof -c mysql 说明: -c 选项将会列出所有以mysql这个进程开头的程序的文件,其实你也可以写成 lsof | grep mysql, 但是第一种方法明显比第二种方法要少打几个字符了 实例7:列出多个进程多个打开的文件信息 命令: lsof -c mysql -c apache 实例8:列出某个用户以及某个进程所打开的文件信息 命令: lsof -u test -c mysql 说明: 用户与进程可相关,也可以不相关 实例9:列出除了某个用户外的被打开的文件信息 命令: lsof -u ^root 说明: ^这个符号在用户名之前,将会把是root用户打开的进程不让显示 实例10:通过某个进程号显示该进行打开的文件 命令: lsof -p 1 实例11:列出多个进程号对应的文件信息 命令: lsof -p 1,2,3 实例12:列出除了某个进程号,其他进程号所打开的文件信息 命令: lsof -p ^1 实例13:列出所有的网络连接 命令: lsof -i 实例14:列出所有tcp 网络连接信息 命令: lsof -i tcp 实例15:列出所有udp网络连接信息 命令: lsof -i udp 实例16:列出谁在使用某个端口 命令: lsof -i :3306 实例17:列出谁在使用某个特定的udp端口 命令: lsof -i udp:55 或者:特定的tcp端口 命令: lsof -i tcp:80 实例18:列出某个用户的所有活跃的网络端口 命令: lsof -a -u test -i 实例19:列出所有网络文件系统 命令: lsof -N 实例20:域名socket文件 命令: lsof -u 实例21:某个用户组所打开的文件信息 命令: lsof -g 5555 实例22:根据文件描述列出对应的文件信息 命令: lsof -d description(like 2) 例如:lsof -d txt 例如:lsof -d 1 例如:lsof -d 2 说明: 0表示标准输入,1表示标准输出,2表示标准错误,从而可知:所以大多数应用程序所打开的文件的 FD 都是从 3 开始 实例23:根据文件描述范围列出文件信息 命令: lsof -d 2-3 实例24:列出COMMAND列中包含字符串" sshd",且文件描符的类型为txt的文件信息 命令: lsof -c sshd -a -d txt 输出: [root@localhost soft]# lsof -c sshd -a -d txt COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME sshd 2756 root txt REG 8,2 409488 1027867 /usr/sbin/sshd sshd 24155 root txt REG 8,2 409488 1027867 /usr/sbin/sshd sshd 24905 root txt REG 8,2 409488 1027867 /usr/sbin/sshd sshd 24937 root txt REG 8,2 409488 1027867 /usr/sbin/sshd 实例25:列出被进程号为1234的进程所打开的所有IPV4 network files 命令: lsof -i 4 -a -p 1234 实例26:列出目前连接主机peida.linux上端口为:20,21,22,25,53,80相关的所有文件信息,且每隔3秒不断的执行lsof指令 命令: lsof -i @peida.linux:20,21,22,25,53,80 -r 3 十三 watch命令简介 watch是一个非常实用的命令,基本所有的Linux发行版都带有这个小工具,如同名字一样,watch可以帮你监测一个命令的运行结果,省得你一遍遍的手动运行。在Linux下,watch是周期性的执行下个程序,并全屏显示执行结果。你可以拿他来监测你想要的一切命令的结果变化,比如 tail 一个 log 文件,ls 监测某个文件的大小变化,看你的想象力了! 1.命令格式: watch[参数][命令] 2.命令功能: 可以将命令的输出结果输出到标准输出设备,多用于周期性执行命令/定时执行命令 3.命令参数: -n或--interval watch缺省每2秒运行一下程序,可以用-n或-interval来指定间隔的时间。 -d或--differences 用-d或--differences 选项watch 会高亮显示变化的区域。 而-d=cumulative选项会把变动过的地方(不管最近的那次有没有变动)都高亮显示出来。 -t 或-no-title 会关闭watch命令在顶部的时间间隔,命令,当前时间的输出。 -h, --help 查看帮助文档 4.使用实例: 实例1:每隔一秒高亮显示网络链接数的变化情况 命令: watch -n 1 -d netstat –ant 说明: 其它操作: 切换终端: Ctrl+x 退出watch:Ctrl+g 实例2:每隔一秒高亮显示http链接数的变化情况 命令: watch -n 1 -d 'pstree|grep http' 说明: 每隔一秒高亮显示http链接数的变化情况。 后面接的命令若带有管道符,需要加''将命令区域归整。 实例3:实时查看模拟***客户机建立起来的连接数 命令: watch 'netstat -an | grep:21 | \ grep<模拟***客户机的IP>| wc -l' 说明: 实例4:监测当前目录中 scf' 的文件的变化 命令: watch -d 'ls -l|grep scf' 实例5:10秒一次输出系统的平均负载 命令: watch -n 10 'cat /proc/loadavg' 十四 crond命令简介 crond 是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务 工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。 Linux下的任务调度分为两类,系统任务调度和用户任务调度。 系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc目录下有一个crontab文件,这个就是系统任务调度的配置文件。 /etc/crontab文件包括下面几行: [root@localhost ~]# cat /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=""HOME=/ # run-parts 51 * * * * root run-parts /etc/cron.hourly 24 7 * * * root run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4 1 * * root run-parts /etc/cron.monthly 前 四行是用来配置crond任务运行的环境变量,第一行SHELL变量指定了系统要使用哪个shell,这里是bash,第二行PATH变量指定了系统执行 命令的路径,第三行MAILTO变量指定了crond的任务执行信息将通过电子邮件发送给root用户,如果MAILTO变量的值为空,则表示不发送任务 执行信息给用户,第四行的HOME变量指定了在执行命令或者脚本时使用的主目录。第六至九行表示的含义将在下个小节详细讲述。这里不在多说。 用户任务调度:用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab 工具来定制自己的计划任务。所有用户定义的crontab 文件都被保存在 /var/spool/cron目录中。其文件名与用户名一致。 一.使用者权限文件: 文件: /etc/cron.deny 说明: 该文件中所列用户不允许使用crontab命令 文件: /etc/cron.allow 说明: 该文件中所列用户允许使用crontab命令 文件: /var/spool/cron/ 说明: 所有用户crontab文件存放的目录,以用户名命名 二.crontab文件的含义: 用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式如下: minute hour day month week command 其中: minute: 表示分钟,可以是从0到59之间的任何整数。 hour:表示小时,可以是从0到23之间的任何整数。 day:表示日期,可以是从1到31之间的任何整数。 month:表示月份,可以是从1到12之间的任何整数。 week:表示星期几,可以是从0到7之间的任何整数,这里的0或7代表星期日。 command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。 在以上各个字段中,还可以使用以下特殊字符: 星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。 逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9” 中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6” 正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。 三.crond服务 安装crontab: yum install crontabs 服务操作说明: /sbin/service crond start //启动服务 /sbin/service crond stop //关闭服务 /sbin/service crond restart //重启服务 /sbin/service crond reload //重新载入配置 查看crontab服务状态: service crond status 手动启动crontab服务: service crond start 查看crontab服务是否已设置为开机启动,执行命令: ntsysv 加入开机自动启动: chkconfig –level 35 crond on 四.crontab命令详解 1.命令格式: crontab [-u user] file crontab [-u user] [ -e | -l | -r ] 2.命令功能: 通过crontab 命令,我们可以在固定的间隔时间执行指定的系统指令或 shell script脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合。这个命令非常设合周期性的日志分析或数据备份等工作。 3.命令参数: -u user:用来设定某个用户的crontab服务,例如,“-u ixdba”表示设定ixdba用户的crontab服务,此参数一般有root用户来运行。 file:file是命令文件的名字,表示将file做为crontab的任务列表文件并载入crontab。如果在命令行中没有指定这个文件,crontab命令将接受标准输入(键盘)上键入的命令,并将它们载入crontab。 -e:编辑某个用户的crontab文件内容。如果不指定用户,则表示编辑当前用户的crontab文件。 -l:显示某个用户的crontab文件内容,如果不指定用户,则表示显示当前用户的crontab文件内容。 -r:从/var/spool/cron目录中删除某个用户的crontab文件,如果不指定用户,则默认删除当前用户的crontab文件。 -i:在删除用户的crontab文件时给确认提示。 4.常用方法: 1). 创建一个新的crontab文件 在 考虑向cron进程提交一个crontab文件之前,首先要做的一件事情就是设置环境变量EDITOR。cron进程根据它来确定使用哪个编辑器编辑 crontab文件。9 9 %的UNIX和LINUX用户都使用vi,如果你也是这样,那么你就编辑$ HOME目录下的. profile文件,在其 中加入这样一行: EDITOR=vi; export EDITOR 然后保存并退出。不妨创建一个名为<user> cron的文件,其中<user>是用户名,例如, davecron。在该文件中加入如下的内容。 # (put your own initials here)echo the date to the console every # 15minutes between 6pm and 6am 0,15,30,45 18-06 * * * /bin/echo 'date' > /dev/console 保存并退出。确信前面5个域用空格分隔。 在 上面的例子中,系统将每隔1 5分钟向控制台输出一次当前时间。如果系统崩溃或挂起,从最后所显示的时间就可以一眼看出系统是什么时间停止工作的。在有些 系统中,用tty1来表示控制台,可以根据实际情况对上面的例子进行相应的修改。为了提交你刚刚创建的crontab文件,可以把这个新创建的文件作为 cron命令的参数: $ crontab davecron 现在该文件已经提交给cron进程,它将每隔1 5分钟运行一次。 同时,新创建文件的一个副本已经被放在/var/spool/cron目录中,文件名就是用户名(即dave)。 2). 列出crontab文件 为了列出crontab文件,可以用: $ crontab -l 0,15,30,45,18-06 * * * /bin/echo `date` > dev/tty1 你将会看到和上面类似的内容。可以使用这种方法在$ H O M E目录中对crontab文件做一备份: $ crontab -l > $HOME/mycron 这样,一旦不小心误删了crontab文件,可以用上一节所讲述的方法迅速恢复。 3). 编辑crontab文件 如果希望添加、删除或编辑crontab文件中的条目,而E D I TO R环境变量又设置为v i,那么就可以用v i来编辑crontab文件,相应的命令为: $ crontab -e 可以像使用v i编辑其他任何文件那样修改crontab文件并退出。如果修改了某些条目或添加了新的条目,那么在保存该文件时, c r o n会对其进行必要的完整性检查。如果其中的某个域出现了超出允许范围的值,它会提示你。 我们在编辑crontab文件时,没准会加入新的条目。例如,加入下面的一条: # DT:delete core files,at 3.30am on 1,7,14,21,26,26 days of each month 30 3 1,7,14,21,26 * * /bin/find -name "core' -exec rm {} \; 现在保存并退出。最好在crontab文件的每一个条目之上加入一条注释,这样就可以知道它的功能、运行时间,更为重要的是,知道这是哪位用户的作业。 现在让我们使用前面讲过的crontab -l命令列出它的全部信息: $ crontab -l # (crondave installed on Tue May 4 13:07:43 1999) # DT:ech the date to the console every 30 minites 0,15,30,45 18-06 * * * /bin/echo `date` > /dev/tty1 # DT:delete core files,at 3.30am on 1,7,14,21,26,26 days of each month 30 3 1,7,14,21,26 * * /bin/find -name "core' -exec rm {} \; 4). 删除crontab文件 要删除crontab文件,可以用: $ crontab -r 5). 恢复丢失的crontab文件 如果不小心误删了crontab文件,假设你在自己的$ H O M E目录下还有一个备份,那么可以将其拷贝到/var/spool/cron/<username>,其中<username>是用户名。如果由于权限问题无法完成拷贝,可以用: $ crontab <filename> 其中,<filename>是你在$ H O M E目录中副本的文件名。 我建议你在自己的$ H O M E目录中保存一个该文件的副本。我就有过类似的经历,有数次误删了crontab文件(因为r键紧挨在e键的右边)。这就是为什么有些系统文档建议不要直接编辑crontab文件,而是编辑该文件的一个副本,然后重新提交新的文件。 有些crontab的变体有些怪异,所以在使用crontab命令时要格外小心。如果遗漏了任何选项,crontab可能会打开一个空文件,或者看起来像是个空文件。这时敲delete键退出,不要按<Ctrl-D>,否则你将丢失crontab文件。 6.使用实例 实例1:每1分钟执行一次command 命令: * * * * * command 实例2:每小时的第3和第15分钟执行 命令: 3,15 * * * * command 实例3:在上午8点到11点的第3和第15分钟执行 命令: 3,15 8-11 * * * command 实例4:每隔两天的上午8点到11点的第3和第15分钟执行 命令: 3,15 8-11 */2 * * command 实例5:每个星期一的上午8点到11点的第3和第15分钟执行 命令: 3,15 8-11 * * 1 command 实例6:每晚的21:30重启smb 命令: 30 21 * * * /etc/init.d/smb restart 实例7:每月1、10、22日的4 : 45重启smb 命令: 45 4 1,10,22 * * /etc/init.d/smb restart 实例8:每周六、周日的1 : 10重启smb 命令: 10 1 * * 6,0 /etc/init.d/smb restart 实例9:每天18 : 00至23 : 00之间每隔30分钟重启smb 命令: 0,30 18-23 * * * /etc/init.d/smb restart 实例10:每星期六的晚上11 : 00 pm重启smb 命令: 0 23 * * 6 /etc/init.d/smb restart 实例11:每一小时重启smb 命令: * */1 * * * /etc/init.d/smb restart 实例12:晚上11点到早上7点之间,每隔一小时重启smb 命令: * 23-7/1 * * * /etc/init.d/smb restart 实例13:每月的4号与每周一到周三的11点重启smb 命令: 0 11 4 * mon-wed /etc/init.d/smb restart 实例14:一月一号的4点重启smb 命令: 0 4 1 jan * /etc/init.d/smb restart 实例15:每小时执行/etc/cron.hourly目录内的脚本 命令: 01 * * * * root run-parts /etc/cron.hourly 说明: run-parts这个参数了,如果去掉这个参数的话,后面就可以写要运行的某个脚本名,而不是目录名了 五、使用注意事项 1. 注意环境变量问题 有时我们创建了一个crontab,但是这个任务却无法自动执行,而手动执行这个任务却没有问题,这种情况一般是由于在crontab文件中没有配置环境变量引起的。 在 crontab文件中定义多个调度任务时,需要特别注意的一个问题就是环境变量的设置,因为我们手动执行某个任务时,是在当前shell环境下进行的,程 序当然能找到环境变量,而系统自动执行任务调度时,是不会加载任何环境变量的,因此,就需要在crontab文件中指定任务运行所需的所有环境变量,这 样,系统执行任务调度时就没有问题了。 不要假定cron知道所需要的特殊环境,它其实并不知道。所以你要保证在shelll脚本中提供所有必要的路径和环境变量,除了一些自动设置的全局变量。所以注意如下3点: 1)脚本中涉及文件路径时写全局路径; 2)脚本执行要用到java或其他环境变量时,通过source命令引入环境变量,如: cat start_cbp.sh #!/bin/sh source /etc/profile export RUN_CONF=/home/d139/conf/platform/cbp/cbp_jboss.conf /usr/local/jboss-4.0.5/bin/run.sh -c mev & 3)当手动执行脚本OK,但是crontab死活不执行时。这时必须大胆怀疑是环境变量惹的祸,并可以尝试在crontab中直接引入环境变量解决问题。如: 0 * * * * . /etc/profile;/bin/sh /var/www/java/audit_no_count/bin/restart_audit.sh 2. 注意清理系统用户的邮件日志 每条任务调度执行完毕,系统都会将任务输出信息通过电子邮件的形式发送给当前系统用户,这样日积月累,日志信息会非常大,可能会影响系统的正常运行,因此,将每条任务进行重定向处理非常重要。 例如,可以在crontab文件中设置如下形式,忽略日志输出: 0 */3 * * * /usr/local/apache2/apachectl restart >/dev/null 2>&1 “/dev/null 2>&1”表示先将标准输出重定向到/dev/null,然后将标准错误重定向到标准输出,由于标准输出已经重定向到了/dev/null,因此标准错误也会重定向到/dev/null,这样日志输出问题就解决了。 3. 系统级任务调度与用户级任务调度 系 统级任务调度主要完成系统的一些维护操作,用户级任务调度主要完成用户自定义的一些任务,可以将用户级任务调度放到系统级任务调度来完成(不建议这么 做),但是反过来却不行,root用户的任务调度操作可以通过“crontab –uroot –e”来设置,也可以将调度任务直接写入/etc /crontab文件,需要注意的是,如果要定义一个定时重启系统的任务,就必须将任务放到/etc/crontab文件,即使在root用户下创建一个 定时重启系统的任务也是无效的。 4. 其他注意事项 新创建的cron job,不会马上执行,至少要过2分钟才执行。如果重启cron则马上执行。 当crontab突然失效时,可以尝试/etc/init.d/crond restart解决问题。或者查看日志看某个job有没有执行/报错tail -f /var/log/cron。 千万别乱运行crontab -r。它从Crontab目录(/var/spool/cron)中删除用户的Crontab文件。删除了该用户的所有crontab都没了。 在crontab中%是有特殊含义的,表示换行的意思。如果要用的话必须进行转义\%,如经常用的date ‘+%Y%m%d’在crontab里是不会执行的,应该换成date ‘+\%Y\%m\%d’。 十五 Vmstat命令简介 vmstat 是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监控。他是对系统的整体 情况进行统计,不足之处是无法对某个进程进行深入分析。vmstat 工具提供了一种低开销的系统性能观察方式。因为 vmstat 本身就是低开销工具,在非常高负荷的服务器上,你需要查看并监控系统的健康情况,在控制窗口还是能够使用vmstat 输出结果。在学习vmstat命令前,我们先了解一下Linux系统中关于物理内存和虚拟内存相关信息。 一.物理内存和虚拟内存区别: 我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概念。 物理内存就是系统硬件提供的内存大小,是真正的内存,相对于物理内存,在linux下还有一个虚拟内存的概念,虚拟内存就是为了满足物理内存的不足而提出的策略,它是利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间(Swap Space)。 作为物理内存的扩展,linux会在物理内存不足时,使用交换分区的虚拟内存,更详细的说,就是内核会将暂时不用的内存块信息写到交换空间,这样以来,物理内存得到了释放,这块内存就可以用于其它目的,当需要用到原始的内容时,这些信息会被重新从交换空间读入物理内存。 linux的内存管理采取的是分页存取机制,为了保证物理内存能得到充分的利用,内核会在适当的时候将物理内存中不经常使用的数据块自动交换到虚拟内存中,而将经常使用的信息保留到物理内存。 要深入了解linux内存运行机制,需要知道下面提到的几个方面: 首先,Linux系统会不时的进行页面交换操作,以保持尽可能多的空闲物理内存,即使并没有什么事情需要内存,Linux也会交换出暂时不用的内存页面。这可以避免等待交换所需的时间。 其 次,linux进行页面交换是有条件的,不是所有页面在不用时都交换到虚拟内存,linux内核根据”最近最经常使用“算法,仅仅将一些不经常使用的页面 文件交换到虚拟内存,有时我们会看到这么一个现象:linux物理内存还有很多,但是交换空间也使用了很多。其实,这并不奇怪,例如,一个占用很大内存的 进程运行时,需要耗费很多内存资源,此时就会有一些不常用页面文件被交换到虚拟内存中,但后来这个占用很多内存资源的进程结束并释放了很多内存时,刚才被 交换出去的页面文件并不会自动的交换进物理内存,除非有这个必要,那么此刻系统物理内存就会空闲很多,同时交换空间也在被使用,就出现了刚才所说的现象 了。关于这点,不用担心什么,只要知道是怎么一回事就可以了。 最 后,交换空间的页面在使用时会首先被交换到物理内存,如果此时没有足够的物理内存来容纳这些页面,它们又会被马上交换出去,如此以来,虚拟内存中可能没有 足够空间来存储这些交换页面,最终会导致linux出现假死机、服务异常等问题,linux虽然可以在一段时间内自行恢复,但是恢复后的系统已经基本不可 用了。 因此,合理规划和设计linux内存的使用,是非常重要的。 二.虚拟内存原理: 在 系统中运行的每个进程都需要使用到内存,但不是每个进程都需要每时每刻使用系统分配的内存空间。当系统运行所需内存超过实际的物理内存,内核会释放某些进 程所占用但未使用的部分或所有物理内存,将这部分资料存储在磁盘上直到进程下一次调用,并将释放出的内存提供给有需要的进程使用。 在Linux内存管理中,主要是通过“调页Paging”和“交换Swapping”来完成上述的内存调度。调页算法是将内存中最近不常使用的页面换到磁盘上,把活动页面保留在内存中供进程使用。交换技术是将整个进程,而不是部分页面,全部交换到磁盘上。 分页(Page)写入磁盘的过程被称作Page-Out,分页(Page)从磁盘重新回到内存的过程被称作Page-In。当内核需要一个分页时,但发现此分页不在物理内存中(因为已经被Page-Out了),此时就发生了分页错误(Page Fault)。 当 系统内核发现可运行内存变少时,就会通过Page-Out来释放一部分物理内存。经管Page-Out不是经常发生,但是如果Page-out频繁不断的 发生,直到当内核管理分页的时间超过运行程式的时间时,系统效能会急剧下降。这时的系统已经运行非常慢或进入暂停状态,这种状态亦被称作 thrashing(颠簸)。 1.命令格式: vmstat [-a] [-n] [-S unit] [delay [ count]] vmstat [-s] [-n] [-S unit] vmstat [-m] [-n] [delay [ count]] vmstat [-d] [-n] [delay [ count]] vmstat [-p disk partition] [-n] [delay [ count]] vmstat [-f] vmstat [-V] 2.命令功能: 用来显示虚拟内存的信息 3.命令参数: -a:显示活跃和非活跃内存 -f:显示从系统启动至今的fork数量 。 -m:显示slabinfo -n:只在开始时显示一次各字段名称。 -s:显示内存相关统计信息及多种系统活动数量。 delay:刷新时间间隔。如果不指定,只显示一条结果。 count:刷新次数。如果不指定刷新次数,但指定了刷新时间间隔,这时刷新次数为无穷。 -d:显示磁盘相关统计信息。 -p:显示指定磁盘分区统计信息 -S:使用指定单位显示。参数有 k 、K 、m 、M ,分别代表1000、1024、1000000、1048576字节(byte)。默认单位为K(1024 bytes) -V:显示vmstat版本信息。 4.使用实例: 实例1:显示虚拟内存使用情况 命令: vmstat 输出: [root@localhost ~]# vmstat 5 6 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 0 3029876 199616 690980 0 0 0 2 3 2 0 0 100 0 0 0 0 0 3029752 199616 690980 0 0 0 41 1009 39 0 0 100 0 0 0 0 0 3029752 199616 690980 0 0 0 3 1004 36 0 0 100 0 0 0 0 0 3029752 199616 690980 0 0 0 4 1004 36 0 0 100 0 0 0 0 0 3029752 199616 690980 0 0 0 6 1003 33 0 0 100 0 0 0 0 0 3029752 199616 690980 0 0 0 5 1003 33 0 0 100 0 0 说明: 字段说明: Procs(进程): r: 运行队列中进程数量 b: 等待IO的进程数量 Memory(内存): swpd: 使用虚拟内存大小 free: 可用内存大小 buff: 用作缓冲的内存大小 cache: 用作缓存的内存大小 Swap: si: 每秒从交换区写到内存的大小 so: 每秒写入交换区的内存大小 IO:(现在的Linux版本块的大小为1024bytes) bi: 每秒读取的块数 bo: 每秒写入的块数 系统: in: 每秒中断数,包括时钟中断。 cs: 每秒上下文切换数。 CPU(以百分比表示): us: 用户进程执行时间(user time) sy: 系统进程执行时间(system time) id: 空闲时间(包括IO等待时间),中央处理器的空闲时间 。以百分比表示。 wa: 等待IO时间 备注: 如 果 r经常大于 4 ,且id经常少于40,表示cpu的负荷很重。如果pi,po 长期不等于0,表示内存不足。如果disk 经常不等于0, 且 在 b中的队列 大于3, 表示 io性能不好。Linux在具有高稳定性、可靠性的同时,具有很好的可伸缩性和扩展性,能够针对不同的应用和硬件环境调 整,优化出满足当前应用需要的最佳性能。因此企业在维护Linux系统、进行系统调优时,了解系统性能分析工具是至关重要的。 命令: vmstat 5 5 表示在5秒时间内进行5次采样。将得到一个数据汇总他能够反映真正的系统情况。 实例2:显示活跃和非活跃内存 命令: vmstat -a 2 5 输出: [root@localhost ~]# vmstat -a 2 5 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 0 3029752 387728 513008 0 0 0 2 3 2 0 0 100 0 0 0 0 0 3029752 387728 513076 0 0 0 0 1005 34 0 0 100 0 0 0 0 0 3029752 387728 513076 0 0 0 22 1004 36 0 0 100 0 0 0 0 0 3029752 387728 513076 0 0 0 0 1004 33 0 0 100 0 0 0 0 0 3029752 387728 513076 0 0 0 0 1003 32 0 0 100 0 0 [root@localhost ~]# 说明: 使用-a选项显示活跃和非活跃内存时,所显示的内容除增加inact和active外,其他显示内容与例子1相同。 字段说明: Memory(内存): inact: 非活跃内存大小(当使用-a选项时显示) active: 活跃的内存大小(当使用-a选项时显示) 实例3:查看系统已经fork了多少次 命令: vmstat -f 输出: [root@SCF1129 ~]# vmstat -f 12744849 forks 说明: 这个数据是从/proc/stat中的processes字段里取得的 实例4:查看内存使用的详细信息 命令: vmstat -s 输出: [root@localhost ~]# vmstat -s 4043760 total memory 1013884 used memory 513012 active memory 387728 inactive memory 3029876 free memory 199616 buffer memory 690980 swap cache 6096656 total swap 0 used swap 6096656 free swap 83587 non-nice user cpu ticks 132 nice user cpu ticks 278599 system cpu ticks 913344692 idle cpu ticks 814550 IO-wait cpu ticks 10547 IRQ cpu ticks 21261 softirq cpu ticks 0 stolen cpu ticks 310215 pages paged in 14254652 pages paged out 0 pages swapped in 0 pages swapped out 288374745 interrupts 146680577 CPU context switches 1351868832 boot time 367291 forks 说明: 这些信息的分别来自于/proc/meminfo,/proc/stat和/proc/vmstat。 实例5:查看磁盘的读/写 命令: vmstat -d 输出: [root@localhost ~]# 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 sda 33381 6455 615407 63224 2068111 1495416 28508288 15990289 0 10491 hdc 0 0 0 0 0 0 0 0 0 0 fd0 0 0 0 0 0 0 0 0 0 0 md0 0 0 0 0 0 0 0 0 0 0 说明: 这些信息主要来自于/proc/diskstats. merged:表示一次来自于合并的写/读请求,一般系统会把多个连接/邻近的读/写请求合并到一起来操作. 实例6:查看/dev/sda1磁盘的读/写 命令: 输出: [root@SCF1129 ~]# df 文件系统 1K-块 已用 可用 已用% 挂载点 /dev/sda3 1119336548 27642068 1034835500 3% /tmpfs 32978376 0 32978376 0% /dev/shm /dev/sda1 1032088 59604 920056 7% /boot [root@SCF1129 ~]# vmstat -p /dev/sda1 sda1 reads read sectors writes requested writes 18607 4249978 6 48[root@SCF1129 ~]# vmstat -p /dev/sda3 sda3 reads read sectors writes requested writes 429350 35176268 28998789 980301488[root@SCF1129 ~]# 说明: 这些信息主要来自于/proc/diskstats。 reads:来自于这个分区的读的次数。 read sectors:来自于这个分区的读扇区的次数。 writes:来自于这个分区的写的次数。 requested writes:来自于这个分区的写请求次数。 实例7:查看系统的slab信息 命令: vmstat -m 输出: [root@localhost ~]# vmstat -m Cache Num Total Size Pages ip_conntrack_expect 0 0 136 28 ip_conntrack 3 13 304 13 ip_fib_alias 11 59 64 59 ip_fib_hash 11 59 64 59 AF_VMCI 0 0 960 4 bio_map_info 100 105 1064 7 dm_mpath 0 0 1064 7 jbd_4k 0 0 4096 1 dm_uevent 0 0 2608 3 dm_tio 0 0 24 144 dm_io 0 0 48 77 scsi_cmd_cache 10 10 384 10 sgpool-128 32 32 4096 1 sgpool-64 32 32 2048 2 sgpool-32 32 32 1024 4 sgpool-16 32 32 512 8 sgpool-8 45 45 256 15 scsi_io_context 0 0 112 34 ext3_inode_cache 51080 51105 760 5 ext3_xattr 36 88 88 44 journal_handle 18 144 24 144 journal_head 56 80 96 40 revoke_table 4 202 16 202 revoke_record 0 0 32 112 uhci_urb_priv 0 0 56 67 UNIX 13 33 704 11 flow_cache 0 0 128 30 msi_cache 33 59 64 59 cfq_ioc_pool 14 90 128 30 cfq_pool 12 90 216 18 crq_pool 16 96 80 48 deadline_drq 0 0 80 48 as_arq 0 0 96 40 mqueue_inode_cache 1 4 896 4 isofs_inode_cache 0 0 608 6 hugetlbfs_inode_cache 1 7 576 7 Cache Num Total Size Pages ext2_inode_cache 0 0 720 5 ext2_xattr 0 0 88 44 dnotify_cache 0 0 40 92 dquot 0 0 256 15 eventpoll_pwq 3 53 72 53 eventpoll_epi 3 20 192 20 inotify_event_cache 0 0 40 92 inotify_watch_cache 1 53 72 53 kioctx 0 0 320 12 kiocb 0 0 256 15 fasync_cache 0 0 24 144 shmem_inode_cache 254 290 768 5 posix_timers_cache 0 0 128 30 uid_cache 0 0 128 30 ip_mrt_cache 0 0 128 30 tcp_bind_bucket 3 112 32 112 inet_peer_cache 0 0 128 30 secpath_cache 0 0 64 59 xfrm_dst_cache 0 0 384 10 ip_dst_cache 5 10 384 10 arp_cache 1 15 256 15 RAW 3 5 768 5 UDP 5 10 768 5 tw_sock_TCP 0 0 192 20 request_sock_TCP 0 0 128 30 TCP 4 5 1600 5 blkdev_ioc 14 118 64 59 blkdev_queue 20 30 1576 5 blkdev_requests 13 42 272 14 biovec-256 7 7 4096 1 biovec-128 7 8 2048 2 biovec-64 7 8 1024 4 biovec-16 7 15 256 15 biovec-4 7 59 64 59 biovec-1 23 202 16 202 bio 270 270 128 30 utrace_engine_cache 0 0 64 59 Cache Num Total Size Pages utrace_cache 0 0 64 59 sock_inode_cache 33 48 640 6 skbuff_fclone_cache 7 7 512 7 skbuff_head_cache 319 390 256 15 file_lock_cache 1 22 176 22 Acpi-Operand 4136 4248 64 59 Acpi-ParseExt 0 0 64 59 Acpi-Parse 0 0 40 92 Acpi-State 0 0 80 48 Acpi-Namespace 2871 2912 32 112 delayacct_cache 81 295 64 59 taskstats_cache 4 53 72 53 proc_inode_cache 1427 1440 592 6 sigqueue 0 0 160 24 radix_tree_node 13166 13188 536 7 bdev_cache 23 24 832 4 sysfs_dir_cache 5370 5412 88 44 mnt_cache 26 30 256 15 inode_cache 2009 2009 560 7 dentry_cache 60952 61020 216 18 filp 479 1305 256 15 names_cache 3 3 4096 1 avc_node 14 53 72 53 selinux_inode_security 994 1200 80 48 key_jar 2 20 192 20 idr_layer_cache 74 77 528 7 buffer_head 164045 164800 96 40 mm_struct 51 56 896 4 vm_area_struct 1142 1958 176 22 fs_cache 35 177 64 59 files_cache 36 55 768 5 signal_cache 72 162 832 9 sighand_cache 68 84 2112 3 task_struct 76 80 1888 2 anon_vma 458 864 24 144 pid 83 295 64 59 shared_policy_node 0 0 48 77 Cache Num Total Size Pages numa_policy 37 144 24 144 size-131072(DMA) 0 0 131072 1 size-131072 0 0 131072 1 size-65536(DMA) 0 0 65536 1 size-65536 1 1 65536 1 size-32768(DMA) 0 0 32768 1 size-32768 2 2 32768 1 size-16384(DMA) 0 0 16384 1 size-16384 5 5 16384 1 size-8192(DMA) 0 0 8192 1 size-8192 7 7 8192 1 size-4096(DMA) 0 0 4096 1 size-4096 110 111 4096 1 size-2048(DMA) 0 0 2048 2 size-2048 602 602 2048 2 size-1024(DMA) 0 0 1024 4 size-1024 344 352 1024 4 size-512(DMA) 0 0 512 8 size-512 433 480 512 8 size-256(DMA) 0 0 256 15 size-256 1139 1155 256 15 size-128(DMA) 0 0 128 30 size-64(DMA) 0 0 64 59 size-64 5639 5782 64 59 size-32(DMA) 0 0 32 112 size-128 801 930 128 30 size-32 3005 3024 32 112 kmem_cache 137 137 2688 1 这组信息来自于/proc/slabinfo。 slab:由于内核会有许多小对象,这些对象构造销毁十分频繁,比如i-node,dentry,这些对象如果每次构建的时候就向内存要一个页(4kb),而其实只有几个字节,这样就会非常浪费,为了解决这个问题,就引入了一种新的机制来处理在同一个页框中如何分配小存储区,而slab可以对小对象进行分配,这样就不用为每一个对象分配页框,从而节省了空间,内核对一些小对象创建析构很频繁,slab对这些小对象进行缓冲,可以重复利用,减少内存分配次数。 十六 free命令简介 free命令可以显示Linux系统中空闲的、已用的物理内存及swap内存,及被内核使用的buffer。在Linux系统监控的工具中,free命令是最经常使用的命令之一。 1.命令格式: free [参数] 2.命令功能: free 命令显示系统使用和空闲的内存情况,包括物理内存、交互区内存(swap)和内核缓冲区内存。共享内存将被忽略 3.命令参数: -b 以Byte为单位显示内存使用情况。 -k 以KB为单位显示内存使用情况。 -m 以MB为单位显示内存使用情况。 -g 以GB为单位显示内存使用情况。 -o 不显示缓冲区调节列。 -s<间隔秒数> 持续观察内存使用状况。 -t 显示内存总和列。 -V 显示版本信息。 4.使用实例: 实例1:显示内存使用情况 命令: free free -g free -m 输出: [root@SF1150 service]# free total used free shared buffers cached Mem: 32940112 30841684 2098428 0 4545340 11363424 -/+ buffers/cache: 14932920 18007192 Swap: 32764556 1944984 30819572 [root@SF1150 service]# free -g total used free shared buffers cached Mem: 31 29 2 0 4 10 -/+ buffers/cache: 14 17 Swap: 31 1 29 [root@SF1150 service]# free -m total used free shared buffers cached Mem: 32168 30119 2048 0 4438 11097 -/+ buffers/cache: 14583 17584 Swap: 31996 1899 30097 说明: 下面是对这些数值的解释: total:总计物理内存的大小。 used:已使用多大。 free:可用有多少。 Shared:多个进程共享的内存总额。 Buffers/cached:磁盘缓存的大小。 第三行(-/+ buffers/cached): used:已使用多大。 free:可用有多少。 第四行是交换分区SWAP的,也就是我们通常所说的虚拟内存。 区 别:第二行(mem)的used/free与第三行(-/+ buffers/cache) used/free的区别。 这两个的区别在于使用的角度来 看,第一行是从OS的角度来看,因为对于OS,buffers/cached 都是属于被使用,所以他的可用内存是2098428KB,已用内存是 30841684KB,其中包括,内核(OS)使用+Application(X, oracle,etc)使用的+buffers+cached. 第三行所指的是从应用程序角度来看,对于应用程序来说,buffers/cached 是等于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。 所以从应用程序的角度来说,可用内存=系统free memory+buffers+cached。 如本机情况的可用内存为: 18007156=2098428KB+4545340KB+11363424KB 接下来解释什么时候内存会被交换,以及按什么方交换。 当可用内存少于额定值的时候,就会开会进行交换.如何看额定值: 命令: cat /proc/meminfo 输出: [root@SF1150 service]# cat /proc/meminfo MemTotal: 32940112 kB MemFree: 2096700 kB Buffers: 4545340 kB Cached: 11364056 kB SwapCached: 1896080 kB Active: 22739776 kB Inactive: 7427836 kB HighTotal: 0 kB HighFree: 0 kB LowTotal: 32940112 kB LowFree: 2096700 kB SwapTotal: 32764556 kB SwapFree: 30819572 kB Dirty: 164 kB Writeback: 0 kB AnonPages: 14153592 kB Mapped: 20748 kB Slab: 590232 kB PageTables: 34200 kB NFS_Unstable: 0 kB Bounce: 0 kB CommitLimit: 49234612 kB Committed_AS: 23247544 kB VmallocTotal: 34359738367 kB VmallocUsed: 278840 kB VmallocChunk: 34359459371 kB HugePages_Total: 0HugePages_Free: 0HugePages_Rsvd: 0Hugepagesize: 2048 kB 交换将通过三个途径来减少系统中使用的物理页面的个数: 1.减少缓冲与页面cache的大小, 2.将系统V类型的内存页面交换出去, 3.换出或者丢弃页面。(Application 占用的内存页,也就是物理内存不足)。 事实上,少量地使用swap是不是影响到系统性能的。 那buffers和cached都是缓存,两者有什么区别呢? 为 了提高磁盘存取效率, Linux做了一些精心的设计, 除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换), 还采取了两种 主要Cache方式:Buffer Cache和Page Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache有效缩短 了 I/O系统调用(比如read,write,getdents)的时间。 磁盘的操作有逻辑级(文件系统)和物理级(磁盘块),这两种Cache就是分别缓存逻辑和物理级数据的。 Page cache 实际上是针对文件系统的,是文件的缓存,在文件层面上的数据会缓存到page cache。文件的逻辑层需要映射到实际的物理磁盘,这种映射关系由文件系 统来完成。当page cache的数据需要刷新时,page cache中的数据交给buffer cache,因为Buffer Cache就是缓存 磁盘块的。但是这种处理在2.6版本的内核之后就变的很简单了,没有真正意义上的cache操作。 Buffer cache是针对磁盘块的缓存,也就是在没有文件系统的情况下,直接对磁盘进行操作的数据会缓存到buffer cache中,例如,文件系统的元数据都会缓存到buffer cache中。 简单说来,page cache用来缓存文件数据,buffer cache用来缓存磁盘数据。在有文件系统的情况下,对文件操作,那么数据会缓存到page cache,如果直接采用dd等工具对磁盘进行读写,那么数据会缓存到buffer cache。 所以我们看linux,只要不用swap的交换空间,就不用担心自己的内存太少.如果常常swap用很多,可能你就要考虑加物理内存了.这也是linux看内存是否够用的标准. 如果是应用服务器的话,一般只看第二行,+buffers/cache,即对应用程序来说free的内存太少了,也是该考虑优化程序或加内存了。 实例2:以总和的形式显示内存的使用信息 命令: free -t 输出: [root@SF1150 service]# free -t total used free shared buffers cached Mem: 32940112 30845024 2095088 0 4545340 11364324 -/+ buffers/cache: 14935360 18004752Swap: 32764556 1944984 30819572Total: 65704668 32790008 32914660 说明: 实例3:周期性的查询内存使用信息 命令: free -s 10 输出: [root@SF1150 service]# free -s 10 total used free shared buffers cached Mem: 32940112 30844528 2095584 0 4545340 11364380 -/+ buffers/cache: 14934808 18005304Swap: 32764556 1944984 30819572 total used free shared buffers cached Mem: 32940112 30843932 2096180 0 4545340 11364388 -/+ buffers/cache: 14934204 18005908Swap: 32764556 1944984 30819572 说明: 每10s 执行一次命令 十七 top 命令简介 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。下面详细介绍它的使用方法。top是 一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止.比较准确的说,top命令提供 了实时的对系统处理器的状态监视.它将显示系统中CPU最“敏感”的任务列表.该命令可以按CPU使用.内存使用和执行时间对任务进行排序;而且该命令的 很多特性都可以通过交互式命令或者在个人定制文件中进行设定. 1.命令格式: top [参数] 2.命令功能: 显示当前系统正在执行的进程的相关信息,包括进程ID、内存占用率、CPU占用率等 3.命令参数: -b 批处理 -c 显示完整的治命令 -I 忽略失效过程 -s 保密模式 -S 累积模式 -i<时间> 设置间隔时间 -u<用户名> 指定用户名 -p<进程号> 指定进程 -n<次数> 循环显示的次数 4.使用实例: 实例1:显示进程信息 命令: top 输出: [root@TG1704 log]# top top - 14:06:23 up 70 days, 16:44, 2 users, load average: 1.25, 1.32, 1.35 Tasks: 206 total, 1 running, 205 sleeping, 0 stopped, 0 zombie Cpu(s): 5.9%us, 3.4%sy, 0.0%ni, 90.4%id, 0.0%wa, 0.0%hi, 0.2%si, 0.0%st Mem: 32949016k total, 14411180k used, 18537836k free, 169884k buffers Swap: 32764556k total, 0k used, 32764556k free, 3612636k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 28894 root 22 0 1501m 405m 10m S 52.2 1.3 2534:16 java 18249 root 18 0 3201m 1.9g 11m S 35.9 6.0 569:39.41 java 2808 root 25 0 3333m 1.0g 11m S 24.3 3.1 526:51.85 java 25668 root 23 0 3180m 704m 11m S 14.0 2.2 360:44.53 java 574 root 25 0 3168m 611m 10m S 12.6 1.9 556:59.63 java 1599 root 20 0 3237m 1.9g 11m S 12.3 6.2 262:01.14 java 1008 root 21 0 3147m 842m 10m S 0.3 2.6 4:31.08 java 13823 root 23 0 3031m 2.1g 10m S 0.3 6.8 176:57.34 java 28218 root 15 0 12760 1168 808 R 0.3 0.0 0:01.43 top 29062 root 20 0 1241m 227m 10m S 0.3 0.7 2:07.32 java 1 root 15 0 10368 684 572 S 0.0 0.0 1:30.85 init 2 root RT -5 0 0 0 S 0.0 0.0 0:01.01 migration/0 3 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0 4 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/0 5 root RT -5 0 0 0 S 0.0 0.0 0:00.80 migration/1 6 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/1 7 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/1 8 root RT -5 0 0 0 S 0.0 0.0 0:20.59 migration/2 9 root 34 19 0 0 0 S 0.0 0.0 0:00.09 ksoftirqd/2 10 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/2 11 root RT -5 0 0 0 S 0.0 0.0 0:23.66 migration/3 12 root 34 19 0 0 0 S 0.0 0.0 0:00.03 ksoftirqd/3 13 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/3 14 root RT -5 0 0 0 S 0.0 0.0 0:20.29 migration/4 15 root 34 19 0 0 0 S 0.0 0.0 0:00.07 ksoftirqd/4 16 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/4 17 root RT -5 0 0 0 S 0.0 0.0 0:23.07 migration/5 18 root 34 19 0 0 0 S 0.0 0.0 0:00.07 ksoftirqd/5 19 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/5 20 root RT -5 0 0 0 S 0.0 0.0 0:17.16 migration/6 21 root 34 19 0 0 0 S 0.0 0.0 0:00.05 ksoftirqd/6 22 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/6 23 root RT -5 0 0 0 S 0.0 0.0 0:58.28 migration/7 说明: 统计信息区: 前五行是当前系统情况整体的统计信息区。下面我们看每一行信息的具体意义。 第一行,任务队列信息,同 uptime 命令的执行结果,具体参数说明情况如下: 14:06:23 — 当前系统时间 up 70 days, 16:44 — 系统已经运行了70天16小时44分钟(在这期间系统没有重启过的吆!) 2 users — 当前有2个用户登录系统 load average: 1.15, 1.42, 1.44 — load average后面的三个数分别是1分钟、5分钟、15分钟的负载情况。 load average数据是每隔5秒钟检查一次活跃的进程数,然后按特定算法计算出的数值。如果这个数除以逻辑CPU的数量,结果高于5的时候就表明系统在超负荷运转了。 第二行,Tasks — 任务(进程),具体信息说明如下: 系统现在共有206个进程,其中处于运行中的有1个,205个在休眠(sleep),stoped状态的有0个,zombie状态(僵尸)的有0个。 第三行,cpu状态信息,具体属性说明如下: 5.9%us — 用户空间占用CPU的百分比。 3.4% sy — 内核空间占用CPU的百分比。 0.0% ni — 改变过优先级的进程占用CPU的百分比 90.4% id — 空闲CPU百分比 0.0% wa — IO等待占用CPU的百分比 0.0% hi — 硬中断(Hardware IRQ)占用CPU的百分比 0.2% si — 软中断(Software Interrupts)占用CPU的百分比 备注:在这里CPU的使用比率和windows概念不同,需要理解linux系统用户空间和内核空间的相关知识! 第四行,内存状态,具体信息如下: 32949016k total — 物理内存总量(32GB) 14411180k used — 使用中的内存总量(14GB) 18537836k free — 空闲内存总量(18GB) 169884k buffers — 缓存的内存量 (169M) 第五行,swap交换分区信息,具体信息说明如下: 32764556k total — 交换区总量(32GB) 0k used — 使用的交换区总量(0K) 32764556k free — 空闲交换区总量(32GB) 3612636k cached — 缓冲的交换区总量(3.6GB) 备注: 第 四行中使用中的内存总量(used)指的是现在系统内核控制的内存数,空闲内存总量(free)是内核还未纳入其管控范围的数量。纳入内核管理的内存不见 得都在使用中,还包括过去使用过的现在可以被重复利用的内存,内核并不把这些可被重新使用的内存交还到free中去,因此在linux上free内存会越 来越少,但不用为此担心。 如果出于习惯去计算可用内存数,这里有个近似的计算公式:第四行的free + 第四行的buffers + 第五行的cached,按这个公式此台服务器的可用内存:18537836k +169884k +3612636k = 22GB左右。 对于内存监控,在top里我们要时刻监控第五行swap交换分区的used,如果这个数值在不断的变化,说明内核在不断进行内存和swap的数据交换,这是真正的内存不够用了。 第六行,空行。 第七行以下:各进程(任务)的状态监控,项目列信息说明如下: PID — 进程id USER — 进程所有者 PR — 进程优先级 NI — nice值。负值表示高优先级,正值表示低优先级 VIRT — 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES RES — 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA SHR — 共享内存大小,单位kb S — 进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程 %CPU — 上次更新到现在的CPU时间占用百分比 %MEM — 进程使用的物理内存百分比 TIME+ — 进程使用的CPU时间总计,单位1/100秒 COMMAND — 进程名称(命令名/命令行) 其他使用技巧: 1.多U多核CPU监控 在top基本视图中,按键盘数字“1”,可监控每个逻辑CPU的状况: 观察上图,服务器有16个逻辑CPU,实际上是4个物理CPU。再按数字键1,就会返回到top基本视图界面。 2.高亮显示当前运行进程 敲击键盘“b”(打开/关闭加亮效果),top的视图变化如下: 我们发现进程id为2570的“top”进程被加亮了,top进程就是视图第二行显示的唯一的运行态(runing)的那个进程,可以通过敲击“y”键关闭或打开运行态进程的加亮效果。 3.进程字段排序 默认进入top时,各进程是按照CPU的占用量来排序的,在下图中进程ID为28894的java进程排在第一(cpu占用142%),进程ID为574的java进程排在第二(cpu占用16%)。 敲击键盘“x”(打开/关闭排序列的加亮效果),top的视图变化如下: 可以看到,top默认的排序列是“%CPU”。 4. 通过”shift + >”或”shift + <”可以向右或左改变排序列 下图是按一次”shift + >”的效果图,视图现在已经按照%MEM来排序。 实例2:显示 完整命令 命令: top -c 输出: 说明: 实例3:以批处理模式显示程序信息 命令: top -b 输出: 说明: 实例4:以累积模式显示程序信息 命令: top -S 输出: 说明: 实例5:设置信息更新次数 命令: top -n 2 输出: 说明: 表示更新两次后终止更新显示 实例6:设置信息更新时间 命令: top -d 3 输出: 说明: 表示更新周期为3秒 实例7:显示指定的进程信息 命令: top -p 574 输出: 说明: 5.top交互命令 在top 命令执行过程中可以使用的一些交互命令。这些命令都是单字母的,如果在命令行中使用了s 选项, 其中一些命令可能会被屏蔽。 h 显示帮助画面,给出一些简短的命令总结说明 k 终止一个进程。 i 忽略闲置和僵死进程。这是一个开关式命令。 q 退出程序 r 重新安排一个进程的优先级别 S 切换到累计模式 s 改变两次刷新之间的延迟时间(单位为s),如果有小数,就换算成m s。输入0值则系统将不断刷新,默认值是5 s f或者F 从当前显示中添加或者删除项目 o或者O 改变显示项目的顺序 l 切换显示平均负载和启动时间信息 m 切换显示内存信息 t 切换显示进程和CPU状态信息 c 切换显示命令名称和完整命令行 M 根据驻留内存大小进行排序 P 根据CPU使用百分比大小进行排序 T 根据时间/累计时间进行排序 W 将当前设置写入~/.toprc文件中 十八 killall 命令简介 Linux 系统中的killall命令用于杀死指定名字的进程(kill processes by name)。我们可以使用kill命令杀死指定进程PID的进 程,如果要找到我们需要杀死的进程,我们还需要在之前使用ps等命令再配合grep来查找进程,而killall把这两个过程合二为一,是一个很好用的命 令。 1.命令格式: killall[参数][进程名] 2.命令功能: 用来结束同名的的所有进程 3.命令参数: -Z 只杀死拥有scontext 的进程 -e 要求匹配进程名称 -I 忽略小写 -g 杀死进程组而不是进程 -i 交互模式,杀死进程前先询问用户 -l 列出所有的已知信号名称 -q 不输出警告信息 -s 发送指定的信号 -v 报告信号是否成功发送 -w 等待进程死亡 --help 显示帮助信息 --version 显示版本显示 4.使用实例: 实例1:杀死所有同名进程 命令: killall vi 输出: [root@localhost ~]# ps -ef|grep vi root 17581 17398 0 17:51 pts/0 00:00:00 vi test.txt root 17611 17582 0 17:51 pts/1 00:00:00 grep vi [root@localhost ~]# ps -ef|grep vi root 17581 17398 0 17:51 pts/0 00:00:00 vi test.txt root 17640 17612 0 17:51 pts/2 00:00:00 vi test.log root 17642 17582 0 17:51 pts/1 00:00:00 grep vi [root@localhost ~]# killall vi [root@localhost ~]# ps -ef|grep vi root 17645 17582 0 17:52 pts/1 00:00:00 grep vi 实例2:向进程发送指定信号 命令: 后台运行程序:vi & 杀死 vi进程:killall -TERM vi 或者 killall -KILL vi 输出: [root@localhost ~]# vi & [1] 17646[root@localhost ~]# killall -TERM vi [1]+ Stopped vi [root@localhost ~]# vi & [2] 17648[root@localhost ~]# ps -ef|grep vi root 17646 17582 0 17:54 pts/1 00:00:00 vi root 17648 17582 0 17:54 pts/1 00:00:00 vi root 17650 17582 0 17:55 pts/1 00:00:00 grep vi [2]+ Stopped vi [root@localhost ~]# killall -TERM vi [root@localhost ~]# ps -ef|grep vi root 17646 17582 0 17:54 pts/1 00:00:00 vi root 17648 17582 0 17:54 pts/1 00:00:00 vi root 17653 17582 0 17:55 pts/1 00:00:00 grep vi [root@localhost ~]# killall -KILL vi [1]- 已杀死 vi [2]+ 已杀死 vi [root@localhost ~]# ps -ef|grep vi root 17656 17582 0 17:56 pts/1 00:00:00 grep vi 实例3:把所有的登录后的shell给杀掉 命令: killall -9 bash 输出: [root@localhost ~]# w 18:01:03 up 41 days, 18:53, 3 users, load average: 0.00, 0.00, 0.00USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 10.2.0.68 14:58 9:52 0.10s 0.10s -bash root pts/1 10.2.0.68 17:51 0.00s 0.02s 0.00s w root pts/2 10.2.0.68 17:51 9:24 0.01s 0.01s -bash [root@localhost ~]# killall -9 bash [root@localhost ~]# w 18:01:48 up 41 days, 18:54, 1 user, load average: 0.07, 0.02, 0.00USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 10.2.0.68 18:01 0.00s 0.01s 0.00s w 说明: 运行命令:killall -9 bash 后,所有bash都会被卡掉了,所以当前所有连接丢失了。需要重新连接并登录。