Apache 的 CPU 使用率突然增加,而请求、磁盘 i/o、php/数据库连接等并没有增加

Apache 的 CPU 使用率突然增加,而请求、磁盘 i/o、php/数据库连接等并没有增加

今天早上,我们发现我们的 Web 服务器(称为 host1)的 CPU 利用率和负载大幅增加。总体 CPU 使用率从大约 100% 上升到 500%(16 个内核,32 个超线程),负载从平均 < 1 上升到 ~6。然后它保持在该增加的水平。使用 top,很明显增加的 CPU 使用率全部来自 Apache(httpd 进程)。(我们使用的是 CentOS 7.6 上的 Apache 2.4.39。)

PHP 进程和 mariadb 连接均与基线水平持平。通过服务器网络连接传输的数据保持不变。基于服务器 domlog 行数的每分钟请求数保持不变。磁盘利用率、等待时间或服务时间均未增加。内存使用量也持平。

我检查了负载突然上升时的 Apache 错误日志,没有看到任何新内容,而且 Apache 当时也没有重新启动。

作为测试,我将我们所有的网络流量从 host1 移至一台实际上完全相同的备份服务器 host2。一旦流量迁移完毕,host1 的 CPU 使用率就会降至接近零(此时下降了约 400%),而 host2 上的使用率仅上升到约 80%,大约相当于 host1 在突然上升之前的运行水平。因此,无论发生什么变化,都与该特定服务器有关,而不是与我们网络流量的性质有关。

我检查了两台服务器上的 apache 配置,正如预期的那样,它们是相同的。查看 apache 状态,主机 1 上的并发连接数似乎大约是主机 2 上的两倍。考虑到更高的负载/CPU 使用率,这是意料之中的。处理请求需要更长的时间,因此在相同的吞吐量下,我们有更多的并发连接。主观上,似乎某些请求在主机 1 上在正常时间内返回,而其他请求则比平时花费的时间长得多(秒而不是预期的毫秒)。但这可能是负载增加的原因或结果。

我尝试在 host1 上禁用 mod_security,并排除了这是原因。接下来,我尝试完全重新启动 host1,但在将流量转移回来后,高负载仍然存在。还有什么可能导致特定服务器上的 apache 突然持续使用更多 CPU 并花费更长时间处理相同数量的请求?

编辑:无论就其价值而言,系统和用户的 CPU 使用率都成比例增加。

编辑2:perf top 的结果:

