4.6. 反向代理

4.6.1. 使用 HAProxy 进行反向代理

CouchDB 建议使用 HAProxy 作为负载均衡器和反向代理。团队在生产环境中使用它的经验表明,它在配置和监控功能以及整体性能方面都优于其他选择。

CouchDB 的示例 haproxy 配置位于 代码库 和发布包中,名为 rel/haproxy.cfg。它包含在下面。此示例适用于 3 节点 CouchDB 集群

global
    maxconn 512
    spread-checks 5

defaults
    mode http
    log global
    monitor-uri /_haproxy_health_check
    option log-health-checks
    option httplog
    balance roundrobin
    option forwardfor
    option redispatch
    retries 4
    option http-server-close
    timeout client 150000
    timeout server 3600000
    timeout connect 500

    stats enable
    stats uri /_haproxy_stats
    # stats auth admin:admin # Uncomment for basic auth

frontend http-in
     # This requires HAProxy 1.5.x
     # bind *:$HAPROXY_PORT
     bind *:5984
     default_backend couchdbs

backend couchdbs
    option httpchk GET /_up
    http-check disable-on-404
    server couchdb1 x.x.x.x:5984 check inter 5s
    server couchdb2 x.x.x.x:5984 check inter 5s
    server couchdb2 x.x.x.x:5984 check inter 5s

4.6.2. 使用 nginx 进行反向代理

4.6.2.1. 基本配置

以下是在 <nginx config directory>/sites-available/default 中的 nginx 配置文件中的基本摘录。这将代理来自 http://domain.com/... 的所有请求到 http://localhost:5984/...

