from:风雷的技术天地
在每一个基本的系统中,都包含有各种各样的基本进程,用于检查系统服务,和操作系统通信等等。进程和系统的性能表现有着很大的关系,因此,一个系统 管理者应该清楚了解当前系统中正在运行什么东西,有什么资源可用等等,只有这样,你才能够调整配置,例如,禁止不需要的进程,打开必须的监护程序以及将你 的内核调整到最优化,最后得到一个最适合自己使用的最好的系统。Ubuntu是一个为大众设计的系统,这也就决定了其系统设置的大众化,换句话说,臃肿 化。为了适应兼容性而支持的很多东西,我们其实不一定需要。在这里,笔者试图讲解一些通过调整内核参数,shell参数以及特定应用的设置来优化系统的方 法,供大家参考。需要注意的是,不同的ubuntu系统有着不同的启动脚本,并有着不同的运行进程,这里我只能以7.04系统为基础来讲解。其实自己学会 对进程进行追踪查看是非常重要的,只有这样你才能在不同的系统中都游刃有余。另外,如果要更加深入调整系统,那么自己编译一个属于自己的系统是最合适的, 本文没有牵涉这么深入的东西。如果你对自己编译linux系统感兴趣,可以参考这篇文章和这篇文章。
本文假设你有一点点基本使用linux的基础,所以很多东西只是讲一个概念性的大纲,想深入了解的话,网络上有很多文章。如果你是系统高手,基本就
可以不用看本文了,你会觉得很简单,如果你是连ps,who
-r都不知道的新手,建议你还是先放google搜索一些入门文章,并亲自使用linux一周以上,再回过头来看这篇文章。本文很大程度上参考了Ubuntu Performance Guides,篇幅较长,故分两页发出。
基础知识
理解进程
进程简介
刚才就几次提到进程,那么,我们应该怎么理解这个词语?广泛得说,所有在系统中运行的,用于执行各种各样任务的,都是一个进程,只不过根据具体执行任务的不同可以有所区分,例如,用于管理和维持操作系统运行的属于系统进程,而用于处理用户需求的就是用户进程。
进程并不是一个独立的概念,它是相互交互的,很多进程都为其他进程提供服务,或者携手共同完成某一个功能。这些服务中,有一些对于系统的运作是非常 关键的,例如X-Windows服务。绝大多数的系统进程都是服务性质的进程,而绝大多数用户进程则是应用程序类进程。应用程序,比如你现在在使用的 FireFox(或者其它,估计FF最多吧)通常是由一个或多个满足用户需求的进程组成。总的来说,服务的开启和关闭是基于系统需求的,而应用程序的开启 和关闭,则是基于用户的需求的。
我们上面说的这些进程阿,服务阿啥的,其实之间的区分并不是很明显,举个例子,Gnome的桌面系统就是由各种程序和进程组成,而他们不仅提供其它程序需要的服务,还可以支持用户的需求。GDE完全可以被称为是程序,进程,应用和服务的集合体,这不会产生任何冲突。
当然,我们还是要稍微做一下区分,后面才方便继续讲解。现在就统一一下,进程表示任何可以产生运行中的进程标志符的东西,程序则表示能产生进程的可执行文件。用户能够直接使用应用程序,而操作系统才使用服务。
进程基本操作
在你的机器上,唯一能够消耗你资源的就是正在运行的进程。如果当你发现自己的系统突然很慢,运行不正常时,通常只有两个可能,一种是某些进程运行异常,另一种就是某些进程所消耗的资源已经大于你所拥有的资源。
当然,想看看什么东西正在你机器上运行其实很简单,使用ps -aux或者top命令即可,这些东西资料很多,我就不多说了,实在不行man top或者man ps吧。当然,对于初学者来说最方便的还是利用图形化界面的系统监视器,如图:
所有信息都尽显眼前。注意,在系统监视器中,你不仅能看到进程运行情况,还能看到磁盘使用,CPU使用等很多有价值的信息,这些信息是接下来的部分可能用到的。
ok,现在我们知道,如果系统异常,如何去确定是什么进程异常了。但是接下来该怎么处理呢?无论是命令行还是图形界面显示,你都可以看到每一个进程 都有属于自己的ID,也就是PID。它们都是进程的句柄,而不是表示真实的进程。这有什么区别?对于一个拥有多线程的进程来讲,可以让所有的线程都拥有同 一个句柄,也可以让每一个线程都拥有一个句柄。太专业了?恩,通俗来讲,这就相当于……进程的身份证,我们通过它来标志进程。这个东西在ubuntu中默 认可以有32768个不同的PID,每有一个新的进程,就分配一个当前未用的PID给它。
好了,让我们找到那个让我们系统变慢的该死的罪魁祸首,看看它的PID,然后用kill PID命令来关闭它。等等,你确定就是这个进程影响了你的系统?你确信没有错杀好人?好吧,其实可以先用kill -stop PID命令来暂停一个进程,看看没有了它,我们的系统是否正常。如果发现了冤假错案,没关系,kill -cont PID能让进程继续工作。
除了直接使用kill PID之外,我们还有更进一步的kill进程的办法。kill PID仅仅是发出一个TERM信号,然后进程能捕捉这个信号,开始释放资源,关闭程序,这不是一下子就完成的,因此在关闭程序之前,你可以结束打开的文件 和完成正在做的任务。但是这导致一个问题,假如进程正在进行作业而且不能中断,那么进程可以忽略这个SIGTERM信号,而且如果进程失去响应了怎么办? 别急,我们还可以试一试kill -1 PID命令,这个命令发送的是hang up信号,含义是“中止信号”,它告诉进程,终端已经被kill了。但这个信号同样只被运行良好的进程所拦截。假设这两种方式都无法结束进程,那么只能使 用kill -9 PID了。这个命令发送的是真正的kill信号,对于这个信号,进程是不能忽略的。 这是一个“我不管您在做什么,立刻停止”的信号,也就是说进程立刻被终止,不实施清理操作。
信号是用来与守护程序和进程通信的。任何活动任务都是一个进程,而守护程序是等待对某些事件做出反应或者按照日程安排执行任务的后台服务。一个程序 必须有建在其中的信号处理程序用于捕获和应答信号。在LINUX中的signal参考指南解释了各种不同信号和这些信号的用途。常用的信号除了上面介绍的 以外,还有INT,CHLD等。
进程操作进阶
当然,仅仅了解上面的知识,对于对进程的理解,还是不够的。下面,我会介绍更多的关于进程的知识。
首先,我们需要知道,并不是所有的进程都会被动态分配PID,至少有两个进程不会,就是kernel和init。kernel进程的PID是0, 一直是0,而且你无法从ps,top这些命令中看见它,当然,也无法用kill命令来终止它。init进程是主父进程,什么意思呢?每一个进程都需要一个 父进程来监管它,父进程的作用就是接受子进程的返回值和状态值。而如果任何一个进程的父进程被终止,init就会成为它的父进程。init进程的PID固 定是1,从理论上讲,你也可以终止它,但是千万不要试图这样做,因为它是用来清除呆死进程的,一旦将其kill,系统最终将崩溃。
除了他俩,还有一些进程是你不应该kill的,包括Zombies,/O Bound—A和Interception。事实上,我们很少解除这几个进程,普通用户也没必要接触它们,因此,在这里我不会详细解释它们的用途,有兴趣的朋友可以自己google。
其它进程,在保证系统本身不崩溃的情况下,一旦有异常你都可以试图去kill,不过要知道,kill命令只作用一次,也就是说,假如,我是说假如, 这个进程在被kill后又重新自启动,那么你不得不再运行一次kill,这样循环。当然,此时,你就不能一直陪它kill下去了,追踪查看其自启动的根源 才是正确的做法。你觉得这太麻烦了?好吧,还有一个懒办法,就是看看这个进程的名字,然后用kill name来阻止它。我知道很多地方都有介绍kill -9 -1这个命令,但是你需要知道,这个命令会kill你所有的进程,包括界面进程以及终端。而且如果你是root权限……它会连所有系统应用都一起 kill,然后,你的系统就将崩溃。所以用这个命令,你还不如直接按下你的重新启动按键,还更加省心……
进程的启动
我们能够查看正在运行的进程,查看进程的具体信息,但是,我们能不能知道它们是怎样开始的?难道是和孙猴子一样从石头里面崩出来的?你也许会看它的 PPID,恭喜你,摸着点门道了,but……你会发现大多数进程的PPID都是1,init进程。而事实上,进程的启动原因可能是很多种,启动脚本,设备 配置脚本,网络变化,甚至是任务日程等等等等。因此,我们需要探查进程启动的秘密。
启动脚本
看看你的/etc/init.d/文件夹,你会发现其中包含了很多用于启动和停止系统服务的脚本,而它们,都将以链接形式存在于/etc/rc0.d, /etc/rc1.d以及类似目录中。例如,在/etc/rc1.d执行命令ls -l,你会看见如下结果:
lrwxrwxrwx 1 root root 13 2007-04-21 22:01 K01gdm -> ../init.d/gdm*
lrwxrwxrwx 1 root root 17 2007-04-21 21:59 K01usplash -> ../init.d/usplash*
lrwxrwxrwx 1 root root 17 2007-04-23 14:54 K09apache2 -> ../init.d/apache2*
lrwxrwxrwx 1 root root 17 2007-04-21 21:58 K11anacron -> ../init.d/anacron*
lrwxrwxrwx 1 root root 13 2007-04-21 21:58 K11atd -> ../init.d/atd*
lrwxrwxrwx 1 root root 14 2007-04-21 21:58 K11cron -> ../init.d/cron*
lrwxrwxrwx 1 root root 16 2007-04-21 21:59 K19cupsys -> ../init.d/cupsys*
lrwxrwxrwx 1 root root 15 2007-04-21 21:59 K19hplip -> ../init.d/hplip*
lrwxrwxrwx 1 root root 22 2007-04-21 21:58 K20acpi-support -> ../init.d/acpi-su
……………………………..
如果你的运行级别是1,init就会进入/etc/rc1.d并调用其中的链接符号,也就是启动相应的进程,以此类推。如果想知道目前系统的运行级别,最简单的办法就是用who -r命令,会显示:
run-level 2 2007-05-04 10:09
这就表示我目前的系统运行级别是2。在boot的时候,所有/etc/rc2.d目录下对应的init脚本的输出都会存到/var/log/messages这个文件中,你可以根据它来判断哪些进程被执行了。
启动设备
udev进程用于动态管理设备的配置,这个进程监视和管理即插即用设备。一旦这些设备生效,存在于/etc/udev/rules.d/文件夹下的哪些脚本就会生效,调用不同的应用程序。
shell启动脚本
每当你登入登出系统,或者是启动了一个新的shell之后,都会执行配置脚本,每一个脚本都会启动进程。对于笔者使用的ubuntu而言,默认的shell是bash,相应的配置脚本如下:
/etc/profile:每次登录shel都会执行,全局配置文件
$HOME/.bash_profile:基于用户自定义,每一个用户都可以有自己的登录脚本
/etc/bash.bashrc:交互式非登录全局配置脚本,这个文件在.bashrc中会调用
$HOME/.bashrc:交互式非登录用户自定义的配置脚本,也是我们大多数时候需要修改的文件
/etc/bash.logout:不一定存在,如果存在的话,每次用户登出时调用它
$HOME/.bash_logout:同上,只不过是用户自定义的
我们可以注意到,上面这些脚本大致可以分为两类,一类是用于登入登出的,一类是交互式。它们有什么区别么?简单得说,每当你登入你的系统时,登入脚本和交互式脚本都会执行。而当你打开一个终端窗口时,只有交互式脚本才会被执行。
桌面脚本
linux喊了一万年的要易用,要占领桌面系统,简单说来,就是希望有一个漂亮易用的图形界面。大多数人的大多数应用还是基于图形界面的,因此,除了上面介绍的shell脚本,我们还应该关注一下图形界面脚本。
在启动图形界面的时候,首先会运行/etc/X11/xinit/xinitrc, /etc/X11/Xsession和/etc/X11/xinit/xserverrc这三个脚本。它们会设置相应的环境变量,并在最开始启动时运行应 用程序。在X-Windows启动完毕之后,就是Gnome的启动,它会调用很多程序,产生很多进程,也就是类似于Windwos下的开机自启动程序。到 底是哪些进程呢?我们可以从存放系统级别启动脚本的/etc/X11/gdm/目录,用于用户自定义启动程序的$HOME/.gnomerc文件,或者通 过系统>首选项>会话菜单来查看:
好,问题来了。既然有这么多的地方都能进行开机自启动程序的添加,难道它们都是完全一样的么?这样有什么意义呢?
恩,它们当然不是完全一样的,而是各司其职。
如果你希望自启动程序是作用于使用X-Windwos的所有人,那么你要修改的地方就是/etc/X11/Xsession,或者把脚本放置到 /etc/X11/Xsession.d/目录下。如果仅仅是希望对你自己使用X-Windwos时生效,则修改$HOME/.xsession即可。
如果你希望自启动程序是作用于使用Gnome的所有人,那么你要修改的地方就是/etc/X11/gdm/PostSession /Default,它会仅仅对Gnome使用者起作用,而不是KDE使用者或者其他。或者把脚本放置到/etc/X11/Xsession.d/目录下。 如果仅仅是希望对你自己使用Gnome时生效,则修改$HOME/.gnomerc即可。
小知识:Gnome和X-Windows的区别?
X-Windows是图形界面底层,提供的功能是在屏幕上构造方块(窗口),然后画出里面的元素,但不提供交互式操作。gnome,kde这些都是基于 X-Windows的不同风格的界面,属于桌面环境。怎么理解这个桌面环境呢?基本的意思是指“ Mac OS 和 Windows的图形界面有,而X没有却应该有的东西”。通常是一组有着共同外观和操作感的应用程序,和程序库,以及创建新的应用程序的方法。事实上你可 以同时有两个文件管理器,两个面板,等等,并不冲突,因为它们都是属于应用。
桌面应用
插入光盘,就会自动弹出文件浏览器,插入数码相机,就会自动弹出照片导入程序,等等。这些应用是怎么实现的?如何禁止程序的自动执行?如何自定义在即插即用设备被认出以后的启动程序?
答案就在 系统>首选项>可移动驱动器和介质 里。打开它,你就明白怎么回事了,这东西实在太简单,我就不多说了。
只有一点补充的,就是如果你要使用一款新的即插即用设备,而这种设备在可移动驱动器和介质选项中没有,那么此时你就必须求助于udev了。至于udev的
具体知识,讲起来又是一篇文章,所以就不讲了,还是那句话,放google~~^_^。
评估资源
刚才我们一直再说资源资源,当然,系统资源的使用情况直接决定了你系统当前的性能。那么,我们如何才能对自己系统的性能做一个基础评估呢?在评估之 前,我们需要对资源做一个更加详细的解释。所谓的资源,都是指进程所能使用的资源,包括了CPU处理能力,磁盘空间,磁盘I/O,RAM使用情况,显存使 用情况,网络流量等。而这些资源的当前使用状态,我们都是有办法自己获取的。
系统监视器和proc
正如大多数linuxer所知道的那样,/proc挂载了一个虚拟文件系统,专门用于列出当前系统资源情况和正在运行的进程。在这里,所有的东西都 是动态的,随时可能改变的。最关键的是,/proc目录下有很多以数字命名的文件夹,这些文件夹都对应了某一个响应PID的进程,内含进程的很多信息,包 括使用命令,运行环境等。还有一些不是以数字命名的文件夹,那是设备驱动和内核的情况,例如,cpuinfo这个文件就提供了系统中cpu的相关信息。
当然,你可能觉得从这里面获取系统资源信息实在太麻烦了,你会抱怨,拜托,我仅仅是初学者,有没有直观的办法?sure!刚才我们说的CPU处理能 力,磁盘可使用空间,内存情况,网络情况,你统统都可以从系统监视器中看到。监视器以曲线图的形式把情况呈现在你的面前,你可以根据它评估系统的运行是否 良好,有没有异常的发生。
其它
那么,监视器就是万能的?no,至少显存和磁盘I/O的情况它就无法呈现给你。在实际使用中,可能会发生你的系统中有好几个磁盘,但某个磁盘的I /O通道堵塞会导致系统性能下降的现象。有什么办法来确定是哪个通道在搞鬼呢?这里,iostat就可以帮助我们了。这是一个小的,评估I/O性能的软 件,通过sudo apt-get install sysstat来获得它。安装完后直接输入iostat命令,就会显示:
avg-cpu: %user %nice %system %iowait %steal %idle
7.18 0.08 3.58 2.34 0.00 86.83Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
sda 16.63 0.19 0.16 1046 877
sdb 0.01 0.00 0.00 0 0
包括基本CPU负荷以及I/O情况。我机器上磁盘数量较少,所以结果比较少。好了,光知道这些数据是没用的,我们需要做的是根据这些数据来分析系统 负荷。我们假设现在sdb设备数据量不正常,好,接下来就用mount命令来看看,是哪个文件挂载到sda下的,得出文件路径名后,用lsof来查看这个 目录下打开了哪些文件,哪些进程,以及相关信息。这样,就能有的放矢得来寻找到让你磁盘I/O情况异常的东西。
之后谈谈显存的情况读取。首先谈谈我们为什么要关注显存,显存的容量会直接影响你的显示情况,例如,如果你只有一块老的,256K显存的显卡,那么 屏幕的显示最高也就是支持到800×600,16位色深。 如今,大部分的高端显卡都拥有至少128MB的显存,能够轻松在32位色深的情况下上到1280×1024的分辨率。更多的显存同样对游戏以及桌面的逼真 度有益,因为可以由显存的一部分来保持主画面的显示,其它空余下来的显存就可以用来体现各种层面的仿真元素。我们可以通过lspci –v 命令来显示所有PCI卡,包括显卡的存储关联情况。这个命令有什么用呢?当你遇到硬件问题,比如缺乏关键的硬件环境支持时,可以用这个命令来诊断到底是什 么设备出了问题。这个命令在我这里奏效,但我不保证在所有的机器上都能奏效。在显示的情况中找VGA这一栏,可以看到显示信息如下:
01:00.0 VGA compatible controller: ATI Technologies Inc RV370 [Sapphire X550 Silent] (prog-if 00 [VGA])
Flags: bus master, fast devsel, latency 0, IRQ 16
Memory at 20000000 (32-bit, prefetchable) [size=256M]
I/O ports at 2000 [size=256]
Memory at 30110000 (32-bit, non-prefetchable) [size=64K]
Expansion ROM at 30120000 [disabled] [size=128K]
Capabilities:
从这里,我们 ...