Samples: 905K of event 'cycles:ppp', Event count (approx.): 111054988919
Overhead  Shared Object             Symbol
  16.69%  [kernel]                  [k] system_call_after_swapgs
  11.02%  [kernel]                  [k] sysret_check
   5.64%  [kernel]                  [k] copy_user_enhanced_fast_string
   3.79%  [kernel]                  [k] fget_light
   3.04%  [kernel]                  [k] __audit_syscall_exit
   3.01%  [kernel]                  [k] generic_file_aio_read
   2.51%  [kernel]                  [k] __audit_syscall_entry
   1.78%  [kernel]                  [k] sys_lseek
   1.63%  [kernel]                  [k] __radix_tree_lookup
   1.45%  [kernel]                  [k] sys_read
   1.43%  libpthread-2.17.so        [.] __pthread_disable_asynccancel
   1.32%  [kernel]                  [k] touch_atime
   1.28%  [kernel]                  [k] ext4_file_read
   1.23%  [kernel]                  [k] radix_tree_descend
   1.11%  [kernel]                  [k] mutex_lock
   1.08%  [kernel]                  [k] vfs_read
   1.04%  [kernel]                  [k] file_read_actor
   0.95%  libapr-1.so.0.6.5         [.] apr_file_read
   0.85%  [kernel]                  [k] do_sync_read
   0.84%  [kernel]                  [k] __d_lookup_rcu
   0.81%  [kernel]                  [k] __x86_indirect_thunk_rax
   0.79%  [kernel]                  [k] fsnotify
   0.78%  [kernel]                  [k] generic_segment_checks
   0.77%  [kernel]                  [k] __check_object_size
   0.74%  [kernel]                  [k] current_kernel_time
   0.73%  libapr-1.so.0.6.5         [.] apr_file_read_full
   0.71%  [kernel]                  [k] put_page
   0.70%  [kernel]                  [k] ext4_llseek
   0.70%  php-fpm                   [.] execute_ex
   0.69%  libaprutil-1.so.0.6.1     [.] getpage
   0.65%  [kernel]                  [k] _cond_resched
   0.64%  libaprutil-1.so.0.6.1     [.] read_from
   0.59%  [kernel]                  [k] strncpy_from_user
   0.59%  libpthread-2.17.so        [.] llseek
   0.57%  [kernel]                  [k] __fsnotify_parent
   0.57%  [kernel]                  [k] cleanup_module
   0.55%  [kernel]                  [k] rw_verify_area
   0.55%  [kernel]                  [k] __find_get_page
   0.51%  [kernel]                  [k] auditsys
   0.51%  [kernel]                  [k] security_file_permission
   0.48%  php-fpm                   [.] _is_numeric_string_ex
   0.47%  [kernel]                  [k] unroll_tree_refs
   0.47%  libapr-1.so.0.6.5         [.] apr_file_seek
   0.42%  [kernel]                  [k] generic_file_llseek_size
   0.41%  [kernel]                  [k] fput
   0.40%  php-fpm                   [.] zend_hash_find
   0.35%  [kernel]                  [k] __virt_addr_valid
   0.30%  [kernel]                  [k] path_put
   0.27%  libaprutil-1.so.0.6.1     [.] getnext
   0.27%  libz.so.1.2.7             [.] 0x0000000000002d11
   0.27%  [kernel]                  [k] tracesys
   0.27%  [unknown]                 [k] 0x00002af9a2716d7b
   0.27%  [kernel]                  [k] lookup_fast
   0.25%  [kernel]                  [k] mutex_unlock
   0.25%  [kernel]                  [k] kfree
   0.24%  [kernel]                  [k] current_fs_time

为了进行比较,以下是我们另一台服务器 host2 的结果,该服务器正在处理相当数量的网络流量以及当前我们所有的数据库,并且没有遇到这种高负载问题:

