lighttpd 安装

编译安装
      ./configure --prefix=/usr/local/lighttpd
      make
      make install
    2,编译后配置
      cp doc/sysconfig.lighttpd /etc/sysconfig/lighttpd
      mkdir /etc/lighttpd
      cp doc/lighttpd.conf /etc/lighttpd/lighttpd.conf
 
      如果你的Linux是RedHat/CentOS,那么:
      cp doc/rc.lighttpd.redhat /etc/init.d/lighttpd
      如果你的Linux是SuSE,那么:
      cp doc/rc.lighttpd /etc/init.d/lighttpd
      其他Linux发行版本可以自行参考该文件内容进行修改。
      然后修改/etc/init.d/lighttpd,把
      LIGHTTPD_BIN=/usr/sbin/lighttpd
      改为
      LIGHTTPD_BIN=/usr/local/lighttpd/sbin/lighttpd
 
      此脚本用来控制lighttpd的启动关闭和重起:
      /etc/init.d/lighttpd start
      /etc/init.d/lighttpd stop
      /etc/init.d/lighttpd restart
    3,配置
      修改/etc/lighttpd/lighttpd.conf
      1)server.modules
      取消需要用到模块的注释,mod_rewrite,mod_access,mod_fastcgi,mod_simple_vhost,mod_cgi,      mod_compress,mod_accesslog是一般需要用到的。
 
      2)server.document-root, server.error-log,accesslog.filename需要指定相应的目录
         server.document-root        = "/www/phc/html/"

 

 

-----------auto run---

chkconfig --add lighttpd

chkconfig --level 35 lighttpd on

 

-------------------------------------

lighttpd虚拟目录的配置

命令为alias.url,使用时只需要在lighttpd.conf的虚拟主机段加上

alias.url = ( "/img/" => "/path/to/img/" )

即可完成配置,启动时如果出现错误类似

unknown config-key: alias.url

则需要在lighttpd.conf的server.modules段设置加载mod_alias模块

server.modules = ("mod_rewrite", "mod_redirect")

加入

server.modules = ("mod_alias", "mod_rewrite", "mod_redirect")

--------------------------------------------------------

 

 

因為 lighttpd
已經用的蠻久了,所以都會有一份制式的 lighttpd.conf (精簡到「會動」而已) 拿來用,今天拿這個版本丟檔案的時候想用 Squid
當 reverse proxy 放在前面,結果發現永遠都是 TCP_MISS,看 HTTP Header 後發現 lighttpd 沒送 Last-Modified 欄位,應該是這樣造成 Squid 不會存下來。

lighttpd 不送 Last-Modified 的原因後來查出是因為沒有指定 MIME Type。這是一個 feature,而不是 bug (所以不會修正),所以我除了把線上得版本加上以外,在公版的 lighttpd.conf 裡也把 mimetype.assign 加上,這樣就正常了

-------------------------------------------------------------------------------------------

优化配置

server.chroot
使用chroot提高安全性时,web服务器的root目录。建议使用。

server.username = "..." server.groupname = "..."
放弃root权限。

dir-listing.activate
如果没有找到index文件就列出目录。建议disable。

server.event-handler
设置时间处理方式。Default: "poll"。Bsd上默认就可以,使用kqueue反而影响了效率。原因不明。以下是各种操作系统对应的方式:
OS Method Config-Value
all select select
Unix poll poll
Linux 2.4+ rt-signals linux-rtsig
Linux 2.6+ epoll linux-sysepoll
Solaris /dev/poll solaris-devpoll
FreeBSD, ... kqueue freebsd-kqueue
server.max-request-size
maximum size in kbytes of the request (header + body)
Default:

server.max-worker
lighttpd默认只启动一个进程工作,但也支持apache那样启动多个进程,我的实验显示启动多个进程同时工作时并不能提高性能。

server.max-keep-alive-requests
这一条比较关键,对性能的影响比较大。在一个keep-alive会话终止连接前能接受处理的最大请求数。Default: 128,对一个高负载的应用来说是不够的。我用了4000。

server.max-keep-alive-idle
一个空闲keep-alive连接被丢弃前,存在的的最大秒数。Default: 30。

server.error-handler-404
页面找不到时候的处理,对性能没什么影响,指出来一下,例如:
server.error-handler-404 = "/error-404.php"

server.max-fds
因为lighttpd是一个单线程(single-threaded)服务器,它的主要资源限制是文件描述符数目,默认值是1024。如果在一个高负载的站点上,可能你需要通过下面的设定增加这个限定值
server.max-fds = 2048 但这个限定只有在lighttpd做为root身份运行时才能生效。

