Tag

呼叫中心Linux服务器系统故障排除 归档 - 呼叫中心,呼叫中心系统,云通讯平台,asterisk 呼叫中心

呼叫中心Linux服务器系统故障排除-第一部分:高负载

By | 开发者博客 | No Comments

呼叫中心Linux服务器系统故障排除

当你得到一个系统负载高的警告时,你会怎么办?寻找高负载的原因只是需要一些时间、一些经验 和 一些Linux工具。

      这个专栏是我喜欢的文献中第一个主题:故障排除。尽管我一天到晚是一个系统管理员,但我很喜欢我工作的方方面面,很难打消我追踪复杂服务器问题的热情。就像有许多故障诊断方法一样,也有很多原因会让Linux文本编译器无法工作。在过去的几年里,我发现我执行相同的步骤来避免问题,因为我的专栏通常更多针对技巧办法,并且减少理和设计。我不会大谈整体解决问题的方法,相反,在本系列中,我描述了一些你可能会在Linux系统上发现的基本问题。然后我将讨论如何使用那些大部分可能已经在系统上的常用工具,去避免和解决同类问题。

      对于第一个专栏,我将以你在运行Linux系统时,最常见问题之一开始入手。我谈论的是一个缓慢的服务器高负载问题。在我解释如何诊断和修复高负载之前,退一步讲我们先搞清楚Linux机器上都有什么负载,并且我们如何知道何时负载会过高。

正常运行时间和负载

管理员所说的高负载,通常他们说的是平均负载。我要诊断服务器缓慢的原因,我登录到系统敲入的第一条命令就是:uptime:

$ uptime

显示结果:
18:30:35 up 365 days, 5:29, 2 users, load average: 1.37, 10.15, 8.10

正如你看到的,截至到今天,服务器已经运行了365天。同时你还可以看到,平均负载为:1.37, 10.15, 8.10。这些数字分别代表最后1分钟,5分钟,15分钟的系统的平均负载。技术上讲,平均负载是指在过去的1分钟,5分钟,15分钟内 进程等待CPU响应时间 的平均数。例如:如果负载为0,那么系统是完全空闲的。如果负载为1,那么CPU会忙得以至于等待CPU响应时间。如果有一个负载为1,并且它引发通常占用CPU的一些进程,这样一来,负载就会变为2了。正是因为平均负载,系统会统计在过去的1分钟,5分钟,15分钟里是如何持续运行的。

另一个重要的是,要知道当你看到的平均负载并不是完全的记录系统里的CPU数量。一般说来,一个准确的负载意味着在系统上只有一个CPU被占用。简言之,这就意味着负载为1的单核CPU系统和一个负载为4的4核CPU一样忙。所以在上面的例子中,假设我有一个单核CPU系统。如果我想登录去并且去看他们的平均负载,最好假设在过去的15分钟服务器有相当高的负载(8.10),大约在5分钟前(10.15)。但最近,至少在最后1分钟,负载已大幅下降。如果我看到了这现象,我甚至可以假设负载的真正原因已经消退。另一方面,如果平均负载分别为20.68,5.01,1.03,我得出的结论是:高负载有可能开始在最后5分钟,并且负载变得更加糟糕。

负载多高算高?

但当你明白了平均负载的含义以后,接下来你就会问:什么样的平均负载是好?什么样的是坏? 答案是“看情况”。很多不同的事务可以导致高负载,并且每个事务的影响也不同。一个服务器可能有一个负载为50,仍然运行良好,而另一个服务器可能有一个负载10并采取永远登录。我有一个非常慢的平均负载数成百上千的服务器,但并没有崩溃。还有服务器一直有50个负载,也运行良好,而且运行了好多年。

当你诊断一个高负载的系统时,什么才是负载高的真正重要因素。当你开始排除高负载的故障时,你会发现大多数负载似乎分为三类:中央处理器受限负载、内存不足引起的负载 以及 I / O密集型负载。我在下面详细解释每一类问题,该如何使用工具,比如用top和iostat去阻止根原。

 

top命令

如果说登录一个缓慢的系统时,使用的第一个工具是uptime,那么使用的第二个工具就是top。top的伟大之处就在于它可以获取Linux系统的所有主要因素,而且可以提供很多有用的信息,显示在一张屏幕上。top是一个有很多参数选项的十分复杂的工具,多的以至于可以写满整个文章。但对于这个专题,我仍坚持如何通过解释其输出来诊断高负载。

