基础教程
配置文件 haproxy.cfg
global
log stdout format raw local0 debug
maxconn 4096
master-worker
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5s
timeout client 50s
timeout server 50s
frontend http-in
bind *:80
stats uri /stats
stats enable
stats auth admin:changeme123
stats refresh 10s
stats show-legends
acl host_dash hdr(host) -i dash.4.fx4.cn
use_backend arcane_backend if host_dash
default_backend webservers
backend webservers
balance roundrobin
http-check connect
http-check send meth HEAD uri / ver HTTP/1.1 hdr Host localhost
http-check expect status 200,301,302
server web1 web1:80 check inter 5s rise 2 fall 3
server web2 web2:80 check inter 5s rise 2 fall 3
backend arcane_backend
server arcane arcane:3552 check
添加一个服务
│ ✓ Edit config/haproxy.cfg: global... => global... │
│ │
│ 21 stats refresh 10s │
│ 22 stats show-legends │
│ 23 │
│ 24 + acl host_dash hdr(host) -i dash.4.fx4.cn │
│ 25 + use_backend arcane_backend if host_dash │
│ 26 + │
│ 27 default_backend webservers │
│ 28 │
│ 29 backend webservers │
│ ═══════════════════════════════════════════════════════════════════════════════════════════════════ │
│ 36 server web1 web1:80 check inter 5s rise 2 fall 3 │
│ 37 server web2 web2:80 check inter 5s rise 2 fall 3 │
│ 38 │
│ 39 + │
│ 40 + backend arcane_backend │
│ 41 + server arcane arcane:3552 check
这次修改 haproxy.cfg 文件的主要用法和作用如下:
添加域名路由规则:
- 在 frontend http-in 配置块中,我们添加了一个 acl (Access Control List),名为 host_dash。
- 这个 acl 的作用是检查进入 HAProxy 的 HTTP 请求的 Host 头信息。如果 Host 头与 dash.4.fx4.cn
匹配(-i 表示不区分大小写),则该条件为真。
- 紧接着,我们使用 use_backend arcane_backend if host_dash。这意味着,如果 host_dash
条件为真(即请求是发往 dash.4.fx4.cn 的),HAProxy 就会将这个请求转发给名为 arcane_backend
的后端服务。
定义新的后端服务:
- 我们在配置文件末尾新增了一个 backend 配置块,名为 arcane_backend。
- 在这个后端中,我们定义了一个 server arcane arcane:3552 check。这表示 arcane_backend
服务包含一个名为 arcane 的服务器,其地址是 arcane:3552。check 参数表示 HAProxy
会对这个服务器进行健康检查,确保它正常运行。
总结:
通过这些修改,HAProxy 现在会:
接收所有进入 80 端口的 HTTP 请求。
如果请求的域名是 dash.4.fx4.cn,它会将请求转发到 arcane:3552 这个服务。
对于其他所有非 dash.4.fx4.cn 的请求,HAProxy 仍然会按照原来的配置,将其转发到 webservers
后端服务。
添加 https 支持,并设置 http 跳转至 https
│ ✓ Edit config/haproxy.cfg: global... => global... │
│ │
│ 21 stats refresh 10s │
│ 22 stats show-legends │
│ 23 │
│ 24 + redirect scheme https code 301 if { hdr(host) -i dash.4.fx4.cn } │
│ 25 + │
│ 26 + frontend https-in │
│ 27 + bind *:443 ssl crt /etc/haproxy/certs │
│ 28 + │
│ 29 acl host_dash hdr(host) -i dash.4.fx4.cn │
│ 30 use_backend arcane_backend if host_dash │
│ 31 │
│ 27 - │
│ 28 - │
│ 32 backend arcane_backend │
│ 33 server arcane arcane:3552 check
- 启用 HTTPS 监听: 新增了一个 https-in 前端,监听 443 端口以处理 HTTPS 请求。
- 泛域名证书集成: 配置 HAProxy 从 /etc/haproxy/certs 目录加载证书,支持 dash.4.fx4.cn 使用的
*.4.fx4.cn 泛域名证书。
- HTTP 到 HTTPS 强制跳转: 为 dash.4.fx4.cn 配置了 301 重定向规则,所有访问 http://dash.4.fx4.cn
的请求都将自动跳转到 https://dash.4.fx4.cn。
- HTTPS 流量路由: https-in 前端现在能够正确识别 dash.4.fx4.cn 的 HTTPS 流量,并将其路由到
优化版本配置
global
log stdout format raw local0 info # Docker 里输出到 stdout,便于 logs 查看
maxconn 4096
master-worker # 支持优雅 reload
# daemon 不要加(Docker 里必须前台运行)
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5s
timeout client 30s
timeout server 30s
# HTTP 入口:80 端口,强制跳转 HTTPS(只针对特定域名)
frontend http-in
bind *:80
mode http
# 统计页面(建议只在 HTTP 上开,或加 ACL 限制)
stats uri /stats
stats enable
stats auth admin:admin888
stats refresh 10s
stats show-legends
# 只针对这些域名跳转到 HTTPS,其他域名可正常走 HTTP 或其他规则
acl is_dash hdr(host) -i dash.4.fx4.cn
acl is_arcane hdr(host) -i arcane.4.fx4.cn
acl is_sozu hdr(host) -i sozu.4.fx4.cn
http-request redirect scheme https code 301 if is_dash
http-request redirect scheme https code 301 if is_arcane
http-request redirect scheme https code 301 if is_sozu
# 如果你想所有 HTTP 都跳 HTTPS,可以改成:
# http-request redirect scheme https code 301 if !{ ssl_fc }
# HTTPS 入口:443 端口,SSL 终止
frontend https-in
bind *:443 ssl crt /etc/haproxy/certs/ # ← 注意这里加了 / ,表示目录(自动 SNI)
# 如果是单个 pem 文件,就写成:crt /etc/haproxy/certs/fullchain.pem
mode http
# 统计页面也可以在这里放一份(可选)
# stats uri /stats
# stats enable
# stats auth admin:admin888
acl host_dash hdr(host) -i dash.4.fx4.cn
acl host_arcane hdr(host) -i arcane.4.fx4.cn
acl host_sozu hdr(host) -i sozu.4.fx4.cn
# 为每个域名设置独立的后端或处理方式
use_backend arcane_backend if host_dash
use_backend nginx_backend if host_arcane
use_backend nginx_backend if host_sozu
# 如果没有匹配任何 ACL,默认行为(可加 default_backend 或返回 404) │
│ # default_backend arcane_backend # 或 http-request deny 等
# 如果没有匹配任何 ACL,默认行为拒绝访问
http-request deny
# 后端服务
backend arcane_backend
balance roundrobin
# 健康检查建议加上(HEAD 请求更轻量)
http-check connect
http-check send meth HEAD uri / ver HTTP/1.1
http-check expect status 200
server arcane arcane:3552 check inter 5s rise 2 fall 3
# nginx 后端服务
backend nginx_backend
balance roundrobin
# 健康检查建议加上(HEAD 请求更轻量)
http-check connect
http-check send meth HEAD uri / ver HTTP/1.1
http-check expect rstatus (2|3)[0-9][0-9]
# 保留原始 Host 头以避免串站问题
http-request set-header Host %[req.hdr(Host)]
server nginx nginx:80 check inter 5s rise 2 fall 3
增加 Websocket 配置
global
log stdout format raw local0 info # Docker 日志输出到 stdout,便于 docker logs 查看
maxconn 4096
master-worker # 支持优雅 reload,无需停机
# daemon 不要加(Docker 必须前台运行)
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5s
timeout client 30s
timeout server 30s
timeout tunnel 1h # ← WebSocket 关键!建议 1h 或更大(0=不限,但生产慎用)
# 如果你的 WS 连接很长(如聊天/实时数据),可设 12h 或 86400s
# HTTP 入口:80 端口,针对特定域名强制跳 HTTPS
frontend http-in
bind *:80
mode http
# 统计页面(建议只在内部访问,或加 IP ACL 限制)
stats uri /stats
stats enable
stats auth admin:admin888
stats refresh 10s
stats show-legends
acl is_dash hdr(host) -i dash.4.fx4.cn
acl is_arcane hdr(host) -i arcane.4.fx4.cn
acl is_sozu hdr(host) -i sozu.4.fx4.cn
http-request redirect scheme https code 301 if is_dash
http-request redirect scheme https code 301 if is_arcane
http-request redirect scheme https code 301 if is_sozu
# 如果以后想所有 HTTP 都强制 HTTPS,可改成下面这行(覆盖所有域名)
# http-request redirect scheme https code 301 if !{ ssl_fc }
# HTTPS 入口:443 端口,SSL 终止(目录模式自动 SNI 选证书)
frontend https-in
bind *:443 ssl crt /etc/haproxy/certs/ # 目录结尾加 / 表示自动按域名选 pem 文件
mode http
# 可选:在这里也放一份 stats(如果想 HTTPS 访问统计页)
# stats uri /stats
# stats enable
# stats auth admin:admin888
acl host_dash hdr(host) -i dash.4.fx4.cn
acl host_arcane hdr(host) -i arcane.4.fx4.cn
acl host_sozu hdr(host) -i sozu.4.fx4.cn
# 路由规则
use_backend arcane_backend if host_dash # dash → arcane(支持 WS)
use_backend nginx_backend if host_arcane
use_backend nginx_backend if host_sozu
# 未匹配任何域名 → 直接拒绝(安全默认)
http-request deny
# arcane 后端(支持 WebSocket)
backend arcane_backend
balance roundrobin
mode http
timeout tunnel 1h # ← 再次确认(覆盖 defaults,如果需要不同值可独立设)
timeout client 1h # 与 tunnel 保持一致或更大
timeout server 1h
# 健康检查(用 HEAD 轻量,避免 WS 路径干扰)
http-check connect
http-check send meth HEAD uri / ver HTTP/1.1
http-check expect status 200
# 保留原始 Host 头(防止后端应用判断 Host 出错)
http-request set-header Host %[req.hdr(Host)]
server arcane arcane:3552 check inter 5s rise 2 fall 3
# nginx 后端(普通 HTTP,无 WS 需求)
backend nginx_backend
balance roundrobin
mode http
http-check connect
http-check send meth HEAD uri / ver HTTP/1.1
http-check expect rstatus (2|3)[0-9][0-9]
http-request set-header Host %[req.hdr(Host)]
server nginx nginx:80 check inter 5s rise 2 fall 3
Let's Encrypt 申请的证书需要合并为一个 pem 文件
cat "example.com.fullchain.cer" "example.com.key" > "example.com.pem"