项目

通用

个人资料

操作

代理接口

注意:此模块仅在(现已停止开发的)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 字节且无法工作。

参见

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" )
}

更新于 gstrauss 3 个月前 · 52 次修订