connection.kbytes-per-second,server.kbytes-per-second
还有值得一提的时lighttpd可以限制每个连接或则特定虚拟机的流量。

compress.cache-dir,compress.filetype
如果文本稍微大点可以考虑使用压缩算法,减少带宽同时也能提高效率。例如:
compress.cache-dir = "/var/www/cache/"
compress.filetype = ("text/plain", "text/html")

server.stat-cache-engine = "fam"
这一条能明显提升性能,stat() cache。一个stat调用代价可能是昂贵的。为它设一个cache能省时间又避免上下文切换。替代每次都stat()来确定文件的存在,它只stat()一次,然后会监视目录,如果目录不变,他里面的文件也就没有变化。我们的内存文件系统中有没必要保留,依情况而定。
server.stat-cache-engine = "fam"   # either fam, simple or disabled

//使用sendfile发送文件

server.network-backend = "linux-sendfile"

--------------------------------------------------------------------------------------------------

Lighttpd与PHP

Lighttpd和PHP的搭配现在越来越常见了。但是老实说,如非必要,我还是推荐你使用Apache和PHP的搭配方式,毕竟LAMP构架的成熟度和稳定度都是经过时间考验的。

那么什么时候Lighttpd和PHP的搭配更值得选择呢?可以从以下几点考虑:如果访问量比较大,硬件资源吃紧,那么Lighttpd适合你;如果和稳定相比,你倾向速度多一些,那么Lighttpd适合你。

题外话:NginX
大有赶超Lighttpd
的态势。

Lighttpd的安装,本文就不多说了,大家自己搜索一下就能找到大把大把的教程。这里我们着重讨论一下Lighttpd的配置。

安装好Lighttpd+PHP后,你的配置很可能是类似下面的代码:

fastcgi.server = ( ".php" =>
 



 



 



(( "socket" => "/tmp/php-fastcgi.socket",
 



 



 



 



 



 



 



"bin-path" => "/usr/bin/php-cgi",
 



 



 



 



 



 



 



"max-procs" => 10,
 



 



 



 



 



 



 



"bin-environment" => (
 



 



 



 



 



 



 



 



 



 



 



"PHP_FCGI_CHILDREN" => "16",
 



 



 



 



 



 



 



 



 



 



 



"PHP_FCGI_MAX_REQUESTS" => "1000"
 



 



 



 



 



 



 



),
 



 



 



 



 



 



 



"broken-scriptfilename" => "enable"
 



 



 



))
)

其中,PHP_FCGI_MAX_REQUESTS的作用是在一个子进程工作一定次数后就干掉它,以免可能出现的问题连累系统,主进程会再创建一个相应的子进程来替补,保证子进程数一直是PHP_FCGI_CHILDREN个。

另外还有两个设置选项至关重要,分别是max-procs和PHP_FCGI_CHILDREN。如上所示的配置,系统将创建170个PHP-cgi的进程,它的计算公式如下:

num-procs = max-procs * ( 1 + PHP_FCGI_CHILDREN )

如果一个php-cgi进程占用十几兆内存的话,那么总计大约就要占用2G左右的内存。

我们先来看看max-procs的意思:从字面意思看,它似乎指得是最大进程数。实际它指的是Lighttpd一开始spawn多少个进程。

至于PHP_FCGI_CHILDREN的意思,和字面意思相同,指的就是每个主进程里产生多少个PHPFCGI子进程。

如果你的Lighttpd已经启动,你可以尝试执行一下命令:ps aux | grep php-cgi,将会看到大量的php-cgi进程:

nobody 10939 0.0 0.1 15556 4820 ? Ss 16:24 0:00 /usr/local/bin/php-cgi
nobody 11380 0.0 0.1 15452 5588 ? S 16:24 0:00 /usr/local/bin/php-cgi

仔细观察,你会发现这些php-cgi的状态不尽相同,有的是Ss,有的是S,通过man ps你能找到这些状态的含义:

S Interruptible sleep (waiting for an event to complete)
s is a session leader

也就是说,Ss状态的进程都是主进程(max-procs代表的那些进程),而S状态的进程都是子进程(PHP_FCGI_CHILDREN代表的那些进程)。如果不相信,你可以使用命令核实一下数量:

ps aux | grep php-cgi | grep Ss | grep -v grep | wc -l

确认了这些,我们再仔细看ps aux | grep php-cgi的结果,你还会发现主进程的内存占用(4840)和子进程的内存占用(5588)是不同的。这是因为主进程不处理实际的PHP请求,它唯一的工作就是看管好自己手下的子进程。而实际的PHP请求都是由子进程来完成的,所以子进程占用的内存要稍大一些。

