Posts Tagged ‘lighttpd’

Lighttpd + mod_magnet on CentOS (64 bit)

Tuesday, August 18th, 2009

After about an hour of tinkering around on google and in the terminal here is what you need to do:

wget http://www.lua.org/ftp/lua-5.1.2.tar.gz
tar xfz lua-5.1.2.tar.gz
cd lua-5.1.2
nano src/Makefile

Replace:

 CFLAGS= -O2 -Wall $(MYCFLAGS) 

With:

 CFLAGS= -O2 -Wall -fPIC $(MYCFLAGS) 
make linux install

wget http://luaforge.net/frs/download.php/2384/md5-1.0.2.tar.gz
tar xfz md5-1.0.2.tar.gz
cd md5-1.0.2
make
make install
cd ..
wget http://luaforge.net/frs/download.php/1678/luazlib-0.0.1.rar

wget wget http://www.rarlab.com/rar/unrar-3.7.7-centos.gz
gunzip unrar-3.7.7-centos.gz
chmod +x unrar-3.7.7-centos
./unrar-3.7.7-centos x luazlib-0.0.1.rar
cd luazlib-0.0.1
make
make install

export LUA_CFLAGS="-I/usr/local/include"
export LUA_LIBS="-L/usr/local/lib -llua"

cd LIGHTTPD_DIRECTORY
./configure -with-lua
make
make install

All done!

Thanks to:
http://gadelkareem.com/2007/09/17/dynamic-content-caching-using-lighty-mod_magnet-lua/ && http://www.verlihub-project.org/doku.phpid=howto_install_lua_library_on_64_bit

Lighttpd, Mongrel, Ruby on Rails, and Lighttpd Proxy backend Performance Comparison

Wednesday, March 18th, 2009

First I was kind of surprised at the lack of performance comparisons people have made between the different lighttpd proxies with a rails/mongrel cluster backend and which ones would be best.

Lets start off the the specs of the box:
Intel Atom 330 CPU
Standard 7,200RPM HDD
CentOS 5.2
2GB Ram
Lighttpd with 3 Mongrel Clusters running an online food ordering system I wrote (MySQL + Rails)

Other than that there was nothing special. I’ve done no kernel tweaking or any other performance optimizations with Lighttpd or any other part of the system.

Result Data / Proxy Type / Result

Requests Per Second

requests-per-second lighttpd rails mongrel cluster

Hash 21.41
Round-Robin 39.73
First 40.07

Hash is the loser in the proxy test over all. The requests per second capabilities of it were nearly half of what Round-Robin and First were able to achieve with the 3 node mongrel cluster running in the background. This is to be expected though since the Hash algorithm (so far as I understand it) will send the same url requests to the same proxy to help caching, whereas round-robin and first proxy methods balance it over the 3 nodes (or however many you have running).

Total Time Taken

time-taken

Hash 467.20772
Round-Robin 251.725273
First 249.578092

Round-Robin are nearly neck and neck with the total time taken to return 10,000 hits with 250 concurrency, while the hash algorithm still lags far behind.

Transfer Rate

transfer-rate

Hash 59.74
Round-Robin 110.84
First 111.79

Since only one mongrel cluster is able to serve all the requests in Hash, where as 3 are able to in the Round Robin and First tests, the transfer rate is much higher. I’m sure this could have been improved even further had I put all static files like style sheets and images on a separate instance so Mongrel could just worry about the rails files instead of rails + static, but since this site only has about 5 or so images, I did not think it necessary.

Longest Request

longest-request

Hash 22795
Round-Robin 17132
First 11936

This is the result data where First comes through, beating Round Robin by a good portion (~6 seconds) and proving to be the quickest to serve up the website.

Load Averages

load-avg

Hash 1.15
Round-Robin 3.15
First 3.28

Since Hash is only using one mongrel cluster instance, instead of the 3, the CPU load was much lower. However, Round Robin and First were very close, but I believe that when comparing the request times for First and Round Robin, First is worth the very miniscule increase in server load.

Notes on Apache + Passenger + Mod_Rails + Phusion mumbo jumbo

