lighttpd+fastcgi
1. 简介
lighttpd
提供了一种外部程序调用的接口,即 FastCGI
接口。这是一种独立于平台和服务器的接口,它介于 Web 应用程序和 Web 服务器之间。
这就意味着能够在 Apache
服务器上运行的 FastCGI
程序,也一定可以无缝的在 lighttpd
上使用。
2. FastCGI 介绍
1)就像 CGI
一样,FastCGI
也是独立于编程语言的。
2)就像 CGI
一样,FastCGI
程序运行在完全独立于核心 Web Server
之外的进程中,和 API
方式相比,提供了很大的安全性。(API 会将程序代码与核心 Web Server 挂接在一起,这就意味着基于问题 API 的应用程序可能会使整个 Web Server 或另一个应用程序崩溃;一个恶意 API 还可以从核心 Web Server 或另一个应用程序中盗取安全密钥)
3)虽然 FastCGI
不能一夜之间复制 CGI 的所有功能,但是 FastCGI
一直宣扬开放,这也使得我们拥有很多免费的 FastCGI
应用程序库(C/C++、Java、Perl、TCL)和免费的 Server 模块(Apache、ISS、Lighttpd)。
4)就像 CGI
一样,FastCGI
并不依附于任何 Web Server
的内部架构,因此即使 Server
的技术实现变动,FastCGI
仍然非常稳定;而 API
设计是反映 Web Server
内部架构的,因此,一旦架构改变,API 要随之变动。
5)FastCGI
程序可以运行在任何机器上,完全可以和 Web Server
不在一台机器上。这种分布式计算的思想可以确保可扩展性、提高系统可用性和安全性。
6)CGI
程序主要是对 HTTP
请求做计算处理,而 FastCGI
却还可以做得更多,例如模块化认证、授权检查、数据类型转换等等。在未来,FastCGI
还会有能力扮演更多角色。
7)FastCGI
移除了 CGI
程序的许多弊端。例如,针对每一个新请求,WebServer
都必须重启 CGI
程序来处理新请求,这导致 WebServer
的性能会大受影响。而 FastCGI
通过保持进程处理运行状态并持续处理请求的方式解决了该问题,这就将进程创建和销毁的时间节省了出来。
8)CGI
程序需要通过管道(pipe)方式与 Web Server
通信,而 FastCGI
则是通过 Unix-Domain-Sockets
或 TCP/IP
方式来实现与 Web Server
的通信。这确保了 FastCGI
可以运行在 Web Server
之外的服务器上。FastCGI
提供了 FastCGI
负载均衡器,它可以有效控制多个独立的 FastCGI Server
的负载,这种方式比 load-balancer+apache+mod_php
方式能够承担更多的流量。
3. FastCGI 模块
若要 lighttpd
支持 fastcgi
,则需要配置如下内容:
在 fastcgi.conf
中配置
1 | server.modules += ( "mod_fastcgi" ) |
及在 module.conf
中配置
1 | include "conf.d/fastcgi.conf" |
4. FastCGI 配置选项
lighttpd
通过 fastcgi
模块的方式实现了对 fastcgi
的支持,并且在配置文件中提供了三个相关的选项:
1) fastcgi.debug
可以设置一个从 0 到 65535 的值,用于设定 FastCGI
模块的调试等级。当前仅有 0 和 1 可用。1 表示开启调试(会输出调试信息),0 表示禁用。例如:
1 | fastcgi.debug = 1 |
2) fastcgi.map-extentsions
同一个 fastcgi server
能够映射多个扩展名,如 .php3
和 .php4
都对应 .php
。例如:
1 | fastcgi.map-extensions = ( ".php3" => ".php" ) |
or for multiple
1 | fastcgi.map-extensions = ( ".php3" => ".php", ".php4" => ".php" ) |
3) fastcgi.server
这个配置是告诉 Web Server
将 FastCGI
请求发送到哪里,其中每一个文件扩展名可以处理一个类型的请求。负载均衡器可以实现对同一扩展名的多个对象的负载均衡。
fastcgi.server
的结构语法如下:
1 | ( <extension> => |
其中:
extentsion :文件名后缀或以”/” 开头的前缀(也可为文件名)
name :这是一个可选项,表示 handler 的名称,在 mod_status 中用于统计功能,可以清晰的分辨出是哪一个 handler 处理了。
host :FastCGI 进程监听的 IP 地址。此处不支持 hostname 形式。
port :FastCGI 进程所监听的 TCP 端口号
bin-path :本地 FastCGI 二进制程序的路径,当本地没有 FastCGI 正在运行时,会启动这个 FastCGI 程序。
socket :unix-domain-socket 所在路径。
mode :可以选择 FastCGI 协议的模式,默认是 “responder”,还可以选择 authorizer。
docroot :这是一个可选项,对于 responder 模式来讲,表示远程主机 docroot;对于 authorizer 模式来说,它表示 MANDATORY,并且指向授权请求的 docroot。
check_local :这是一个可选项,默认是 enable。如果是 enable,那么 server 会首先在本地(server.document-root)目录中检查被请求的文件是否存在,如果不存在,则给用户返回 404(Not Found),而不会把这个请求传递给 FastCGI。如果是 disable,那么 server 不会检查本地文件,而是直接将请求转发给 FastCGI。(disable 的话,server 从某种意义上说就变为了一个转发器)
broken-scriptfilename :以类似 PHP 抽取 PATH_INFO 的方式,抽取 URL 中的 SCRIPT_FILENAME。
如果 bin-path
被设置了,那么:
max-procs :设置多少个 FastCGI 进程被启动
bin-environment :在 FastCGI 进程启动时设置一个环境变量
bin-copy-environment :清除环境,并拷贝指定的变量到全新的环境中。
kill-signal :默认的话,在停止 FastCGI 进程时,lighttpd 会发送 SIGTERM (-15) 信号给子进程。此处可以设置发送的信号。
举例 :
使用前缀来对应主机:
1 | fastcgi.server = ( |
如果有一个请求 “http://my.example.org/remote_scripts/test.cgi",那么 server 会将其转发给 192.168.0.3 的 9000 端口,并且 SCRIPT_NAME
会被赋值为 “/remote_scripts/test.cgi”
。如果所设置的 handler
的末尾不是 “/”
,那么会被认为是一个文件。
负载均衡 :
FastCGI
模块提供了一种在多台 FastCGI
服务器间负载均衡的方法。
例如:
1 | fastcgi.server = ( ".php" => |
为了更好的理解负载均衡实现的原理,建议你置 fastcgi.debug
为 1
。即使对于本机的多个 FastCGI
,你也会获得如下输出:
1 | proc: 127.0.0.1 1031 1 1 1 31454 |
上述信息显示出了 IP 地址,端口号、当前链接数(也就是负载)(倒数第二列)、进程 ID(倒数第一列)等等。整个输出信息总是以负载域来从小到大排序的。
5. 参考文献
6. 附:QC V3 PP 版本 lighttpd.conf
1 | $ cat /etc/qtilighttpd.conf |