Tuning Apache, MySQL, PHP on CentOS 5.2 for spike of traffic
I also added APC to cache PHP.
My blog http://www.hardware-revolution.com
Now, I'd like to tune whatever is needed, server wise, to be able to handle traffic spikes when I get hit by Digg, StumbleUpon and such.
What are your recommendations?
Thank you.
3 Replies
I was CPU bound, with most it being used by Apache so I'm not sure how much more tuning there is to do, unless there are some tunables that make PHP more CPU efficient.
I did tune things by reducing the max number of apache processes. This had no real impact on overall throughput, but did reduce the variation in page generation times dramatically and leaves more memory for caching.
I went further still and set up nginx as a front end webserver to serve static files directly and proxy all the dynamic requests to apache. I went a little further too and turned off gzip compression on apache and left that to nginx.
The idea here is that nginx is an extremely CPU and, most importantly, memory efficient webserver. It can easily saturate 100mbit ethernet sending static files to thousands of simultaneous client connections files without using much CPU and, more importantly without using much memory. When proxying requests to apache, it accepts the results from apache at very high speed and then serves them out to the client as fast as they will take it. The end result is that the apache processes, which use a lot more memory, don't waste time waiting to send stuff to slow clients. This means that memory spends more time in support of actually generating php pages.
Some people go further and try and get apache out of the picture all together and run php as a fastcgi. I may yet go down that route, but it seemed more trouble than it was worth. The Apache/PHP combo is extremely well understood. Putting nginx in front of it ads a little complexity, but its still pretty straightforward and reliable. I guess the fast-cgi approach might save me 50MB or something but, even on the smallest linode, I have over 200MB of "free" memory for the filecache, etc.
Let me know, I'd be happy to share my configs for frontending apache with nginx.
You may be able to tune mysql some, but I haven't gotten in to that yet.
I'm running this same setup and it's making wonders.
@eas:
Let me know, I'd be happy to share my configs for frontending apache with nginx.
I would like to see yours if possible.
Here's mine running in ubuntu:
apache2.conf
Timeout 50
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
<ifmodule mpm_prefork_module="">StartServers 2
MinSpareServers 2
MaxSpareServers 2
MaxClients 10
MaxRequestsPerChild 1000</ifmodule>
nginx.conf
user www-data;
worker_processes 2;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
## General Options
server_tokens off;
sendfile on;
server_names_hash_bucket_size 64;
ignore_invalid_headers on;
limit_zone limit_per_ip $binary_remote_addr 1m;
## Timeouts
keepalive_timeout 10 10;
client_body_timeout 10;
client_header_timeout 10;
send_timeout 10;
## TCP options
tcp_nodelay on;
tcp_nopush on;
## GZip
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 9;
gzip_http_version 1.0;
gzip_min_length 0;
gzip_proxied any;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/x-javascript application/xml application/xml+rss application/x-httpd-php
gzip_disable "MSIE [1-6]\.";
gzip_vary on;
# Upstream servers
upstream backend {
server 127.0.0.1:8080;
}
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
proxy.conf
proxy_pass http://backend;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 32k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
nginx - example.com
server {
listen 80;
server_name example.com;
rewrite ^/(.*) http://www.example.com/$1 permanent;
}
server {
listen 80;
server_name www.example.com;
access_log off;
# Main location
location / {
include proxy.conf;
}
# Static files location
location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
root /home/public_html/example.com/public;
}
}
apache - example.com
<virtualhost *:8080=""># Admin email, Server Name (domain name) and any aliases
ServerAdmin mail@example.com
ServerName example.com
ServerAlias www.example.com
# Index file and Document Root (where the public files are located)
DirectoryIndex index.html index.php
DocumentRoot /home/public_html/example.com/public
# Custom log file locations
LogLevel warn
ErrorLog /var/log/apache2/example.com-error.log
CustomLog /var/log/apache2/example.com-access.log combined
# RPAF proxy
RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1
<directory home="" public_html="" example.com="" public="">Options MultiViews Indexes Includes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all</directory></virtualhost>