Tuning Apache, MySQL, PHP on CentOS 5.2 for spike of traffic

Running Apache, MySQL and PHP for a Wordpress website, on CentOS 5.2 with a Linode 720.

I also added APC to cache PHP.

My blog http://www.hardware-revolution.com is now live on said configurations and running very well with about 3k hits per day.

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

start by getting some baselines of what your current config is capable of. I've got a Linode 360 running multiple wordpress sites. I did a little basic benchmarking with apache bench and was pushing something like 40 front page views/second without any tuning beyond installing APC. APC is a huge win.

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.

Hi,

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> 

Thanks for posting your config. I posted mine here: http://www.linode.com/forums/viewtopic. … 2010#22010">http://www.linode.com/forums/viewtopic.php?p=22010#22010

At this point, I haven't done a lot of tweaking with mine but it is working well.

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct