How to handle 1000s of concurrent users on a 360MB VPS
markmaunder.com
markmaunder.com
I like living on the bleeding edge, so I do varnish -> mongrel2 <-> apps instead... but varnish -> nginx <-> apps or varnish -> apache <-> apps seem equally reasonable. The key is caching and being able to handle slow users without tying up your app. All three of these setups do that. nginx to apache only saves your app server; it doesn't do much caching.
From what I gather, varnish uses a threaded model with 1 thread per connection which is what nginx solves. So it might make sense to put nginx in front of varnish so you get high concurrency with great caching.
Nginx does offer some caching but I've played with it in high load environments and wasn't impressed with the performance.
I love varnish. Hard.
Any help would be great, thank you!
But for using it directly with a application server I just use it as a backend and handle Cache-Control headers directly in the app. As for static files I haven't really handled them but caching them forever seems like a good enough option. It seems to work great and I haven't discovered any problems yet and with grace-time in varnish you could even survive a backend dying if it's serving out fairly static content.
This makes things served through my sinatra application/unicorn have session cookies, even if it's something like a css file. I'm specifically stripping them out at this point but it shouldn't be needed. I don't know enough about Rack yet to fix the bug myself and way too busy with exams anyway.
Thanks.
True loadtesting requires quite a bit of thought to go into your test-setup, but for those kind of differential tests it is usually enough to make sure that your test-client and network connectivity to the application are constant factors and good enough to generate a decent load.
You won't catch the subtleties with those tests, but you will normally catch the 'oops, my perfomance dropped by 50%' type of errors. The subtleties you can then work out during normal operations.
Thanks for all the love today guys. Have an awesome memorial day weekend if you're in the States.
I've been using nginx for about 2 years and it performs so much better than Apache.
I'm not using Apache as a backend though, I use FastCGI. It performs even better.
I think the only reason people use nginx -> Apache mod_php is because there's a lot of documentation and knowledge about Apache. nginx requires a little bit different mental model how HTTP requests are served but it's worth it.
EDIT: You can think of PHP5-FPM as Apache+mod_php but only serving PHP requests. So nginx handles static files and URL magic and when there's request for PHP, it passes it to PHP5-FPM, just like it would pass it to Apache+mod_php. This is oversimplifed but it's kind of like that.
I have nginx configured with php-fpm to use sockets to communicate between each other.
Just use nginx and php-fpm (or php-cgi/fcgi).
Are there any performance benefits to having Apache as well?
The only benefits I can think of offhand would be if you had a requirement for something that Apache specifically provided, or custom modules you needed run. Something like suphp, modsecurity, or shared hosting configuration, etc. All policy type stuff, not performance.
In fact by not using PHP-FPM you lose out on awesome stuff like the slow log!
I speak of Wordpress and database-backed PHP applications of its ilk. Wordpress loves to spray MySQL in a thick stew of queries for every single page load.
Without sensible -- preferably aggressive -- caching, your Wordpress site will die in the arse.
My setup generates cached .gz files, which nginx can serve directly. It flies. It didn't used to.
I've used Varnish for some high-traffic Wordpress sites by sitting it in front of Apache running Wordpress. With well planned TTLs, and logged-in cookie detection, most of the inconveniences of caching can be eliminated.
Also, using Disqus or similar services for comments will be helpful. You wont have to worry about comments not showing up until the cache clears, leading to confused users. That is, if you use the javascript implementation of these comment services.
Alternatively, plugins like WP Super Cache have automatic post cache flushing if there are updates, and you can also tell it to bypass cache for logged in users. But it is IO-bound.
It supports disk-based caches and memcached.
Moreover, issues with slow clients often can be solved by raising the TCP send buffer size. As long as the response size is less than the send buffer size, it really doesn't matter how slow the client is: write() will return immediately, leaving the webserver free to serve the next request. Getting the data to the client then becomes the kernel's responsibility.
> SO_SNDBUF: [...] The default value is set by the wmem_default sysctl and the maximum allowed value is set by the wmem_max sysctl.
You can't use sysctl under OpenVZ. QED.
nginx servers up static content (e.g. if you are using WP-SuperCache and it's generating those static cache files for you, JS, CSS, images, etc.) then you configure a pool of warmed up PHP VM instances via PHP-FPM (Check /etc/php5/php-fpm or some equiv dir on your server).
Then you setup a rule that directed PHP requests to the FPM service, that would probably look something like this in nginx:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/mysite.com/$fastcgi_script_name;
include fastcgi_params;
}and instead of adding the layer of Apache servicing the PHP requests, you are having nginx pass through the PHP requests directly to PHP processes to run.
Going from an Apache2 + FCGID configuration (somewhat similar to this, but with Apache) to nginx, I saw a 75% drop in server load.
I'm almost certain this still isn't a totally tweaked out setup that someone more familiar with this process could do better, but for my needs it took my server crashing under load no matter what I did, to typically being idle most of its life (~900k/month pageviews)
So I'm a big fan of nginx. I'm not saying you couldn't configure Apache to do the same... just 5 years of attempts to do so never got me anywhere with it.
Interesting comments on the original thread.
Is it possible to set this up where nginx and apache communicate via a socket?
And that's using Apache!
Minus two for an on topic question?
Me, I use php-fastcgi daemons with APC and nginx, with no Apaches. The speed bump and the drop in memory requirements were staggering. The main 'cost' is figuring out how to convert rewrite rules from one type to another, but if you're using a widely-known app, someone's already done it for you.
I suggest the worker mpm if you don't want to switch to nginx.
This is partly because when a table contains a TEXT field, MySQL performs all joins against that table on disk, regardless of what fields you're selecting or joining on.
Which is a problem for, oh, I dunno, every PHP blog engine / bulletin board / CMS ever.
My personal (anecdotal) experience shows that nginx is amazingly fast. Some nginx configs can impact performance if you aren't careful (I am thinking of try_files vs if-tests[1]), and there are various nginx tunables (worker process count, cpu affinity, etc) as well.
I have personally seen issues with apachebench when there are lots of connections (not to mention linux system tunables such as max file descriptors!), iptables state tracking, etc...
This is another interesting benchmark between nginx, lighttpd and varnish: http://nbonvin.wordpress.com/2011/03/24/serving-small-static... Even on a Core i3 laptop nginx can handle 70k req/s
Moving forward to the actual issue. Something is really broken into your configuration. The first thing is the file AIO. But this is Linux's fault. The file AIO is broken by design. It bypasses the kernel file cache. Which is a pretty large performance hit per se. The second thing is the fact that I can easily get 55k req/s on a Q9400 with nginx, without even touching the sysctl parameters of a Ubuntu 10.04 x86_64. The only actual difference is nginx 1.0.x instead of the ancient 0.7.x you would actually find into the standard repos aka the production version I publish into my company's private repo.