Httpd

如何使用 Apache PHP 減少伺服器負載

  • May 30, 2018

在上個月執行 CentOS 7 時,我們的 Linode 伺服器負載有所增加。我現在在 CentOS 7.5 上使用 PHP 7.2 升級到 MariaDB 10.3,具有 16GB 記憶體和 6 個核心。根據 apache2buddy perl 腳本,MariaDB 也在伺服器上使用 5372.81 MB。我正在使用預設的 MaxRequestWorkers,腳本說它太高了,但我已經在它的範圍內嘗試過並且沒有任何區別。我們最近將整個站點置於 HTTPS 下,但其中很多已經在問題發生之前。伺服器過去主要在伺服器負載 1 左右執行,現在平均為 3-4,峰值達到 8+。

top - 12:39:15 up 10:26,  2 users,  load average: 3.27, 3.57, 4.08
Tasks: 181 total,   2 running, 117 sleeping,   0 stopped,   0 zombie
%Cpu(s):  9.3 us,  6.0 sy,  0.0 ni, 54.2 id,  4.2 wa,  0.0 hi,  0.9 si, 25.4 st
KiB Mem : 16419324 total,   462908 free,  7237284 used,  8719132 buff/cache
KiB Swap:   524284 total,   524284 free,        0 used.  8808064 avail Mem

 PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
3614 mysql     20   0   10.1g   5.2g  21372 S  45.2 33.5 259:48.57 mysqld
15613 wmnf_ad+  20   0  842992 178644  95772 S  20.9  1.1   0:03.67 httpd
15650 wmnf_ad+  20   0  792196 131184  97048 S  16.6  0.8   0:10.31 httpd
15636 wmnf_ad+  20   0  837444 179280 101916 R  15.9  1.1   0:15.06 httpd
15634 wmnf_ad+  20   0  870480 136836 100236 S   7.0  0.8   0:16.07 httpd
15632 wmnf_ad+  20   0  794060 125052  89772 S   5.6  0.8   0:12.00 httpd
1937 root      20   0       0      0      0 D   2.3  0.0   7:03.28 jbd2/sda-8
   1 root      20   0  191432   5732   3856 S   1.0  0.0   1:01.34 systemd
15654 wmnf_ad+  20   0  795988 123584  88628 S   1.0  0.8   0:05.54 httpd
   8 root      20   0       0      0      0 I   0.7  0.0   3:45.27 rcu_sched
  34 root      20   0       0      0      0 S   0.3  0.0   1:13.51ksoftirqd/5
3207 root      20   0  492880  15488  12152 S   0.3  0.1   0:17.17 NetworkManager
15254 root      20   0  161992   4632   3856 R   0.3  0.0   0:03.46 top
15604 wmnf_ad+  20   0  799320 141524 104940 S   0.3  0.9   0:17.32 httpd
15628 wmnf_ad+  20   0  794284 128708  95872 S   0.3  0.8   0:17.75 httpd
15951 wmnf_ad+  20   0  796216 124368  89456 S   0.3  0.8   0:09.05 httpd
   2 root      20   0       0      0      0 S   0.0  0.0   0:00.12 kthreadd
   4 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 kworker/0:0H

當 Linode 之前給我們 8GB 的​​ 16GB 時,我在 httpd conf 中將這些數字翻了一番:

StartServers        4
MinSpareServers     20
MaxSpareServers     40
MaxClients          200
MaxRequestsPerChild 4500

自上次重新啟動約一小時後,Apache 記憶體使用情況如下所示:

[root@archives conf.d]# ps -ylC httpd | awk '{x += $8;y += 1} END {print "Apache Memory Usage (MB): "x/1024; print "Average Process Size (MB): "x/((y- 1)*1024)}'
Apache Memory Usage (MB): 6136.5
Average Process Size (MB): 109.58

查看 Apache 伺服器狀態頁面,看起來並沒有大量請求,而且肯定沒有使用我允許的所有資源:

Server Version: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/7.2.6
Server MPM: prefork
Server Built: Apr 20 2018 18:10:38
Current Time: Monday, 28-May-2018 12:27:12 EDT
Restart Time: Monday, 28-May-2018 12:26:14 EDT
Parent Server Config. Generation: 1
Parent Server MPM Generation: 0
Server uptime: 57 seconds
Server load: 4.54 4.76 4.67
Total accesses: 324 - Total Traffic: 127.9 MB
CPU Usage: u47.7 s18.95 cu0 cs0 - 117% CPU load
5.68 requests/sec - 2.2 MB/second - 404.3 kB/request
30 requests currently being processed, 30 idle workers
WKWR__W._W__WWW_RWK_W______RK._.K_R_K_R___K_RW__.R_..___W__KWRRW
.W_.............................................................
................................................................
........

我在幾個程序上使用了 pmap 並註意到很多模組,我可能不需要,但其中一些,所有這些模組是否預設載入?當然我安裝了php7、fcgid、status等…

