代理接口¶
注意:此模块仅在(现已停止开发的)1.5.x 分支中可用。
模块:mod_proxy_core (已废弃)
描述¶
FastCGI、SCGI、HTTP 等做着同样简单的工作:它们将 HTTP 请求转发到后端并向服务器发送响应。它们只是使用不同的协议来编码数据。
- FastCGI,由 Open Market 开发并记录在 http://www.fastcgi.com/ 上,是一个围绕 HTTP 请求的二进制容器,可减少解析开销。除了正常的响应生成外,它还支持授权查询
- SCGI 类似于 HTTP,只是为 HTTP 头部添加了一个长度头部。http://www.mems-exchange.org/software/scgi/ 中写道:“SCGI 协议是通用网关接口 (CGI) 协议的替代品。它是一个应用程序与 HTTP 服务器接口的标准。它类似于 FastCGI,但设计起来更易于实现。”
- 对于 HTTP,我们支持后端侧的 HTTP/1.0 和 HTTP/1.1
- AJP13 是 Apache JServ 协议版本 1.3(参见 https://tomcat.net.cn/tomcat-3.3-doc/AJPv13.html),由 Apache 世界中的 mod_jk 和 mod_proxy_ajp (Apache 2.2+) 实现。
本小指南将帮助您选择适合您需求的协议。
协议 | 偏好 | 二进制协议 | 长连接 |
---|---|---|---|
HTTP | mongrel | 否 | 是 |
SCGI | WSGI (Python) | 不完全是 | 否 |
FastCGI | PHP, Rails | 是 | 是 |
AJP13 | Tomcat | 是 | 是 |
安装¶
mod-proxy-core 需要 lighttpd 1.5,旨在取代 mod_fastcgi。
如果您想使用 mod-proxy-core,则必须先加载它。每个协议也是一个模块,也必须在加载
核心模块之后加载。
server.modules = ( ..., "mod_proxy_core", "mod_proxy_backend_http", "mod_proxy_backend_fastcgi", ... )
负载均衡¶
mod-proxy-core 支持 4 种不同的负载均衡器
- 静态负载均衡器 (static) 不进行负载均衡,仅在第一个列出的后端不可用时进行故障转移。有关示例(基本上是本地和远程后端),请参见 http://permalink.gmane.org/gmane.comp.web.lighttpd/4686。
- 在轮询 (round-robin) 中,请求平均分配给所有后端。在我们的实现中,我们不强制执行真正的轮询,而是随机选择一个后端。
- 最短队列优先 (sqf) 类似于轮询,并优先选择等待队列最短的后端。
- 缓存数组路由协议 (carp) 有点不同,因为它能提高后端局部性。它对 URL 进行哈希处理,并始终将相同的 URL 发送到相同的后端。http://icp.ircache.net/carp.txt 解释了完整的规范。
当前未实现
故障转移处理¶
如果对后端的请求失败(连接被拒绝,连接超时等),请求将被发送到另一个后端。如果没有可用的后端,则返回“504 网关超时”。(参见 http://forum.lighttpd.net/topic/4993)
超时¶
如果您的传入请求超出了可用后端的数量,则该请求将被放入积压队列中。一旦后端再次可用,队列中的第一个连接将被唤醒并处理。
如果请求在队列中等待超过 10 秒,则该请求将被终止并返回“504 网关超时”。
选项¶
proxy-core.balancer
可以是 'round-robin'、'sqf'、'carp' 或 'static' 之一。
参见
proxy-core.protocol
可以是 'http'、'fastcgi'、'ajp13' 或 'scgi' 之一。请确保加载后端模块(参见 mod_proxy_backend_<name>)
proxy-core.backends
告诉模块将代理请求发送到哪里。
它是一个主机名/IP 地址/Unix 域套接字列表
例如:
proxy-core.backends = ( "10.0.0.1:80", ## IPv4 address "unix:/tmp/php.socket", ## unix domain socket "[::1]:80", ## IPv6 addresss "google.com:80" ## hostname, resolved at startup )
proxy-core.max-pool-size
单个后端连接池的最大大小。
- 对于 mongrel,这应设置为 1
- 对于 PHP,这应与 PHP_FCGI_CHILDREN 设置匹配
- 对于 WSGI,这应与后端线程数匹配
- 对于 HTTP 代理,您可以自行决定允许向同一后端发送多少个并行请求
默认值:1
proxy-core.allow-x-sendfile
启用使用“X-Sendfile/X-LIGHTTPD-Sendfile/X-LIGHTTPD-send-tempfile”头部。
注意:如果您正在运行启用了 zlib 压缩的 PHP,请使用 ini_set("zlib.output_compression", "off") 将其关闭,否则您尝试发送的文件将只有 1 字节且无法工作。
参见
- https://blog.lighttpd.ac.cn/articles/2006/07/22/mod_proxy_core-got-x-sendfile-support
- https://blog.lighttpd.ac.cn/articles/2006/11/29/faster-fastcgi
proxy-core.allow-x-rewrite
启用使用 X-Rewrite
使您能够通过使用响应头部“X-Rewrite-URI”和“X-Rewrite-Host”将请求从一个后端重定向到另一个后端,而客户端不会察觉。
假设您想要某种负载均衡,但其背后的逻辑比轮询或加权随机化更复杂。
客户端请求 http://host.tld/,该请求由您的 fastcgi 后端处理,后端会进行一些计算来决定应使用哪个后端。
现在,您的后端只需发送 200 OK,并附带例如“X-Rewrite-URI: /foo”和“X-Rewrite-Host: internal3.host.tld”。
这样做会使 mod_proxy_core 再次处理来自客户端的当前请求,但 URI 为“/foo”而不是“/”,主机为“internal3.host.tld”而不是“host.tld”。
参见
proxy-core.rewrite-request
重写请求头或请求 URI。
目前支持以下键:
- “_uri”:请求的完整路径 + 查询字符串,例如“/some/file/in/some/dir.fcgi?request&uri=1”
- “_docroot”:文档根目录路径,如果请求发送到具有不同文件系统布局的另一台服务器,则此选项很有用
- “_pathinfo”:CGI 环境变量 PATH_INFO(例如,对于到 /myfcgiapp/foobar 的请求,为 /foobar)
- “_scriptname”:CGI 环境变量 SCRIPT_NAME(例如,对于到 /myfcgiapp 的请求,为 /myfcgiapp)
注意,参见 #1600。
示例
trac 需要一个猜测的 PATH_INFO
$HTTP["url"] =~ "^/trac/" { proxy-core.backends = ( "127.0.0.1:9090" ) proxy-core.protocol = "fastcgi" proxy-core.rewrite-request = ( "_pathinfo" => ( "^/trac(/.*)" => "$1" ), "_scriptname" => ( "^(/trac/)" => "$1" ) ) }
我们从请求 URI(与 $HTTP["url"] 中的相同)构建 PATH_INFO,并从中提取 trac-base 之后的部分作为 PATH_INFO。SCRIPT_NAME 相应地缩短。
trac will only see:
SCRIPT_NAME=/trac
PATH_INFO=/wiki
For proxies can make a relative part of your URL:
$HTTP["url"] =~ "^/blog" {
proxy-co...
proxy-core.rewrite-request = (
"_uri" => ( "^/blog/?(.*)" => "/$1" ),
"Host" => ( ".*" => "blog.example.org" ),
)
}
All requests to http://example.org/blog will be fetched from http://blog.example.org/ transparently for the user.
proxy-core.rewrite-response
重写响应头。
proxy-core.max-keep-alive-requests
关闭长连接之前的请求数。
默认值:0
proxy-core.split-hostnames
如果后端使用具有多个 IP 地址的 DNS 主机名,则将每个地址拆分为一个单独的后端。
禁用此选项可将 IP 地址放入该后端的地址池中。
默认值:已启用
示例¶
在 8 个 Squid 前使用 lighttpd + mod_proxy_core,由它们为您处理动态内容的缓存。对主机 www.example.org 的所有请求都应转发到代理。所有代理都侦听端口 80 以处理请求。
server.modules += ( "mod_proxy_backend_http" ) $HTTP["host"] == "www.example.org" { proxy-core.protocol = "http" proxy-core.balancer = "carp" proxy-core.backends = ( "10.0.0.10", "10.0.0.11", "10.0.0.12", "10.0.0.13", "10.0.0.14", "10.0.0.15", "10.0.0.16", "10.0.0.17" ) }
如果其中一个主机宕机,则该服务器的所有请求将平均转移到其他服务器。如果您想了解更多关于此处使用的算法,请在 Google 上搜索“Microsoft CARP”。
对于使用 Unix 域套接字“/tmp/php-fastcgi.sock”的 PHP
server.modules += ( "mod_proxy_backend_fastcgi" ) $PHYSICAL["existing-path"] =~ "\.php$" { proxy-core.balancer = "round-robin" proxy-core.protocol = "fastcgi" proxy-core.allow-x-sendfile = "enable" proxy-core.backends = ( "unix:/tmp/php-fastcgi.sock" ) proxy-core.max-pool-size = 16 proxy-core.rewrite-request = ( "_pathinfo" => ( "\.php(/.*)" => "$1" ) ) }
对于 SCGI
server.modules += ( "mod_proxy_backend_scgi" ) $PHYSICAL["existing-path"] =~ "\.scgi$" { proxy-core.balancer = "round-robin" proxy-core.protocol = "scgi" proxy-core.allow-x-sendfile = "enable" proxy-core.backends = ( "127.0.0.1:9090" ) proxy-core.max-pool-size = 16 }
对于带有主机和文件扩展名条件的 HTTP 代理
server.modules += ( "mod_proxy_backend_http" ) $HTTP["host"] == "www.example.org" { proxy-core.protocol = "http" proxy-core.balancer = "carp" $HTTP["url"] =~ "\.php$" { proxy-core.backends = ( "10.0.0.10:80" ) } else $HTTP["url"] =~ "\.scgi$" { proxy-core.backends = ( "10.0.0.11:80" ) } }
反向代理
server.modules += ( "mod_proxy_backend_http" ) $HTTP["url"] =~ "^/proxyme(/|$)" { proxy-core.balancer = "round-robin" proxy-core.protocol = "http" proxy-core.backends = ( "en.wikipedia.org" ) proxy-core.rewrite-response = ( "Location" => ( "^http://en.wikipedia.org/(.*)" => "http://127.0.0.1:1025/proxyme/$1" ), ) proxy-core.rewrite-request = ( "_uri" => ( "^/proxyme/?(.*)" => "/$1" ), "Host" => ( ".*" => "en.wikipedia.org" ), ) }
对于使用 AJP13 协议代理到 Tomcat
server.modules += ( "mod_proxy_backend_ajp13" ) $HTTP["url"] =~ "^/tomcat/" { proxy-core.balancer = "round-robin" proxy-core.protocol = "ajp13" proxy-core.backends = ( "localhost:8009" ) proxy-core.max-pool-size = 16 }
allow-x-rewrite 配置示例
server.modules += ( "mod_proxy_backend_fastcgi" ) $PHYSICAL["existing-path"] =~ "\.php$" { proxy-core.balancer = "round-robin" proxy-core.protocol = "fastcgi" proxy-core.allow-x-rewrite = "enable" proxy-core.backends = ( "unix:/tmp/php-fastcgi.sock" ) proxy-core.max-pool-size = 16 } server.modules += ( "mod_proxy_backend_http" ) $HTTP["host"] == "backend-cluster" { proxy-core.balancer = "round-robin" proxy-core.protocol = "http" proxy-core.max-pool-size = 4 }
X-Rewrite 脚本示例
<?php header("X-Rewrite-URI: /"); header("X-Rewrite-Host: backend-cluster"); header("X-Rewrite-Backend: " . $_REQUEST['backend']); // dynamicaly add/select a backend to the "backend-cluster" proxy-core ?>
将 Rails 应用程序的请求代理到本地托管的 mongrel 实例组。
$HTTP["host"] == "rails.dom.ain" { # or, e.g., =~ "^([^.])+\.rails\.tld$" proxy-core.protocol = "http" proxy-core.balancer = "round-robin" proxy-core.allow-x-sendfile = "enable" # avoid send_file memory ballooning by using the x_send_file plugin proxy-core.backends = ( "127.0.0.1:8000", "127.0.0.1:8001", "127.0.0.1:8002", "127.0.0.1:8003" ) }
Django 1.x 结合 lighttpd 1.5.x 示例
$HTTP["host"] == "yourdomain.net" { server.document-root = "/var/www/yourdomain.net/" proxy-core.backends = ( "unix:/var/django/yourdomain/fcgi.sock" ) proxy-core.balancer = "round-robin" proxy-core.max-pool-size = 5 proxy-core.protocol = "fastcgi" proxy-core.allow-x-sendfile = "enable" proxy-core.rewrite-request = ( "_pathinfo" => ( "^(/.*)" => "$1" ), "_scriptname" => ( "^.*" => "" ), ) url.rewrite-once = ( "^/favicon\.ico$" => "/media/favicon.ico", ) } $HTTP["host"] == "media.yourdomain.net" { server.document-root = "/var/django/yourdomain/contrib/admin/media/" expire.url = ( "" => "access 7 days" ) }