Samples: 1M of event 'cycles:ppp', Event count (approx.): 104427407206424
Overhead  Shared Object                  Symbol
  27.34%  [kernel]                       [k] retint_userspace_restore_args
  13.57%  php-fpm                        [.] zend_do_inheritance
   7.56%  [kernel]                       [k] handle_mm_fault
   7.56%  httpd                          [.] 0x000000000004470e
   6.87%  libpthread-2.17.so             [.] pthread_cond_broadcast@@GLIBC_2.3.2
   4.43%  [kernel]                       [k] cpuidle_enter_state
   3.31%  libc-2.17.so                   [.] __memmove_ssse3_back
   3.31%  [unknown]                      [.] 0x00002b8a4d236777
   2.68%  [kernel]                       [k] cap_inode_permission
   2.09%  libperl.so                     [.] S_refto
   2.09%  [unknown]                      [k] 0x00007f4479518900
   1.37%  [kernel]                       [k] free_pages_prepare
   1.20%  [kernel]                       [k] hrtimer_interrupt
   0.90%  [kernel]                       [k] irq_return
   0.89%  [kernel]                       [k] change_pte_range
   0.76%  httpd                          [.] ap_find_command
   0.69%  [unknown]                      [k] 0x00007fe15a923be8
   0.68%  [kernel]                       [k] lookup_fast
   0.60%  libperl.so                     [.] Perl_runops_standard
   0.60%  libperl.so                     [.] Perl_pp_multideref
   0.60%  [unknown]                      [.] 0x00007f227838a777
   0.55%  [kernel]                       [k] system_call_after_swapgs
   0.46%  [unknown]                      [.] 0x00007f18e7736015
   0.45%  libc-2.17.so                   [.] __memcpy_ssse3_back
   0.40%  mysqld                         [.] 0x0000000000b643c4
   0.40%  ld-2.17.so                     [.] _dl_map_object_deps
   0.39%  [unknown]                      [.] 0x00007f81151f761c
   0.35%  [kernel]                       [k] kmem_cache_alloc
   0.35%  [kernel]                       [k] vma_interval_tree_insert
   0.30%  [kernel]                       [k] _raw_spin_lock_irqsave
   0.30%  libc-2.17.so                   [.] __readdir_r
   0.30%  [kernel]                       [k] tick_do_update_jiffies64
   0.30%  libpng15.so.15.13.0            [.] 0x000000000001ff7f
   0.30%  [unknown]                      [.] 0x00007f2a3ffee13c
   0.30%  libpthread-2.17.so             [.] __ctype_init@plt
   0.26%  libc-2.17.so                   [.] _int_malloc
   0.26%  libc-2.17.so                   [.] malloc
   0.26%  libc-2.17.so                   [.] malloc_consolidate
   0.26%  [kernel]                       [k] mem_cgroup_charge_common
   0.26%  libperl.so                     [.] Perl_hv_common
   0.26%  [kernel]                       [k] pid_revalidate
   0.26%  libperl.so                     [.] Perl_sv_eq_flags
   0.26%  libcairo.so.2.11512.0          [.] 0x000000000004bf43
   0.26%  libperl.so                     [.] S_dopoptosub_at
   0.26%  libcairo.so.2.11512.0          [.] 0x00000000000d059a

但是,就顶级功能而言,host2 的变化更大;这只是一个例子。host1(有问题的主机)在列表中具有非常稳定的前几个条目。

编辑 3:将问题追溯到 mod security 后,我发现它似乎与 IP 地址数据库 /tmp/ip.pag 有关,尽管我们已设置修剪超时,但该数据库仍在无限增长。清除此文件可解决高 CPU 使用率问题,而无需完全禁用 mod security。但是,如果我们继续使用基于 IP 的规则,它可能会再次增长,因此我们正在考虑修改规则,或者可能只是设置每日 cron 来清除文件中的任何旧 IP。

答案1

首先进行健全性检查,看看内核是否试图告诉您一些事情。可能是关于存储系统的,因为存储堆栈出现了样本。查看dmesgsyslog 日志文件的输出。


您的问题主机在内核上花费了更多时间。相比之下,php-fpm 和 httpd 位列前 5 名的其他主机则不然。大多数工作负载在用户空间中执行有用的服务,因此较低的内核开销是件好事。

注意在审计接口。我认为审计系统也使用 fsnotify。查看任何审计规则,包括文件系统和系统调用。审计所有读取之类的操作都非常昂贵。请参阅 auditd 包的文档,了解一些场景中的有针对性审计的示例。

如果你进一步分析,就可以了解 Linux 正在做什么的很多细节。使用perf 统计系统调用. 也有可能得到火焰图可视化中的整个调用图

编辑:如果您有符号,这些火焰图在高 CPU 利用率场景中特别有用。您可以将其与问题报告中的问题堆栈进行比较,并进一步深入研究耗时较长的特定函数。

安装yum-utils并使用它安装符号:( debuginfo-install --enablerepo=base-debuginfo httpd 这是一个方便的脚本,因此您不必知道 -debuginfo 后缀约定。)

你发现了ModSecurity 问题自发导致 CPU 使用率过高 #890。我实际上还没有在您的火焰图上看到这样的堆栈。但是,如果您安装了调试符号,您可以看到 APR、模块代码和操作系统内核之间的交互,而不仅仅是其中之一。

相关内容