[root@archives conf.d]# httpd -M
Loaded Modules:
core_module (static)
so_module (static)
http_module (static)
access_compat_module (shared)
actions_module (shared)
alias_module (shared)
allowmethods_module (shared)
auth_basic_module (shared)
auth_digest_module (shared)
authn_anon_module (shared)
authn_core_module (shared)
authn_dbd_module (shared)
authn_dbm_module (shared)
authn_file_module (shared)
authn_socache_module (shared)
authz_core_module (shared)
authz_dbd_module (shared)
authz_dbm_module (shared)
authz_groupfile_module (shared)
authz_host_module (shared)
authz_owner_module (shared)
authz_user_module (shared)
autoindex_module (shared)
cache_module (shared)
cache_disk_module (shared)
data_module (shared)
dbd_module (shared)
deflate_module (shared)
dir_module (shared)
dumpio_module (shared)
echo_module (shared)
env_module (shared)
expires_module (shared)
ext_filter_module (shared)
filter_module (shared)
headers_module (shared)
include_module (shared)
info_module (shared)
log_config_module (shared)
logio_module (shared)
mime_magic_module (shared)
mime_module (shared)
negotiation_module (shared)
remoteip_module (shared)
reqtimeout_module (shared)
rewrite_module (shared)
setenvif_module (shared)
slotmem_plain_module (shared)
slotmem_shm_module (shared)
socache_dbm_module (shared)
socache_memcache_module (shared)
socache_shmcb_module (shared)
status_module (shared)
substitute_module (shared)
suexec_module (shared)
unique_id_module (shared)
unixd_module (shared)
userdir_module (shared)
version_module (shared)
vhost_alias_module (shared)
dav_module (shared)
dav_fs_module (shared)
dav_lock_module (shared)
lua_module (shared)
mpm_prefork_module (shared)
proxy_module (shared)
lbmethod_bybusyness_module (shared)
lbmethod_byrequests_module (shared)
lbmethod_bytraffic_module (shared)
proxy_ajp_module (shared)
proxy_balancer_module (shared)
proxy_connect_module (shared)
proxy_express_module (shared)
proxy_fcgi_module (shared)
proxy_fdpass_module (shared)
proxy_ftp_module (shared)
proxy_http_module (shared)
proxy_scgi_module (shared)
proxy_wstunnel_module (shared)
ssl_module (shared)
systemd_module (shared)
cgi_module (shared)
fcgid_module (shared)
php7_module (shared)

我還檢查了 PHP 模組,發現 apc 已載入,不應該與新的 opcache 一起執行?它可能自早期版本以來就存在,但總而言之,沒有什麼不同。我還能做些什麼,或者如何確定造成這種高負載的原因?當 Apache 停止時,負載確實消退了。

執行 iotop,我看到了

$$ jbd2/sda-8 $$頂部的處理站點始終保持在 10-60% 的 IO 之間。如果這是與日誌相關的過程,那麼磁碟是否存在潛在問題。也許需要在單使用者模式下清理磁碟?

   Total DISK READ :       0.00 B/s | Total DISK WRITE :     181.41 K/s
Actual DISK READ:       0.00 B/s | Actual DISK WRITE:     272.12 K/s
 TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
1937 be/3 root        0.00 B/s    0.00 B/s  0.00 % 27.02 % [jbd2/sda-8]
3648 be/4 mysql       0.00 B/s  151.18 K/s  0.00 %  4.66 % mysqld
3645 be/4 mysql       0.00 B/s    0.00 B/s  0.00 %  1.40 % mysqld
19502 be/4 mysql       0.00 B/s   18.14 K/s  0.00 %  0.53 % mysqld
   1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % init
   2 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kthreadd]
   4 be/0 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kworker/0:0H]
   6 be/0 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [mm_percpu_wq]
   7 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [ksoftirqd/0]
   8 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [rcu_sched
<snip>

是的,mysqld 程序是問題所在,但由於等待此虛擬伺服器的主機。我頂部的高“st”數字表明主機正忙於其他虛擬機……

top - 12:39:15 up 10:26,  2 users,  load average: 3.27, 3.57, 4.08
Tasks: 181 total,   2 running, 117 sleeping,   0 stopped,   0 zombie
%Cpu(s):  9.3 us,  6.0 sy,  0.0 ni, 54.2 id,  4.2 wa,  0.0 hi,  0.9 si, 25.4 st
                                                                       ^^^^^^^

在向託管服務提供商指出這一點後,我們的虛擬機被遷移到了新的主機上。問題解決了,現在負載像往常一樣非常低。

我也認為 MySQL 是造成負載的原因。如您所料,jbd2 程序是一個核心執行緒,用於更新文件系統日誌。看起來 MySQL 正在大量寫入磁碟,這導致了 jbd2 上的負載。

MySQL 有時需要創建臨時表來處理查詢,尤其是帶有group by子句的查詢。如果這些臨時表是在磁碟上創建的,那可以解釋你的負載。該命令將顯示在磁碟和記憶體中創建了多少臨時表 SHOW GLOBAL STATUS LIKE 'created_tmp%tables';

同樣來自該連結,這也是 MySQL 在磁碟而不是記憶體上創建臨時表的兩個原因:

  • 結果大於 MySQL 變數 max_heap_table_size 和 tmp_table_size 中較小的一個。
  • 結果包含 BLOB 或 TEXT 類型的列。

引用自:https://serverfault.com/questions/914147