Would 360 Linode be sufficient?
thanks.
16 Replies
If you tune your performance a 360 should be sufficient.
Improve php and apache2 performance with apache2-mpm-worker + mod_fcgid + php5-cgi
Solution 1: Run Apache with only one worker process and lots of threads.
Solution 2: Do something clever with your FastCGI config.
Solution 3: (Easiest) Switch to lighttpd or nginx. You'll be surprised how much RAM you can save!
> Apache keeps spawning more and more PHP-CGI processes, all the way up to the number of maximum Apache worker processes!
Is this with modfastcgi or with modfcgid? According to the mod_fcgid homepage
> Strict control on process spawn
Every request handler of Apache (It may be a process, or a thread, depending on the MPM) knows about how many existing fastcgi servers are running (with the help of share memory) , and the request handlers collaborate with each other to make sure over-spawning is not going to happen.
The "problem" with lighttpd (or with apache) is the rewrite rules syntax is not identical.
Perhaps I didn't do enough tweaking, because I was only half serious about setting up Apache. I was just trying it out, as I was building a new linode. I quickly switched over to lighttpd which for me is a hell of a lot easier to configure.
Be that as it may, if you want to use XCache (or APC, or eAccelerator, or any other opcode cacher) on a low-memory server, you want to run exactly one PHP-FastCGI server with a large number of children, instead of several PHP-FastCGI servers with a couple of children each. modfcgid may be better than modfastcgi in managing the number of PHP-FastCGI servers, but it still spawns a handful of them if you don't keep the reins tight. You can run ps -aux -f to find out how your PHP-FastCGI processes are bundled together. One master process with lots of children = good. Several master processes with several children each = bad.
You can search Google for how to translate your CMS's rewrite rules into lighttpd. It's a bit tricky, but a fair amount of information is available for most well-known CMS's. And if you still don't like it, there's nginx
# ps auxf show this (and this is with virtually no traffic)
root 4880 0.0 0.6 13916 3508 ? Ss Jan22 0:00 /usr/sbin/apache2 -k start
www-data 4882 0.0 0.4 13688 2364 ? S Jan22 0:00 \_ /usr/sbin/apache2 -k start
www-data 4941 0.0 6.4 55376 35728 ? S Jan22 3:31 | \_ /usr/lib/cgi-bin/php5
www-data 4943 0.0 6.3 55268 35344 ? S Jan22 3:09 | \_ /usr/lib/cgi-bin/php5
www-data 5291 0.0 2.1 46328 11688 ? S Jan24 0:06 | \_ /usr/lib/cgi-bin/php5
www-data 4884 0.0 1.1 236772 6160 ? Sl Jan22 0:00 \_ /usr/sbin/apache2 -k start
www-data 4886 0.0 1.0 236656 5896 ? Sl Jan22 0:00 \_ /usr/sbin/apache2 -k start
> …you want to run exactly one PHP-FastCGI server with a large number of children, instead of several PHP-FastCGI servers with a couple of children each…
Well, I'm not sure how to configure the number of FastCGI servers to one? To set PHPFCGICHILDREN and PHPFCGIMAX_REQUESTS I believe I need to create a wrapper script
#!/bin/sh
### Set PATH ###
PHP_CGI=/usr/bin/php-cgi
PHP_FCGI_CHILDREN=4
PHP_FCGI_MAX_REQUESTS=100000
### no editing below ###
export PHP_FCGI_CHILDREN
export PHP_FCGI_MAX_REQUESTS
exec $PHP_CGI
# chmod +x /var/www/fastcgi-bin/php.cgi
And, then, for each Directory (in which I want fastcgi support for php) I would do
<directory var="" www="">ScriptAlias /fastcgi-bin/ "/var/www/cgi-bin/"
AddHandler php5-fastcgi .php
Action php5-fastcgi /fastcgi-bin/php.cgi
# ...</directory>
instead of````
FCGIWrapper /usr/lib/cgi-bin/php5 .php
Options +ExecCGI
…
And restart Apache2
/etc/init.d/apache2 restart
````
Yes, you can configure the number of child processes using a wrapper script. (By the way, with lighttpd, you don't need a wrapper script to do that.)
The question is not how many children you've got (15-20 total is plenty for Linode 360), but how many "parents" you've got. (A "parent" is a process from which child processes branch off. You'll recognize it when you see one in the ps output.)
Try applying a moderately heavy load on the server, for example by running ab (apache benchmark) with 10 simultaneous requests to the same PHP script. If PHP spawns more "parents" (each with a few children), you're in trouble. If not, your config is fine.
The reason I like lighttpd is that it keeps memory usage very predictable even under high load (except when there's a memory leak, as oliver mentioned – but these cases are rare nowadays.) My lighttpd server with ~20 PHP children (with XCache) uses ~150M of memory all the time, regardless of whether I have 20 visitors a day or 2000 visitors a day.
Lighttpd is easier to setup (in my opinion) very well documented, has a good user base and a good IRC channel.
@oliver:
fyi, nginx works perfectly fine with fcgi (and xcache) as well and it doesn't leak memory as lighttpd does.
No memory leak over here, have fast-cgi and xcache running.
But According to How many php CGI processes will lighttpd spawn
> If you are using an opcode cache such as eAccelerator, XCache or similar it's advisable to keep max-procs at a very low number (1 is perfectly fine) and raise PHPFCGICHILDREN instead. Those opcode caches will create a separate memory space for each parent process, otherwise, which is not what one would call "efficient memory usage" in that case.. If you leave max-procs at 4, you'll end up with four separate opcode memory cache segments.]lighttpd fastcgi documentation
I'm running Ubuntu. I have /etc/lighttpd/conf-available/10-fastcgi.conf
server.modules += ( "mod_fastcgi" )
## Start an FastCGI server for php (needs the php5-cgi package)
fastcgi.server = ( ".php" =>
((
"bin-path" => "/usr/bin/php-cgi -c /etc/php5/cgi/php.ini",
"socket" => "/tmp/php.socket",
"max-procs" => 1,
"idle-timeout" => 20,
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "4",
"PHP_FCGI_MAX_REQUESTS" => "10000"
),
"bin-copy-environment" => (
"PATH", "SHELL", "USER"
),
"broken-scriptfilename" => "enable"
))
)
@iQwerty:
No memory leak over here, have fast-cgi and xcache running.
i heard the memory leak situation got much better so there is probably little difference and you can pick whatever you prefer.
i set up my server ~1yr ago and did a bit of research about lighttpd vs. nginx and back then i found quiet a few posts complaining about the memory leaks so i went with nginx (and i'm very happy with it).
this here is a pretty good (but also somewhat outdated) summary of lighttpd vs. nginx:
@iQwerty:
No memory leak over here, have fast-cgi and xcache running.
Actually, the latest version (1.4.20, or 1.4.19-5 if you prefer the Debian/Ubuntu binary) still leaks memory in one particular case. If you allow users to download large files through a PHP script, and the script uses readfile() to send the file to the user, lighttpd caches the entire response in RAM and never releases it afterwards. So if somebody is downloading a 50MB file with PHP readfile(), your lighty process grows by 50MB. If 10 users simultaneously download a 50MB file, your lighty process grows by 500MB. Not good! I personally ran into this problem a few weaks ago, and it wasn't pretty.
But there's an easy workaround for this particular memory leak. Instead of using readfile() in your PHP script, you can have your PHP script send a custom HTTP header called X-LIGHTTPD-send-file. Lighttpd will intercept this header and send the named file to the client on your behalf, modifying the value of Content-Length accordingly. Then the custom header will be removed, so your clients will never know the absolute path of the file on your server. This method performs much better – after all, lighttpd is designed to quickly send large static files -- and it doesn't leak memory at all (at least in the latest version). I've been using it to serve large files since the little incident a few weeks back, and lighttpd+PHP could serve 25GB of large media files in a day without any memory leak.
This is how you do it in PHP:
header('X-LIGHTTPD-send-file: /absolute/path/to/file']);
You also need to enable send-file in your FastCGI configuration. Notice the "allow-x-send-file" directive below.
fastcgi.server = ( ".php" =>
((
"bin-path" => "/usr/bin/php-cgi",
"socket" => "/tmp/php.socket",
"max-procs" => 1,
"idle-timeout" => 30,
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "8",
"PHP_FCGI_MAX_REQUESTS" => "10000"
),
"bin-copy-environment" => (
"PATH", "SHELL", "USER"
),
"broken-scriptfilename" => "enable",
"allow-x-send-file" => "enable"
))
)
And if you're still worried about undocumented memory leaks, here's another workaround. Run the following command every now and then, preferably using cron.
ps -C lighttpd -o rss=
This will return a single integer value representing the size (in kilobytes) of your lighttpd process. Pass the value to a little script written in your favorite scripting language. From your script, restart lighttpd if the value exceeds a preset threshold.
But then, I'm seriously considering a move to nginx
I'm using ubuntu 8.10 with nginx/fastcgi running vBulletin with vBSeo as if I had a full server
It's fast and easy to setup.
You can follow this guide
> server {
listen 80;
server_name example.com;
rewrite ^/(.*)
http://www.example.com/$1 permanent;}
server {
listen 80;
server_name
www.example.com ;accesslog /home/www/publichtml/example.com/logs/access.log;
errorlog /home/www/publichtml/example.com/logs/error.log;
root /home/www/public_html/example.com/public/;
index index.html index.php;
vBulletin & vBSeo Restricted
location ~ /forum/(admincp/|modcp/|vbseocp.php).* {
root /home/www/public_html/example.com/public/;
auth_basic "Restricted";
authbasicuser_file htpasswd;
}
FastCGI
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgiparam SCRIPTFILENAME /home/www/publichtml/example.com/public$fastcgiscript_name;
include fastcgi_params;
}
Expire Header for Images, JS and CSS
location ~* ^.+.(jpg|jpeg|gif|png|ico|css|js)$ {
root /home/www/public_html/example.com/public/;
access_log off;
expires 30d;
}
vBSeo - Start
location /forum/ {
rewrite ^/forum/((urllist|sitemap).*.(xml|txt)(.gz)?)$ /forum/vbseositemap/vbseo_getsitemap.php?sitemap=$1 last;
if (!-e $request_filename) {
rewrite ^(/forum/.*)$ /forum/vbseo.php last;
}
}
if ($request_filename ~ ".php$" ) {
rewrite ^(.(admincp/|modcp/|vbseocp.php).) $1 last;
rewrite ^(/forum/.*)$ /forum/vbseo.php last;
}
vBSeo - End
}
This setup as an adicional security layer usgin http_auth
Make sure to edit the path's.
Using PHP with fcgid & suexec on Apache 2.2
Add these to two settings to the /etc/apache2/conf.d/php-fcgid.conf set up shown in Using PHP with mod_fcgid