0

I've looked through lots of other Server Fault and Google results that all have talk about generally similar situations, but I can't quite find the insight that I'm looking for. I would appreciate any help that the community can provide, and don't want anyone thinking that I didn't do an exhaustive amount of research before asking for help. I truly appreciate anyone who takes the to respond and educate me on this.

Here's the situation:

I have a Digital Ocean server with an 8 core processor, 16 GB RAM, and 160 GB SSD. The server is running WordPress on nginx + php5-fpm on Ubuntu 14.04.2 LTS.

I've always used Apache in the past, so this is my first foray into nginx.

Anyway, the site is running fine but I'm getting 502 bad gateway errors occasionally, and have had reports that users are also experience this problem on an intermittent basis. I have fairly aggressive edge caching with CloudFlare, to limit the number of hits to the actual original server.

The nginx error logs show a common problem:

2015/07/03 17:38:51 [error] 4283#0: *74154 connect() to unix:/var/run/php5-fpm.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: 173.245.xx.xx, server: www.mydomain.com, request: "GET /path/to/file HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:

I'm finding that these entries correspond with the 502 scenario, but what I can't figure out is how to effective tune the php5-fpm and nginx to support the traffic.

top shows %Cpu(s): fluctuating between 27% and 54% during the several different times that I've been monitoring.

Memory usage also seems fine to me; here's the output from free -h:

             total       used       free     shared    buffers     cached
Mem:           15G        15G       248M        71M       1.3G        11G
-/+ buffers/cache:       2.3G        13G
Swap:           0B         0B         0B

Finally, turning to the nginx configuration, based on what I read, I have the worker_processes set to 8, with 16192 worker_connections. Here's what the /etc/nginx/nginx.conf looks like:

user www-data;
worker_processes 8;
pid /run/nginx.pid;

events {
    worker_connections  16192;
    multi_accept        on;
    use                 epoll;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 15;
    types_hash_max_size 2048;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    gzip on;
    gzip_disable "msie6";
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

And here's the config from /etc/nginx/sites-available/default

fastcgi_cache_key "$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;
    listen 127.0.0.1 default_server;

    root /usr/share/nginx/html;
    index index.php index.html index.htm;

    server_name my.website.com;
    server_name localhost;

    location / {
        try_files $uri $uri/ =404;
    }

    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;

    }
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }

}

Final note: There are virtual hosts running on this machine too, each of which has a similar site config with fastcgi caching, and each is running WordPress.

Adding the config file for one of the vhosts, at the suggestion of @pennywise. I'm leaving my comments inline.

fastcgi_cache_path /etc/nginx/cache/vhostdomain levels=1:2 keys_zone=vhostdomain:100m inactive=60m;

server {
    listen 80;
    listen [::]:80;

    root /usr/share/nginx/www.vhostdomain.com;
    index index.php index.html index.htm;

    server_name www.vhostdomain.com;
    server_namevhostdomain.com;

    access_log   /var/log/nginx/vhostdomain.com.access.log;
    error_log    /var/log/nginx/vhostdomain.com.error.log;

    set $skip_cache 0;

    # POST requests should always go to PHP
    if ($request_method = POST) {
        set $skip_cache 1;
    }   

    # If the URL contains the query strings params cb or clk, bypass the cache
    if ($query_string ~* "cb=|clk=") {
        set $skip_cache 1;
    }

    # If the URL contains the /ad/ directory, bypass cache
    if ($request_uri ~* "/ad/") {
        set $skip_cache 1;
    }   

    # Don't cache uris containing the following segments
    if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
        set $skip_cache 1;
    }   

    # Don't use the cache for logged in users or recent commenters
    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
        set $skip_cache 1;
    }

    location / {
        try_files $uri $uri/ /index.php?$args;
    }    

    location ~ \.php$ {
        try_files $uri =404; 
        include fastcgi_params;
        #fastcgi_pass 127.0.0.1:9000;
        fastcgi_pass unix:/var/run/php5-fpm.sock;

        fastcgi_cache_bypass $skip_cache;
        fastcgi_no_cache $skip_cache;

        fastcgi_cachevhostdomain;
        fastcgi_cache_valid  60m;

    }

    location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
        access_log off; log_not_found off; expires max;
    }

    location = /robots.txt { access_log off; log_not_found off; }
    location ~ /\. { deny  all; access_log off; log_not_found off; }    
}

Adding /etc/php5/fpm/pool.d/www.conf sans comments:

[www]
user = www-data
group = www-data
listen = /var/run/php5-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /
  • You need to read your fpm logs. If nginx says unable to connect, fpm is going to be saying something more specific. – AD7six Jul 5 '15 at 5:59
0

In your config you have two location blocks \.php$
This is most probably the culprit, combine them in one and you should be fine.

Sometimes staring long time at code/config files makes your mind misses something obvious.

  • Thanks for catching that, @pennywise. I have, indeed, been staring at this for a while and missed that. I removed it. It's worth noting, though, that the duplicate detail doesn't exist in the vhosts, which are also seeing the issue. – Andrew Jul 3 '15 at 22:21
  • You can post these configs as well in the question. If you think there is not a problem with them, you might be under DoS. I recently had such a problem on a smaller DO VPS, but I use monit to monitor services and noticed. Check your logs for someone DoS-ing site around/before the time of the error. – pennywise Jul 3 '15 at 22:32
  • Thanks @pennywise. I just added the vhost config to the original question. I'd obviously never rule a DoS out of the question, but the odd thing is that it's intermittent, and nothing seems particularly odd in the log files. A big question that I'm trying to understand is, do my config settings seem reasonable, given the hardware? Perhaps the answer is just that I need to increase to a larger VPS. I just don't know. – Andrew Jul 3 '15 at 22:51
  • In general Nginx docs advise against using if, check this - wiki.nginx.org/IfIsEvil Also you might want to set up monitoring(if you don't already have), with something like munin, so if you have service like php5-fpm down, the daemon will bring it back. Other than that the question is pretty broad. Maybe posting and the php5-fpm will help if not to me, to someone else. It should be located in /etc/php5/fpm/pool.d/www.conf – pennywise Jul 4 '15 at 1:22
  • Thanks again, @pennywise. I've added the www.conf contents to the question. I removed the comments, in the interest of brevity. – Andrew Jul 4 '15 at 18:32

protected by Community Jul 19 '17 at 7:34

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.