| | 1083 | * Apache 效能調校(Performance Tuning) |
| | 1084 | * 4/11~4/13 多次重新開機 trac 網站,一直無法找出記憶體需求突然高漲的主因是因為升級到 Squeeze,改用 Apache MPM 版本([http://packages.debian.org/apache2-mpm-prefork apache2-mpm-prefork]),還是其他原因。 |
| | 1085 | * [[Image(jazz/11-04-13:11-04-14_memory-week.png)]] |
| | 1086 | * 花了兩天時間,總算找出造成 trac 網站大量記憶體需求的特徵:刻意發起造成 CLOSE_WAIT 的攻擊行為。 |
| | 1087 | {{{ |
| | 1088 | PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND |
| | 1089 | 15652 www-data 20 0 783m 763m 4624 R 97.0 75.4 17:31.07 apache2 |
| | 1090 | 20059 www-data 20 0 52836 31m 4732 S 2.7 3.2 0:06.86 apache2 |
| | 1091 | |
| | 1092 | jazz@trac-pool:~$ sudo netstat -nap | grep 15652 |
| | 1093 | tcp6 1 0 140.110.X.X:80 220.181.93.1:55903 CLOSE_WAIT 15652/apache2 |
| | 1094 | }}} |
| | 1095 | * 手動砍掉 15652 這個 process 之後,同樣這個 IP,後來又產生了一次 CLOSE_WAIT 現象,不禁懷疑這是一種網站攻擊方式。 |
| | 1096 | {{{ |
| | 1097 | PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND |
| | 1098 | 23708 www-data 20 0 414m 396m 4544 R 99.7 39.2 2:44.46 apache2 |
| | 1099 | 23025 www-data 20 0 74940 55m 4752 S 0.0 5.5 0:27.58 apache2 |
| | 1100 | |
| | 1101 | tcp6 0 0 140.110.X.X:80 220.181.93.1:64932 TIME_WAIT - |
| | 1102 | tcp6 0 0 140.110.X.X:80 220.181.93.1:47074 TIME_WAIT - |
| | 1103 | tcp6 0 0 140.110.X.X:80 220.181.93.1:50047 TIME_WAIT - |
| | 1104 | tcp6 0 0 140.110.X.X:80 220.181.93.1:43913 TIME_WAIT - |
| | 1105 | }}} |
| | 1106 | * <解決方法> 降低 net.ipv4.tcp_keepalive_time 的數值,預設是 7200 秒(兩小時),真的太長了!! |
| | 1107 | {{{ |
| | 1108 | echo "decrease TCP socket TIME_WAIT time" |
| | 1109 | sysctl -w net.ipv4.tcp_fin_timeout=10 |
| | 1110 | sysctl -w net.ipv4.tcp_tw_reuse=1 |
| | 1111 | sysctl -w net.ipv4.tcp_tw_recycle=1 |
| | 1112 | echo "decrease TCP socket CLOSE_WAIT time" |
| | 1113 | sysctl -w net.ipv4.tcp_keepalive_time=30 |
| | 1114 | sysctl -w net.ipv4.tcp_keepalive_probes=2 |
| | 1115 | sysctl -w net.ipv4.tcp_keepalive_intvl=2 |
| | 1116 | }}} |
| | 1117 | * <參考> [http://tw.myblog.yahoo.com/yaitoo-richzal/article?mid=212&sc=1 大量 CLOSE_WAIT 的影響] |
| | 1118 | {{{ |
| | 1119 | 大量的 CLOSE_WAIT 連接,直接佔滿 TCP 連線佇列, |
| | 1120 | 導致 Apache 失去回應,且 CPU 使用量與記憶體使用量快速提高!! |
| | 1121 | }}} |
| | 1122 | * <參考> [http://haka.sharera.com/blog/BlogTopic/32309.htm CLOSE_WAIT 生成的原因] |
| | 1123 | |
| | 1124 | * 另外我也做了兩個小調校: |
| | 1125 | * <1> 限制每個 process 的記憶體使用 - 在 /etc/profile 中加入 |
| | 1126 | {{{ |
| | 1127 | ulimit -v 524288 |
| | 1128 | }}} |
| | 1129 | * 其結果是最高可以使用的記憶體是 524288 = 512 * 1024 kbytes = 512 MB。 |
| | 1130 | {{{ |
| | 1131 | virtual memory (kbytes, -v) 524288 |
| | 1132 | }}} |
| | 1133 | * <2> 把 /etc/apache2/apache2.conf 改成只使用 prefork 模組,並且降低 !KeepAliveTimeout 的時間(15秒降低到2秒),還有降低預設開啟的 apache process 數量。 |
| | 1134 | {{{ |
| | 1135 | #!diff |
| | 1136 | --- /etc/apache2/apache2.conf.org 2011-04-12 10:32:53.000000000 +0800 |
| | 1137 | +++ /etc/apache2/apache2.conf 2011-04-14 00:38:39.000000000 +0800 |
| | 1138 | @@ -64,7 +64,7 @@ |
| | 1139 | # |
| | 1140 | # Timeout: The number of seconds before receives and sends time out. |
| | 1141 | # |
| | 1142 | -Timeout 300 |
| | 1143 | +Timeout 30 |
| | 1144 | |
| | 1145 | # |
| | 1146 | # KeepAlive: Whether or not to allow persistent connections (more than |
| | 1147 | @@ -83,7 +83,7 @@ |
| | 1148 | # KeepAliveTimeout: Number of seconds to wait for the next request from the |
| | 1149 | # same client on the same connection. |
| | 1150 | # |
| | 1151 | -KeepAliveTimeout 15 |
| | 1152 | +KeepAliveTimeout 2 |
| | 1153 | |
| | 1154 | ## |
| | 1155 | ## Server-Pool Size Regulation (MPM specific) |
| | 1156 | @@ -96,11 +96,11 @@ |
| | 1157 | # MaxClients: maximum number of server processes allowed to start |
| | 1158 | # MaxRequestsPerChild: maximum number of requests a server process serves |
| | 1159 | <IfModule mpm_prefork_module> |
| | 1160 | - StartServers 5 |
| | 1161 | - MinSpareServers 5 |
| | 1162 | - MaxSpareServers 10 |
| | 1163 | - MaxClients 150 |
| | 1164 | - MaxRequestsPerChild 0 |
| | 1165 | + StartServers 1 |
| | 1166 | + MinSpareServers 1 |
| | 1167 | + MaxSpareServers 1 |
| | 1168 | + MaxClients 5 |
| | 1169 | + MaxRequestsPerChild 100 |
| | 1170 | </IfModule> |
| | 1171 | |
| | 1172 | # worker MPM |
| | 1173 | @@ -113,15 +113,15 @@ |
| | 1174 | # and starting Apache. |
| | 1175 | # ThreadsPerChild: constant number of worker threads in each server process |
| | 1176 | # MaxRequestsPerChild: maximum number of requests a server process serves |
| | 1177 | -<IfModule mpm_worker_module> |
| | 1178 | - StartServers 2 |
| | 1179 | - MinSpareThreads 25 |
| | 1180 | - MaxSpareThreads 75 |
| | 1181 | - ThreadLimit 64 |
| | 1182 | - ThreadsPerChild 25 |
| | 1183 | - MaxClients 150 |
| | 1184 | - MaxRequestsPerChild 0 |
| | 1185 | -</IfModule> |
| | 1186 | +#<IfModule mpm_worker_module> |
| | 1187 | +# StartServers 1 |
| | 1188 | +# MinSpareThreads 1 |
| | 1189 | +# MaxSpareThreads 1 |
| | 1190 | +# ThreadLimit 1 |
| | 1191 | +# ThreadsPerChild 1 |
| | 1192 | +# MaxClients 5 |
| | 1193 | +# MaxRequestsPerChild 50 |
| | 1194 | +#</IfModule> |
| | 1195 | |
| | 1196 | # event MPM |
| | 1197 | # StartServers: initial number of server processes to start |
| | 1198 | @@ -130,15 +130,15 @@ |
| | 1199 | # MaxSpareThreads: maximum number of worker threads which are kept spare |
| | 1200 | # ThreadsPerChild: constant number of worker threads in each server process |
| | 1201 | # MaxRequestsPerChild: maximum number of requests a server process serves |
| | 1202 | -<IfModule mpm_event_module> |
| | 1203 | - StartServers 2 |
| | 1204 | - MaxClients 150 |
| | 1205 | - MinSpareThreads 25 |
| | 1206 | - MaxSpareThreads 75 |
| | 1207 | - ThreadLimit 64 |
| | 1208 | - ThreadsPerChild 25 |
| | 1209 | - MaxRequestsPerChild 0 |
| | 1210 | -</IfModule> |
| | 1211 | +#<IfModule mpm_event_module> |
| | 1212 | +# StartServers 1 |
| | 1213 | +# MinSpareThreads 1 |
| | 1214 | +# MaxSpareThreads 1 |
| | 1215 | +# ThreadLimit 1 |
| | 1216 | +# ThreadsPerChild 1 |
| | 1217 | +# MaxClients 5 |
| | 1218 | +# MaxRequestsPerChild 50 |
| | 1219 | +#</IfModule> |
| | 1220 | |
| | 1221 | # These need to be set in /etc/apache2/envvars |
| | 1222 | User ${APACHE_RUN_USER} |
| | 1223 | }}} |
| | 1224 | * <參考> [http://bobcares.com/blog/?p=71 Configuring Apache for Maximum Performance] |
| | 1225 | * <參考> [http://wiki.vpslink.com/Low_memory_MySQL_/_Apache_configurations Low memory MySQL / Apache configurations] |
| | 1226 | * <參考> [http://www.devside.net/articles/apache-performance-tuning Apache Performance Tuning] |
| | 1227 | {{{ |
| | 1228 | prefork [default MPM for Apache 2.0 and 1.3]: |
| | 1229 | |
| | 1230 | * Apache 1.3-based. |
| | 1231 | * Multiple processes, 1 thread per process, processes handle requests. |
| | 1232 | * Used for security and stability. |
| | 1233 | * Has higher memory consumption and lower performance over the newer Apache 2.0-based threaded MPMs. |
| | 1234 | worker: |
| | 1235 | |
| | 1236 | * Apache 2.0-based. |
| | 1237 | * Multiple processes, many threads per process, threads handle requests. |
| | 1238 | * Used for lower memory consumption and higher performance. |
| | 1239 | * Does not provide the same level of isolation request-to-request, as a process-based MPM does. |
| | 1240 | }}} |
| | 1241 | {{{ |
| | 1242 | MaxClients ≈ (RAM - size_all_other_processes)/(size_apache_process) |
| | 1243 | }}} |
| | 1244 | |