使用“top”,只需在命令行上输入“top”。默认情况下,“top”将以交互模式运行,并每隔几秒更新其输出。下面的列表1显示了从终端输出的“top”示例。

 

Listing 1. Sample top Output   —top案例输出

$top

显示结果:
top - 14:08:25 up 38 days, 8:02, 1 user, load average: 1.70, 1.77, 1.68
Tasks: 107 total,   3 running, 104 sleeping,   0 stopped,   0 zombie
Cpu(s): 11.4%us, 29.6%sy, 0.0%ni, 58.3%id, .7%wa, 0.0%hi, 0.0%si, 0.0%st
Mem:   1024176k total,   997408k used,    26768k free,    85520k buffers
Swap:  1004052k total,     4360k used,   999692k free,   286040k cached

  PID USER    PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 9463 mysql   16   0  686m 111m 3328 S   53  5.5 569:17.64 mysqld
18749 nagios  16   0  140m 134m 1868 S   12  6.6   1345:01 nagios2db_status
24636 nagios  17   0 34660  10m  712 S    8  0.5   1195:15 nagios
22442 nagios  24   0  6048 2024 1452 S    8  0.1   0:00.04 check_time.pl
... ...

正如你所看到的,在仅有的几行中,却包含了很多信息。

第一行显示的是,可以从uptime命令获取的每隔几秒就会更新的平均负载的 信息。在这个例子中,你可以看到系统非常繁忙,但不是我所说的高负载。尽管如此,这个输出被分解到不同负载的类别。当我对这个缓慢的系统进行故障排除时,通常会排除掉CPU受限负载、内存负载问题 以及 I / O密集型负载,所以让我们先从CPU受限负载开始吧。

 

CPU受限负载

CPU负载:是指一次运行过多的CPU密集型进程,所引起的负载。因为每个进程都需要占用CPU资源,他们必须按顺序等待。想检查CPU负载是否受限,用top命令后即可看到CPU行信息:

Cpu(s): 11.4%us, 29.6%sy, 0.0%ni, 58.3%id, .7%wa, 0.0%hi, 0.0%si, 0.0%st

每一个百分数都是CPU处理特定任务所占时间的百分比。其次,top命令出来的内容很多,下面是几个常用值,做简单说明:

  • us: 用户CPU时间比(user CPU time),通常情况下,CPU受限负载,都是由于系统上进程由一个用户运行,如:Apache、MySQL或者shell脚本。如果这个比例较高,最可能引起的负载。
  • sy: 系统CPU时间比(system CPU time),是由内核CPU和其他系统进程占用的百分比。CPU受限负载体现在高百分比的用户或系统CPU时间上。
  • id: CPU 空闲时间比(CPU idle time),这是CPU空闲的时间的百分比。数值越高越好,实际上,如果你看到一个很高的CPU空闲比,那将是一个任何高负载都达不到CPU负载首先的迹象。
  • wa: I/O 等待时间比(I/O wait),这个值表明CPU花费时间在等待I/O(通常是磁盘I / O)上的百分比。如果你有高负载并且这个值很高,很可能负载不是CPU受限,而是由于内存问题或磁盘I/O。

 

追踪CPU受限负载

如果你看到一个高百分比的用户或系统时间比,很有可能你的负载是CPU受限。寻找问题的根源,跳过几行到顶部显示当前系统上运行的进程的列表。默认情况下,top命令将基于进程的CPU使用百分比 进行排序,如下列表2:

 

Listing 2. Current Processes Example  —当前进程事例

  PID USER   PR NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 9463 mysql  16  0  686m 111m 3328 S   53  5.5 569:17.64 mysqld
18749 nagios 16  0  140m 134m 1868 S   12  6.6   1345:01 nagios2db_status
24636 nagios 17  0 34660  10m  712 S    8  0.5   1195:15 nagios
22442 nagios 24  0  6048 2024 1452 S    8  0.1   0:00.04 check_time.pl

