Category Archives: Open Source

Performance Tuning Lighty – Feed2JS

How do you run a site that gets roughly 3 million daily hits, while not killing server performance?  Well, the first step is to get ride of Apache – far too resource intensive to handle the load.  Lighttpd is a light weight webserver designed to do just this!  I recently spent some time performance tuning the site, and wanted to share the config tweaks here in the event that it may help someone else.

The server we are running is  Debian Lenny 64bit box, hosted by SoftLayer.  Before I even got to tuning Lighty, I was getting synflood errors.  I dug into it and discovered the hosting provider had put some checks in place to help prevent DoS attacks.  In “/etc/sysctl.conf” I change the following:

net.ipv4.tcp_syncookies=0
net.ipv4.tcp_synack_retries = 5

Now that I solved that problem – the next thing I went to do was make sure there would not be a restriction on the number of file handlers that the web process could use.  To set this up, I added the following in “/etc/security/limits.conf“:

www-data        soft    nofile          4096
www-data        hard    nofile          10240

This will allow the lighttpd user (www-data) to have a soft limit of 4096 handlers, with a hard limit of 10240.

In order for this file to work, you have to enabled it in PAM.  In “/etc/pam.d/su“, find and uncomment the following line:

session    required   pam_limits.so

There are two main config files that we need to work with – the first is the main config “/etc/lighttpd/lighttpd.conf” which does not have alot of changes.  The following were added to tune performance:

server.max-fds = 40000
server.max-keep-alive-requests = 100
server.max-keep-alive-idle = 2
server.max-connections = 10000

I also enabled the “compress” and “expire” modules.  The compress module is using the default settings:

#### compress module
compress.cache-dir          = "/var/cache/lighttpd/compress/"
compress.filetype           = ("text/plain", "text/html", "application/x-javascript", "text/css")

Now, in order to take advantage of this, you need to enable compression in php.  Since this is using the cgi build of php, the file to change is “/etc/php5/cgi/php.ini“.  There is only one option to change here:

zlib.output_compression = on

In PHP, I also enabled APC for opcode caching.  I currently have this running with the following settings:

apc.enabled=1
apc.shm_size=128M

The expires module is currently configure as follows:

expire.url                  = ( "/" => "access 6 hours")

The second lighttpd config file that needs to be changed is the fastcgi config “/etc/lighttpd/conf-enabled/10-fastcgi.conf“:

fastcgi.server    = ( ".php" =>
((
"bin-path" => "/usr/bin/php-cgi",
"socket" => "/tmp/php.socket",
"max-procs" => 4,
"idle-timeout" => 20,
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "16",
"PHP_FCGI_MAX_REQUESTS" => "10000"
),
"bin-copy-environment" => (
"PATH", "SHELL", "USER"
),
"broken-scriptfilename" => "enable"
))
)

Well, that about does it.  Hopefully the above notes and insight help others out!  I could not have done this without the help of the Lighttpd community – they are great and always willing to help!

The Quest to Conquer the PHP Session Timeout

PHP sessions are handy little things, however it’s a bit tricky to correctly get a custom timeout to work correctly. There are a few key ini settings:

session.gc_maxlifetime -This setting (in seconds) tells the PHP garbage collector how long to keep the session valid.  The default is 24 minutes.

session.gc_probability – The probability that the garbage collector will run and clean up old session data.  The default value is 1.

session.gc_divisor – The divisor to use with the probability.  The default value is 100.

session.save_path – The path for session values to be saved.  The default is /tmp, however it is important to change this to a custom folder for the application – especially if you are in a shared hosting enviorment.  The garbage collector does not discriminate, and it will delete ANY session data that is older than the set limit, not just ones that correspond to your application.

session.cookie_lifetime – How long to keep the cookie written to the client machine valid.  Defaults to 0, which means the cookie will expire at the end of the broswer session (at logout or when closing the broswer).

Now, before you start anything, make sure you have a writable folder setup for your application that you can use to store your session data.

Start your session with something smiliar to:

ini_set(‘session.gc_maxlifetime’, ‘86400’);
ini_set(‘session.gc_divisor’, ‘1’);
ini_set(‘session.gc_probability’, ‘1’);
ini_set(‘session.cookie_lifetime’, ‘0’);
ini_set(‘session.save_path’, /path/to/sessions/myapp);
session_name(‘myapp’);
session_start();

Setting the above configuration well make sure your session files are saveed in a seperate folder, they will expire in 24 hours, and the garbage collector will run everytime session_start is called to cleanup expired sessions.

The problem with alot of other infomormation is that they will suggest setting the cookie_lifetime to be the same as the gc_maxlifetime.  The problem with this is that when the cookie value is set, the expiration date is not updated as the user continues to be active in the application.  The session data on the server side is updated.  So, if this is the case, after the value of cookie_lifetime has expired, even if the session data on the server was just updated, your session will be invalid, and you will be required to login again.

I hope that this post will help someone else in the quest to conquer the php session timeout.  It definitely is not very clear, and can be very confusing!

Htaccess Authentication Manager Released!

The initial release of the Htaccess Authentication Manager (htauthman) has just been zipped up and published to SourceForge. Everyone is encouraged to try it out and let me know if you run into any issues! It has been heavily tested, and is already in use so it should be pretty rock solid. It does require php 5.2, but that’s about it!

A special thanks to Jamie Overman for whipping up the design!

SourceForge Project: http://sourceforge.net/projects/htauthman/