I’m not going to claim to be an Apache expert, but one thing I’m positive about is Apache’s slowness…. with everything. I go nuts when pages don’t load fast because of server software and when I tried out Phusion Passenger / Mod Rails and apache (whatever you want to call it)… even with Enterprise ruby installed, it was still incredibly slow (noticable to me while just randomly hitting refresh).

While Phusion makes deploying rails apps a bit simpler / easier to add new apps, in the long run I view it as detrimental should your application ever grow. The reason I chose to work with mongrel and Lighttpd (although Nginx is another viable option) is because I looked at sites like GitHub and EngineYard (a large rails host) and checked a few of their web server headers and found them to be running Nginx (with a Mongrel backend I’m assuming).

If you’re worried about memory I did not notice much of a difference between what my application used while in Phusion vs Mongrel, but one of the HUGE differences I did notice was when running `ab -n 1000 -c 10` the load would shoot up to 5, while Lighttpd’s would barely hit .89. I didn’t bother attempting `ab -n 10000 -c 250` with apache since I didn’t want the box to melt/halt/be-killed-by-apache. If load isn’t an issue and you’re a die-hard Apache fan, stick with Phusion, but my tests put it way behind Lighttpd+Mongrel in comparison.

~~~~~~~~~~~~~~~~~~~~

If anyone has any suggestions for other analytic’s to test let me know! I’d love to do some more research regarding this and post my findings since there seems to be a lack of them on google.

Proxy: Hash Raw Data

Server Port:            80

Document Path:          /
Document Length:        2495 bytes

