在 Django 应用程序中使用 HAProxy 和 uWSGI 执行第 7 层健康检查
Performing layer 7 health check with HAProxy and uWSGI in Django application
我正在使用这个 uwsgi.ini
来 运行 一个 Django
应用程序。
[uwsgi]
http-socket = :8000
enable-proxy-protocol = true
chdir = /usr/local/src/api
module = api.wsgi
uid = root
gid = root
pidfile = /var/run/api-uwsgi.pid
master = true
processes = 10
chmod-socket = 664
threaded-logger = true
logto = /var/log/api/uwsgi.log
log-maxsize = 10000000
logfile-chown = true
vacuum = true
die-on-term = true
我添加了 API url 以在 /health-check
url 下执行数据库和缓存健康检查。这个 API returns 状态代码 200 如果一切正常。现在我希望能够使用此 API 和 HAProxy
在第 7 层进行健康检查,但使用 option httpchk
响应状态代码为 301,因此健康检查失败。这是我的 HAProxy
配置的后端部分。
backend http_server
mode http
balance leastconn
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk
http-check send meth GET uri /health-check ver HTTP/1.1 hdr Accept application\json
http-check expect rstatus 200
server app1 192.168.0.11:8000 check inter 500 downinter 5s fall 2 rise 3
server app2 192.168.0.12:8000 check inter 500 downinter 5s fall 2 rise 3
这是 运行 使用 uWSGI
和 HAProxy
连接 Django
应用程序的结果。请注意,第 4 层的健康检查按预期工作。
Server http_server/app2 is DOWN, reason: Layer7 wrong status, code: 301, info: "Moved Permanently", check duration: 54ms. 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
那么是什么导致了这个问题,有没有办法解决它?
解决这个问题有两个步骤:
- 如果没有 url 路由与请求的
Django
的 APPEND_SLASH
设置相匹配,则在 url 的末尾附加一个 /
并执行一个 301 重定向。我使用 /health-check
而不是 /health-check/
所以请求从 /health-check
重定向到 /health-check/
http-check
的 hdr
选项接受键和值。对于 accept
header 值必须在引号内,因此 hdr Accept application\json
变为 hdr accept "application/json"
这是后端配置的最终工作部分:
backend http_server
mode http
balance leastconn
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk
http-check send meth GET uri /health-check/ ver HTTP/1.1 hdr accept "application/json"
http-check expect rstatus 200
server 192.168.0.11:8000 check inter 500 downinter 2s fall 2 rise 3
server 192.168.0.12:8000 check inter 500 downinter 2s fall 2 rise 3
我正在使用这个 uwsgi.ini
来 运行 一个 Django
应用程序。
[uwsgi]
http-socket = :8000
enable-proxy-protocol = true
chdir = /usr/local/src/api
module = api.wsgi
uid = root
gid = root
pidfile = /var/run/api-uwsgi.pid
master = true
processes = 10
chmod-socket = 664
threaded-logger = true
logto = /var/log/api/uwsgi.log
log-maxsize = 10000000
logfile-chown = true
vacuum = true
die-on-term = true
我添加了 API url 以在 /health-check
url 下执行数据库和缓存健康检查。这个 API returns 状态代码 200 如果一切正常。现在我希望能够使用此 API 和 HAProxy
在第 7 层进行健康检查,但使用 option httpchk
响应状态代码为 301,因此健康检查失败。这是我的 HAProxy
配置的后端部分。
backend http_server
mode http
balance leastconn
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk
http-check send meth GET uri /health-check ver HTTP/1.1 hdr Accept application\json
http-check expect rstatus 200
server app1 192.168.0.11:8000 check inter 500 downinter 5s fall 2 rise 3
server app2 192.168.0.12:8000 check inter 500 downinter 5s fall 2 rise 3
这是 运行 使用 uWSGI
和 HAProxy
连接 Django
应用程序的结果。请注意,第 4 层的健康检查按预期工作。
Server http_server/app2 is DOWN, reason: Layer7 wrong status, code: 301, info: "Moved Permanently", check duration: 54ms. 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
那么是什么导致了这个问题,有没有办法解决它?
解决这个问题有两个步骤:
- 如果没有 url 路由与请求的
Django
的APPEND_SLASH
设置相匹配,则在 url 的末尾附加一个/
并执行一个 301 重定向。我使用/health-check
而不是/health-check/
所以请求从/health-check
重定向到/health-check/
http-check
的hdr
选项接受键和值。对于accept
header 值必须在引号内,因此hdr Accept application\json
变为hdr accept "application/json"
这是后端配置的最终工作部分:
backend http_server
mode http
balance leastconn
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk
http-check send meth GET uri /health-check/ ver HTTP/1.1 hdr accept "application/json"
http-check expect rstatus 200
server 192.168.0.11:8000 check inter 500 downinter 2s fall 2 rise 3
server 192.168.0.12:8000 check inter 500 downinter 2s fall 2 rise 3