%CPU这列表示每个进程占用多少CPU。在这个例子中,可以看到MySQL占用了53%。当你注意这个CPU受限负载输出,你可能会发现两个问题:要么有一个占用99%CPU的进程,要么你会看到许多加起来还不到1%的小进程,在这两种情况下,可以看到相对简单的进程导致的问题。最后,我想增加一下CPU限制负载,我可以看到系统获得令人难以置信的高负载,是因为在一个没有多核CPU的系统上,一个多线程程序会催生出一个巨大的负载。如果在一个单核CPU系统上催生20个线程,你会看到一个高平均负载,尽管没有占用CPU时间的具体进程。

 

内存问题

第二个引起系统高负载的原因是内存不足,并且已经进入交换分区了。由于交换分区的空间通常在比RAM慢很多的硬盘上,所以当RAM用完并进入交换分区时,每个进程的运行会随使用硬盘而急剧减缓。通常这会导致一个恶性循环进程,这个进程 交换运行缓慢、响应时间长 并且会引起更多的栈,直到耗尽内存。交换分区最棘手的问题是,由于它对磁盘的重创,很容易误判为是I/O密集型负载。毕竟,当硬盘空间被用作内存时,任何那些实际要访问磁盘文件的进程,都不得不排队等候。所以当我看到CPU行较高的I/O等候时,在我排除所有I/O问题之前,我会检查RAM并排除它。

要诊断内存问题时,我们首先观察以下top输出的两行记录:

Mem: 1024176k total, 997408k used, 26768k free, 85520k buffers
Swap: 1004052k total, 4360k used, 999692k free, 286040k cached

这些记录可以表明RAM和交换分区的总量,以及占用多少,空余多少。然而,仔细观察这些可能会误导你的数字。我看到许多新的甚至有经验的管理员看到以上记录后,因仅有 26768k 空余而得出系统内存不足的结论。尽管这显示的的确是当前未被使用的内存,但是他并没有告诉我们总存储空间。

 

Linux文件缓存

当你访问一个文件时,Linux内核会将其加载到RAM中,并且不再需要他们时,内核也不会卸载掉它们。如果RAM有足够的可用空间时,内核会试图尽可能多地存储文件到RAM中。这样的话,当你第二次访问这个文件的时候,内核可以从RAM而不是从硬盘检索它,并且可以提供更好的性能。当一个系统一直运行时,你会发现RAM的空闲会变得非常小。如果一个进程需要更多的RAM,内核会直接使用文件缓存。事实上,我见到过很多可以提高性能的超频技术,创建一个虚拟内存盘来存储文件。他们没有意识到的是,通常情况下,他们仅使用内核就可以看到更好的结果并且更高效地使用RAM。

想要获得一个更准确的RAM空闲值,需要结合free列和cached列的值来得出。在这个例子中,我们用26768k + 286040k,RAM超过300Mb。在这个事例中,我可以很肯定地说,系统没有内存不足问题。当然,即使系统有很小的RAM空余,那是还没进入交换分区。这就是为何我们必须要检查交换分区:假如很高一部分的swap分区被使用。

 

追踪高内存使用率

如果你发现空闲RAM较低,再看一次同一进程输的数据,但这一次看%MEM列。默认情况下,top命令的输出数据是按照%CPU列排列的,按M它将重新显示内存的最高使用比率。在下面列表3中,我们排序相同内存的进程,并且易知 nagios2db_status 进程占内存最高,占了6.6%。

 

Listing 3. Processes Sorted by RAM —按内存大小排序进程

PID USER   PR NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
18749 nagios 16  0  140m 134m 1868 S   12  6.6   1345:01 nagios2db_status
 9463 mysql  16  0  686m 111m 3328 S   53  5.5 569:17.64 mysqld
24636 nagios 17  0 34660  10m  712 S    8  0.5   1195:15 nagios
22442 nagios 24  0  6048 2024 1452 S    8  0.1   0:00.04 check_time.pl

 

 I / O密集型负载

I / O密集型负载的追踪,有时比较棘手。正如前面所说,如果系统发生了交换,它可以容易判断是I / O密集型负载。一旦你排除了交换,并且还存在一个高I/O等待,那么下一步我们将尝试追踪那些有大量I/O量的硬盘和分区。为了这么做,我们需要一个类似于 iostat 的命令工具。

这个 iostat 工具,就如 top工具,也是一个功能齐全而且复杂的工具。但又不同于 top 工具,它首先要在系统上可以运行,它不会默认的安装到你的系统,所以你要寻找可用的安装包。在red-hat和debian-based的系统上,你可以在 sysstat 的包中获取。一旦被安装,iostat 可以不带任何参数单独运行,来获取一个完整的硬盘I/O统计数据。