Concurrency Level:      250
Time taken for tests:   467.20772 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      28570261 bytes
HTML transferred:       24950000 bytes
Requests per second:    21.41 [#/sec] (mean)
Time per request:       11675.520 [ms] (mean)
Time per request:       46.702 [ms] (mean, across all concurrent requests)
Transfer rate:          59.74 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   3.2      0      35
Processing:    72 11547 1056.2  11694   22795
Waiting:       72 11547 1056.2  11694   22795
Total:         72 11548 1055.2  11694   22795

Percentage of the requests served within a certain time (ms)
  50%  11694
  66%  11717
  75%  11739
  80%  11794
  90%  11887
  95%  11907
  98%  11928
  99%  11942
 100%  22795 (longest request)

Proxy Type: Round Robin Raw Data

Server Port:            80

Document Path:          /
Document Length:        2495 bytes

Concurrency Level:      250
Time taken for tests:   251.725273 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      28570213 bytes
HTML transferred:       24950000 bytes
Requests per second:    39.73 [#/sec] (mean)
Time per request:       6293.132 [ms] (mean)
Time per request:       25.173 [ms] (mean, across all concurrent requests)
Transfer rate:          110.84 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   3.2      0      37
Processing:   103 6192 2439.0   6653   17132
Waiting:      103 6192 2439.0   6653   17132
Total:        103 6192 2438.5   6653   17132

Percentage of the requests served within a certain time (ms)
  50%   6653
  66%   7665
  75%   8169
  80%   8495
  90%   9038
  95%  10066
  98%  10377
  99%  10468
 100%  17132 (longest request)

Proxy Type: First Raw Data

--- Proxy: First 3.28 ---
Server Port:            80

Document Path:          /
Document Length:        2495 bytes

Concurrency Level:      250
Time taken for tests:   249.578092 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      28570190 bytes
HTML transferred:       24950000 bytes
Requests per second:    40.07 [#/sec] (mean)
Time per request:       6239.453 [ms] (mean)
Time per request:       24.958 [ms] (mean, across all concurrent requests)
Transfer rate:          111.79 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   3.3      0      37
Processing:   307 6169 621.6   6256   11936
Waiting:      306 6168 621.7   6256   11936
Total:        307 6169 620.0   6256   11936

Percentage of the requests served within a certain time (ms)
  50%   6256
  66%   6450
  75%   6550
  80%   6598
  90%   6734
  95%   6795
  98%   6858
  99%   6897
 100%  11936 (longest request)

Setting up a Development Machine With PHP, Lighty, Ruby, and Python

Friday, February 6th, 2009

After getting my new mac book pro I had an extra laptop sitting around… so why not turn it into a little low power development box My goal is to get LigHTTPD, Ruby on Rails, PHP, MySQL, and Python to work together with lighty.

Step 1: Install Lighty

wget http://www.lighttpd.net/download/lighttpd-1.4.20.tar.gz

gunzip lighttpd-1.4.20.tar.gz

tar -xvf lighttpd-1.4.20.tar

cd lighttpd-1.4.20

./configure

Here is a list of errors / fixes encountered while doing this from a bare-bones net install. Run ./configure after each one to see what else is broken / needs to be installed.

Error Fix
configure: error: no acceptable C compiler found in $PATH yum install gcc
configure: error: pcre-config not found, install the pcre-devel package or build with –without-pcre yum install pcre*
configure: error: zlib-headers and/or libs where not found, install them or build with –without-zlib yum install zlib*
configure: error: bzip2-headers and/or libs where not found, install them or build with –without-bzip2 yum install bzip*

Copy the lighttpd conf to somewhere easy to find:

cp doc/lighttpd.conf /home/lighttpd.conf
make
make install

Now onto PHP:

yum install php

That’s done easily enough. Verify it’s installed:

root@localhost lighttpd-1.4.20]# php -v
PHP 5.1.6 (cli) (built: Jul 16 2008 19:53:00)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies

Verify python’s installed:

[root@localhost lighttpd-1.4.20]# python
Python 2.4.3 (#1, May 24 2008, 13:47:28)
[GCC 4.1.2 20070626 (Red Hat 4.1.2-14)] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
>>>

(hit ctrl+d to exit the python interpreter)

Install MySQL:

yum install mysql*

( I just install them all as this is a dev server anyways )

Everything went okay so now onto Ruby

yum install ruby*

Everything went okay, and all the software is installed. Now it’s time to configure them.

First lets get PHP working with Lighty.

nano /etc/php.ini

hit CTRL+V to page down real quick…. at the bottom of the file add:

cgi.fix_pathinfo = 1

Save the file and exit.

First:

whereis php-cgi

It should be in /usr/bin/php-cgi

Second:

adduser dev
echo ” >> /home/dev/index.php

Now lets open lighttpd.conf

nano /home/lighttpd.conf

Un-comment the fastcgi, rewrite, and redirect lines.

Lets change the document root to be /home/dev/

Lets also make sure we change the user of Lighty:

## change uid to (default: don’t care)
server.username = “dev”

## change uid to (default: don’t care)
server.groupname = “dev”

Now scroll down and add this to the bottom:

fastcgi.server = ( “.php” => ((
“bin-path” => “/usr/bin/php-cgi”,
“socket” => “/tmp/php.socket”
)))

Exit and save the file.

Lets try starting Lighty:

lighttpd -f /home/lighttpd.conf
2009-01-27 15:02:20: (log.c.84) opening errorlog ‘/var/log/lighttpd/error.log’ failed: No such file or directory
2009-01-27 15:02:20: (server.c.888) Opening errorlog failed. Going down.
mkdir /var/log/lighttpd
touch /var/log/lighttpd/error.log; touch /var/log/lighttpd/access.log; chown -R dev:dev /var/log/lighttpd;

Start lighty again and you’re all set!

Now lets see if PHP worked…. browse to your dev server’s ip and you should see the php info page, and all is well.

Now lets get Ruby working
Now lets get Ruby-FCGI

wget http://sugi.nemui.org/pub/ruby/fcgi/ruby-fcgi-0.8.6.tar.gz; gunzip ruby-fcgi-0.8.6.tar.gz ; tar -xvf ruby-fcgi-0.8.6.tar;
cd ruby-fcgi-0.8.6
ruby install.rb config

This fails so lets check for errors:

[root@localhost ruby-fcgi-0.8.6]# cat ext/fcgi/mkmf.log
have_header: checking for fcgiapp.h… ——————– no

“gcc -E -I. -I/usr/lib/ruby/1.8/i386-linux -I/root/tmp/ruby-fcgi-0.8.6/ext/fcgi -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector –param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -Wall -fno-strict-aliasing -fPIC conftest.c -o conftest.i”
conftest.c:1:21: error: fcgiapp.h: No such file or directory
checked program was:
/* begin */
1: #include
/* end */

——————–

have_header: checking for fastcgi/fcgiapp.h… ——————– no

“gcc -E -I. -I/usr/lib/ruby/1.8/i386-linux -I/root/tmp/ruby-fcgi-0.8.6/ext/fcgi -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector –param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -Wall -fno-strict-aliasing -fPIC conftest.c -o conftest.i”
conftest.c:1:29: error: fastcgi/fcgiapp.h: No such file or directory
checked program was:
/* begin */
1: #include
/* end */

——————–

Fix:

wget http://www.fastcgi.com/dist/fcgi-2.4.0.tar.gz; gunzip fcgi-2.4.0.tar.gz; tar -xvf fcgi-2.4.0.tar; cd fcgi-2.4.0
./configure
make
make install

Now lets try ruby again!

ruby install.rb config
ruby install.rb setup
ruby install.rb install

Done :) .

Now install gem: wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz

Gunzip, tar -xvf it and then compile it:

run

ruby setup.rb

That should install Gem for you.

Next you need to install Rails, which can be done very easily now

gem install rails

When initially doing this I ran into an issue of Rails complaining (specifically when running the ruby script/server command) about not being able to find the specific database information.

First: start a project

cd /home/
mkdir ruby
cd ruby
rails demo

That creates your first demo project.

Now lets make a controller:

ruby script/generate controller hello
exists app/controllers/
exists app/helpers/
create app/views/hello
exists test/functional/
create app/controllers/hello_controller.rb
create test/functional/hello_controller_test.rb
create app/helpers/hello_helper.rb

Start the development server:

ruby script/server
=> Booting Mongrel (use ’script/server webrick’ to force WEBrick)
=> Rails 2.2.2 application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with development environment…
** Rails loaded.
** Loading any Rails specific GemPlugins
** Signals ready. TERM => stop. USR2 => restart. INT => stop (no restart).
** Rails signals registered. HUP => reload (without restart). It might not work well.
** Mongrel 1.1.5 available at 0.0.0.0:3000
** Use CTRL-C to stop.

Browse to http://yourserverip:3000/hello
Error:
MissingSourceFile in HelloController#index

no such file to load — sqlite3

RAILS_ROOT: /home/ruby/demo

To fix:

Hit Ctrl+C to stop the web daemon, then:

cd config
nano database.yml

Change it to read something like:

development:
adapter: mysql
encoding: utf8
database: ruby
username: root
password: PASSWORD

Now to install Ruby MySQL:

gem install mysql — \
–with-mysql-include=/usr/include/mysql \
–with-mysql-lib=/usr/lib64/mysql

Now try running the server again

ruby script/server

and browse to http://yourserverip:3000/hello and you should get another error:
Unknown action

No action responded to index. Actions:

To fix, first exit the web server (Ctrl+C), then:

cd app
cd controllers
nano hello_controller.rb
# Change file to look like this:
class HelloController < ApplicationController
def index
render :text => “Hello World”
end
end

Save and exit, and then:

cd ../../;
ruby script/server

Browse to http://yourserverip:3000/hello

And voila, Rails! You should see: “Hello World!”

I did however find a simpler way to run this using Mongrel:

gem install mongrel

Wait a few for it to install and then just change to your demo directory:

mongrel_rails start -d

Now to setup a Python (via Django)

wget http://www.djangoproject.com/download/1.0.2/tarball/
tar -xzvf Django-1.0.2-final.tar.gz
cd Django-1.0.2-final
python setup.py install

cd /home/
mkdir python
cd python
django-admin.py startproject demo
cd demo
python manage.py runserver 0.0.0.0:8000

Browsing to http://yourserverip:8000/ you should see:

It worked!
Congratulations on your first Django-powered page.

You’re now all set up with one server that can serve PHP, Python, and Ruby pages.

This is by no means a programming tutorial, I was simply showing how to get the basics set up for people to start quickly learning PHP, Python (web programming), and Ruby on Rails.

Please leave a comment if you spot a bug / error somewhere!

© 2008 Josh Rendek.