如此,我们对max-procs和PHP_FCGI_CHILDREN的含义应该理解了吧,别急,还有一个问题:既然php-cgi的总进程数可以由上面的公式算出来,那么以下几个配置选项哪个好?

"max-procs" => 1,
"PHP_FCGI_CHILDREN" => "169",

"max-procs" => 2,
"PHP_FCGI_CHILDREN" => "84",

"max-procs" => 10,
"PHP_FCGI_CHILDREN" => "16",

以上三种配置产生的总进程数一样(都是170),我们如何判断配置的好坏呢?

如果使用了eAccelerator之类的PHP优化器,那么eAccelerator会为每一个主进程创建一个独立的缓存空间,这个时候如果你的max-procs是2的话,就会建立两个独立的缓存空间。一方面这浪费了一些内存,另一方面如果你的一个主进程挂了(它下面的子进程就失控了),至少你还有一个主进程可以保持正常运转。

总体来说,max-procs不宜为较小,否则没有容错性,在有PHP优化器的时候也不宜过大,否则会浪费很多内存做缓存空间,即便没有装PHP优化器,max-procs也不宜过大,因为主进程是不处理PHP请求的,过多的主进程自然就是一种浪费。确定了max-procs的值,剩下PHP_FCGI_CHILDREN的值就好说了。

另外:通过命令netstat -anp | grep php-cgi | wc -l可以得知当前有多少php-cgi处于连接状态,如果接近php-cgi的总进程数,就说明应该加大进程数了。
--------------------------------------------------------------------------------------------------------------------------------

lighttpd(lighty) 性能优化

对服务器而言最重要的就是优化了.
apache的优化文章,相信你也见过不少了.
这里稍微摘出lighttpd的几个优化参数看一看.

本文主要为跑php(fastcgi)的lighttpd设置.
如果需要跑静态页面,可以忽略本文 keep-alive 部分(并调大常连接数)

1 最大连接数

默认是1024
修改 server.max-fds,大流量网站推荐2048.

因为lighttpd基于线程,而apache(MPM-prefork)基于子进程,
所以apache需要设置startservers,maxclients等,这里不需要
 

2 stat() 缓存

stat() 这样的系统调用,开销也是相当明显的.
缓存能够节约时间和环境切换次数(context switches)

一句话,lighttpd.conf加上
server.stat-cache-engine = “fam”

lighttpd还另外提供simple(缓存1秒内的stat()),disabled选项.
相信没人会选disabled吧.

3 常连接(HTTP Keep-Alive)

一般来说,一个系统能够打开的文件个数是有限制的(文件描述符限制)
常连接占用文件描述符,对非并发的访问没有什么意义.

(文件描述符的数量和许多原因有关,比如日志文件数量,并发数目等)

这是lighttpd在keep-alive方面的默认值.
server.max-keep-alive-requests = 128
server.max-keep-alive-idle = 30

换言之,lighttpd最多可以同时承受30秒长的常连接,每个连接最多请求128个文件.
但这个默认值确实不适合非并发这种多数情况.

lighttpd.conf 中减小
server.max-keep-alive-requests
server.max-keep-alive-idle
两个值,可以减缓这种现象.

甚至可以关闭lighttpd keep-alive.
server.max-keep-alive-requests = 0

4 事件处理

对于linux kernel 2.6来说,没有别的可说
lighttpd.conf中加上这一句足矣
server.event-handler = “linux-sysepoll”

另外,
linux 2.4 使用 linux-rtsig
solaris: solaris-devpoll
freebsd 使用 freebsd-kqueue
unix 使用 poll

5 网络处理

lighttpd 大量使用了 sendfile() 这样一个高效的系统调用.
减少了从应用程序到网卡间的距离.
(同时也减少了lighttpd对cpu的占用,这部分占用转嫁到内核身上了)

根据平台,可以设置不同的参数.
(linux) server.network-backend = “linux-sendfile”
solaris: solaris-sendfilev
freebsd: freebsd-sendfile
unix: writev

如果有兴趣的话,也可以看看lighttpd在async io(aio)上的实现,仅限 lighttpd 1.5
(linux-aio-sendfile, posix-aio, gthread-aio)

此外,网络方面,核心的参数也需要适当进行修改,
这里就不需要详细说明了.

6 本文涉及 lighttpd.conf 参数总结

以下适合linux 2.6,php-fastcgi

var.author="fcicq"
server.stat-cache-engine = "fam"
server.network-backend = "linux-sendfile"
server.event-handler = "linux-sysepoll"
server.max-keep-alive-requests = 0
 