location / {
    proxy_pass http://localhost:5984;
    proxy_redirect off;
    proxy_buffering off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

必须禁用代理缓冲,否则 nginx 后面的连续复制将无法正常工作。

4.6.2.2. 使用 nginx 将 CouchDB 反向代理到子目录

将 CouchDB 作为整个域的子目录提供可能很有用,尤其是在避免 CORS 问题时。以下是一个基本 nginx 配置的摘录,它将 URL http://domain.com/couchdb 代理到 http://localhost:5984,以便附加到子目录的请求,例如 http://domain.com/couchdb/db1/doc1 被代理到 http://localhost:5984/db1/doc1

location /couchdb {
    rewrite ^ $request_uri;
    rewrite ^/couchdb/(.*) /$1 break;
    proxy_pass http://localhost:5984$uri;
    proxy_redirect off;
    proxy_buffering off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

基于会话的复制是 CouchDB 2.3.0 后的默认功能。要启用使用反向代理的 CouchDB 在子目录中的基于会话的复制。

location /_session {
    proxy_pass http://localhost:5984/_session;
    proxy_redirect off;
    proxy_buffering off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

4.6.2.3. 使用 nginx 作为反向代理进行身份验证

以下是一个示例配置设置,其中启用了基本身份验证,并将 CouchDB 放置在 /couchdb 子目录中

location /couchdb {
    auth_basic "Restricted";
    auth_basic_user_file htpasswd;
    rewrite /couchdb/(.*) /$1 break;
    proxy_pass http://localhost:5984;
    proxy_redirect off;
    proxy_buffering off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Authorization "";
}

此设置完全依赖于 nginx 执行授权,并将请求转发到 CouchDB,而无需身份验证(CouchDB 处于管理员模式),这在 CouchDB 3.0 中不再足够,因为管理员模式已被删除。您至少需要使用标头将用户凭据硬编码到此版本中。

有关更好的解决方案,请参见 代理身份验证.

4.6.2.4. 使用 nginx 进行 SSL

要启用 SSL,只需启用 nginx SSL 模块,并添加另一个代理标头

ssl on;
ssl_certificate PATH_TO_YOUR_PUBLIC_KEY.pem;
ssl_certificate_key PATH_TO_YOUR_PRIVATE_KEY.key;
ssl_protocols SSLv3;
ssl_session_cache shared:SSL:1m;

location / {
    proxy_pass http://localhost:5984;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_buffering off;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Ssl on;
}

X-Forwarded-Ssl 标头告诉 CouchDB 它应该使用 https 方案而不是 http 方案。否则,所有 CouchDB 生成的重定向都将失败。

4.6.3. 使用 Caddy 2 进行反向代理

Caddy 是 https-by-default,它会自动为您获取、安装、激活并在必要时续订受信任的 SSL 证书 - 所有这些都在后台完成。证书由 **Let’s Encrypt** 证书颁发机构颁发。

4.6.3.1. 基本配置

以下是在 /etc/caddy/Caddyfile 中的 Caddyfile 的基本摘录。这将代理来自 http(s)://domain.com/... 的所有请求到 http://localhost:5984/...

domain.com {

   reverse_proxy localhost:5984

}

4.6.3.2. 使用 Caddy 2 将 CouchDB 反向代理到子目录

将 CouchDB 作为整个域的子目录提供可能很有用,尤其是在避免 CORS 问题时。以下是一个基本 Caddy 配置的摘录,它将 URL http(s)://domain.com/couchdb 代理到 http://localhost:5984,以便附加到子目录的请求,例如 http(s)://domain.com/couchdb/db1/doc1 被代理到 http://localhost:5984/db1/doc1

domain.com {

    reverse_proxy /couchdb/* localhost:5984

}

4.6.3.3. CouchDB 集群的反向代理 + 负载均衡

以下是在 /<path>/<to>/<site>/Caddyfile 中的 Caddyfile 的基本摘录。这将代理来自 http(s)://domain.com/... 的所有请求,并在 localhost:15984localhost:25984localhost:35984 上的 3 个 CouchDB 集群节点之间均匀分配。

Caddy 将每 5 秒检查每个节点的状态,即运行状况;如果一个节点出现故障,Caddy 将避免将请求代理到该节点,直到它恢复在线。

domain.com {

    reverse_proxy http://localhost:15984 http://localhost:25984 http://localhost:35984 {
    lb_policy round_robin
    lb_try_interval 500ms

    health_interval 5s
    }

}

4.6.3.4. 使用 Caddy 2 作为反向代理进行身份验证

以下是一个示例配置设置,其中启用了基本身份验证,并将 CouchDB 放置在 /couchdb 子目录中

domain.com {

    basicauth /couchdb/* {
        couch_username couchdb_hashed_password_base64
    }

    reverse_proxy /couchdb/* localhost:5984

}

此设置完全依赖于 nginx 执行授权,并将请求转发到 CouchDB,而无需身份验证(CouchDB 处于管理员模式),这在 CouchDB 3.0 中不再足够,因为管理员模式已被删除。您至少需要使用标头将用户凭据硬编码到此版本中。

有关更好的解决方案,请参见 代理身份验证.

4.6.4. 使用 Apache HTTP Server 进行反向代理

警告

截至撰写本文时,无法完全禁用 Apache HTTPD Server 和 CouchDB 之间的缓冲。这可能会给连续复制带来问题。Apache CouchDB 团队强烈建议使用其他反向代理,例如 haproxynginx,如本节前面所述。

4.6.4.1. 基本配置

以下是如何使用 VirtualHost 块配置将 Apache 用作 CouchDB 的反向代理的基本摘录。您至少需要使用 --enable-proxy --enable-proxy-http 选项配置 Apache,并使用等于或高于 Apache 2.2.7 的版本才能在 ProxyPass 指令中使用 nocanon 选项。 ProxyPass 指令添加了 CouchDB 所需的 X-Forwarded-For 标头,而 ProxyPreserveHost 指令确保保留原始客户端 Host 标头。

<VirtualHost *:80>
   ServerAdmin [email protected]
   DocumentRoot "/opt/websites/web/www/dummy"
   ServerName couchdb.localhost
   AllowEncodedSlashes On
   ProxyRequests Off
   KeepAlive Off
   <Proxy *>
      Order deny,allow
      Deny from all
      Allow from 127.0.0.1
   </Proxy>
   ProxyPass / http://localhost:5984 nocanon
   ProxyPassReverse / http://localhost:5984
   ProxyPreserveHost On
   ErrorLog "logs/couchdb.localhost-error_log"
   CustomLog "logs/couchdb.localhost-access_log" common
</VirtualHost>