$ iostat

显示结果:
Linux 2.6.24-19-server (hostname) 	01/31/2009

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.73    0.07    2.03    0.53    0.00   91.64

Device:    tps  Blk_read/s  Blk_wrtn/s   Blk_read   Blk_wrtn
sda       9.82       417.96        27.53   30227262    1990625
sda1      6.55       219.10         7.12   15845129     515216
sda2      0.04         0.74         3.31      53506     239328
sda3      3.24       198.12        17.09   14328323    1236081

就像top命令一样,iostat 也会输出CPU使用百分比。在下面,他还提供了系统内崩溃的每个驱动和分区的统计数据:

  • tps:每秒处理的事物数(transactions per second)。
  • Blk_read/s:每秒读取的块数(blocks read per second)。
  • Blk_wrtn/s:每秒写入的块数(blocks written per second)。
  • Blk_read:读取的总块数(total blocks read)。
  • Blk_wrtn:写入的总块数(total blocks written)。

通过观察和比较这些值之间的不同,你首先应该看到哪个(哪些)分区可以获得大量的I/O数据,其次 大多数的量是否被读或者被写。就如我所说,追踪引起I/O负载的问题比较棘手,但是有希望,这些值将会帮助我们筛选出哪些进程可能引起负载。

例如,如果你有一个I / O密集型负载,并且你怀疑你的远程备份事务可能是罪魁祸首。比较读写数据。因为你知道,远程的备份任务主要从硬盘读,如果你看到大部分的磁盘在写入,你可以合理地认为这不是在备份。另一方面,当你看到一个大量读取某个分区上的I / O,你可以运行 lsof 命令和grep命令来查看这个备份进程,看他是否真的在分区上打开了文件句柄。

正如你所看到的,用 iostat 追踪I/O密集型负载并不直观。尽管不需要参数,但需要时间和经验来判断。也就是说,iostat 有很多可以获得更多不同类型I / O信息 的参数,包括寻找 NFS 共享细节的模式。如果你想知道更多,请查看 iostat 手册。

直到现在,诸如 iostat 的工具已经被系统管理员放到解决I/O问题的工具箱里了,由于内核技术的发展,在进程层面上的I/O原因变得更容易发现。假如你有一个相对较新的系统,查看你的 iotop 工具。就像iostat一样,也许他也被默认安装了。顾名思义,它的功能就像top,只针对硬盘I/O。在下面的列表4中,你可以看到在这台机器上,一个使用I/O最多的 rsync 进程 (在本例中是读取I / O)。

 

Listing 4. Example iotop Tool Output —iotop工具案例输出

$ sudo iotop

显示结果:
Total DISK READ: 189.52 K/s | Total DISK WRITE: 0.00 B/s
  TID  PRIO  USER  DISK READ   DISK WRITE SWAPIN   IO>  COMMAND          
 8169  be/4  root  189.52 K/s   0.00 B/s  0.00%  0.00%  rsync --server --se
 4243  be/4  kyle    0.00 B/s   3.79 K/s  0.00%  0.00%  cli /usr/lib/gnome-
 4244  be/4  kyle    0.00 B/s   3.79 K/s  0.00%  0.00%  cli /usr/lib/gnome-
    1  be/4  root    0.00 B/s   0.00 B/s  0.00%  0.00%  init

 

一下你就找到问题的根源

你如何处理这些引起负载问题的进程,取决于你自己和很多其他因素。在某些情况下,您可能有一个脚本,该脚本已经失去控制,但你可以很容易地结束掉它。在其他情况下,比如在数据库的进程中,简单的结束进程可能是不安全的,因为它可能会破坏数据。另外,它可能是你控制能力意外运行的服务,真正的解决方案是在服务器上添加更多的资源,或者添加更多的服务器来分担负载。它甚至可能从工作的计算机上一次性加载运行,并且不影响负载,所以尽管让这个进程完成。由于很多因素会导致进程占用服务器资源,此处很难全部列出,但幸运的是能确定引起高负载的原因,并且让你在下次得到机器过慢的警报时,能够变得正常。

 

索克维尔旗下产品 · CXMind AI联络中心 · WCC全渠道联络中心