ps:
注意到不对劲了没有?

------------------------------------------------------------------------

Lighttpd(4) 功能特性
  # 配置超期
  expire.url = ( "/www/" => "access 2 hours")
  expire.url = ( "/www/mp3/" => "access 2 hours")
  
  #
  
  
  # 压缩
   compress.cache-dir = "/var/www/cache/"
  
   # 或者针对虚拟站点指定临时目录
   $HTTP["host"] == "docs.example.org" {
   compress.cache-dir = "/var/www/cache/docs.example.org/"
   }
  
   压缩文件类型
   compress.filetype = ("text/plain", "text/html")
  
  
  # 重定向
  
   # 重定向到指定网址
   url.redirect = ("^/" => "http://www.tianya.cn/index.asp")
  
   # 变量传递
   url.redirect = ("^/([0-9]+)$" => "http://cache.tianya.cn/publicforum/Content/house/1/$1.shtml")
   url.redirect = ( "^/show/([0-9]+)/([0-9]+)$" => "http://www.example.org/show.php?isdn=$1&page$2")
  
   # 面向虚拟主机的重定向
   $HTTP["host"] =~ "^www\.(.*)" {
   url.redirect = ( "^/(.*)" => "http://%1/$1" )
   }
  
  # 重写
  
  
  # 代理
   使用proxy-module模块。
  
   # 两个选项:
   1)proxy.debug
   2)proxy.balance:hash(同一请求发送到同一主机)、round-robin(循环)、fair(缺省)
  
   # 范例,
   $HTTP["host"] == "www.example.org" {
   proxy.balance = "hash"
   proxy.server = ( "" => ( ( "host" => "10.0.0.10" ),
   ( "host" => "10.0.0.11" ),
   ( "host" => "10.0.0.12" ),
   ( "host" => "10.0.0.13" ),
   ( "host" => "10.0.0.14" ),
   ( "host" => "10.0.0.15" ),
   ( "host" => "10.0.0.16" ),
   ( "host" => "10.0.0.17" ) ) )
   }
  
   当一主机down机时,该机的请求被平等移动到其它服务器。使用Microsoft CARP算法。
  
  
  # 流量修整
   1)每个连接每秒流量限制(k)
   connection.kbytes-per-second = 0
  
   2)服务每秒流量限制
   server.kbytes-per-second
   # 在虚拟主机中限制
   $HTTP["host"] == "www.example.org" {
   server.kbytes-per-second = 128
   }
  
  
  # 目录列表
   # 激活
   dir-listing.activate = "enable"
  
   # 控制在物理目录中
   $HTTP["url"] =~ "^/download($|/)" {
   dir-listing.activate = "enable"
   }
  
   dir-listing.hide-dotfiles = "enable" # 不显示隐藏文件
   dir-listing.external-css = "" # 目录css风格显示的css文件路径
   dir-listing.exclude = "" # 正则表达式,排队不显示的文件
   dir-listing.encoding = "utf-8"
  
  # 禁止googelbot机器人访问
  $HTTP["useragent"] =~ "Google" {
   url.access-deny = ( "" )
  }
  
  
  # 禁止所有图像盗链 (anti-hotlinking for images)
  $HTTP["referer"] !~ "^($|http://www\.example\.org)" {
   url.access-deny = ( ".jpg", ".jpeg", ".png" )
  }
  
  # 禁止非10.0.0.0/8的IP访问www.example.org
  $HTTP["host"] == "www.example.org" {
   $HTTP["remoteip"] != "10.0.0.0/8" {
   url.access-deny = ( "" )
   }
  }
  
  # 允许200.19.1.5和210.45.2.7访问www.example.org/admin/
  $HTTP["host"] == "www.example.org" {
   #!~ is a perl style regular expression not match
   $HTTP["remoteip"] !~ "200.19.1.5|210.45.2.7" {
   $HTTP["url"] =~ "^/admin/" {
   url.access-deny = ( "" )
   }
   }
  }
  
  # 配置虚拟主机
  
  启动模块mod_simple_vhost
  
  $HTTP["host"] == "cache.tianya.cn" {
   server.document-root = "/www/"
   index-file.names = ( "index.shtml", "index.html",
   "index.htm", "default.htm" )
  }
  
  $HTTP["host"] == "sample.tianya.cn" {
   server.document-root = "/www/sample/"
   index-file.names = ( "index.shtml", "index.html",
   "index.htm", "default.htm" )
  }

此条目发表在article分类目录,贴了标签。将固定链接加入收藏夹。