如何使用 Apache PHP 減少伺服器負載
在上個月執行 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 類型的列。