使用哈希方法与 nginx 进行负载平衡
Load balancing with nginx using hash method
我想在几个 node.js 应用程序节点前使用 nginx 作为负载均衡器。
round-robin
和 ip_hash
方法非常容易实现,但在我的用例中,它们并不是最合适的。
我需要 nginx 为后端节点提供客户端服务,这些客户端由 first-landed 节点给出 session id。
在谷歌搜索期间,我想出了 "hash"ing 方法,但找不到太多资源。
这是我尝试过的:
my_site.conf:
http {
upstream my_servers {
hash $remote_addr$http_session_id consistent;
server 127.0.0.1:3000;
server 127.0.0.1:3001;
server 127.0.0.1:3002;
}
server {
listen 1234;
server_name example.com;
location / {
proxy_pass http://my_servers;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
并且在申请时,我 return Session-ID
header 使用 session id。
res.setHeader('Session-ID', req.sessionID);
我错过了什么,但是什么?
$http_session_id
指的是客户端(浏览器)发送的header,不是你的应用响应。而您需要的是 http://nginx.org/r/sticky,但它仅限商业订阅。
有 third-party 模块与商业模块的功能相同,但您必须重新编译 nginx。
它不是开箱即用的,因为 nginx 是一个(好的)网络服务器,但不是真正的 load-balancer。
load-balancing.
更喜欢 haproxy
此外,您需要的不是散列。您需要在 session-id header 上持久化,并且您需要能够在源 IP 上持久化直到获得此 header。
这对于 HAProxy 来说非常简单。 HAProxy 还可用于检查 session id 是否由服务器生成或是否由客户端伪造。
后端 myapp
# 在内存中创建一个 stick table
#(注意:使用peers来同步table的内容)
stick-table type string len 32 expire 1h size 1m
# 在table中匹配客户端http-session-id做持久化
棒匹配 hdr(http-session-id)
# 如果没有找到,则使用源IP地址
坚持 src,lower # 将 IP 地址转换为字符串的肮脏技巧
#学习服务器已经生成的http-session-id
坚持 store-response hdr(http-session-id)
# 如果 http-session-id 似乎是伪造的(在 table 中找不到),请添加一个 header
#(注意:仅适用于 1.6-dev)
acl 有-session-id req.hdr(http-session-id) -m 找到
acl 未知-session-id req.hdr(http-session-id),in_table(myapp)
http-request set-header X-warning 未知\ session-id 如果有-session-id 未知-session-id
那么你就完全安全了:)
巴蒂斯特
我想在几个 node.js 应用程序节点前使用 nginx 作为负载均衡器。
round-robin
和 ip_hash
方法非常容易实现,但在我的用例中,它们并不是最合适的。
我需要 nginx 为后端节点提供客户端服务,这些客户端由 first-landed 节点给出 session id。
在谷歌搜索期间,我想出了 "hash"ing 方法,但找不到太多资源。
这是我尝试过的:
my_site.conf:
http {
upstream my_servers {
hash $remote_addr$http_session_id consistent;
server 127.0.0.1:3000;
server 127.0.0.1:3001;
server 127.0.0.1:3002;
}
server {
listen 1234;
server_name example.com;
location / {
proxy_pass http://my_servers;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
并且在申请时,我 return Session-ID
header 使用 session id。
res.setHeader('Session-ID', req.sessionID);
我错过了什么,但是什么?
$http_session_id
指的是客户端(浏览器)发送的header,不是你的应用响应。而您需要的是 http://nginx.org/r/sticky,但它仅限商业订阅。
有 third-party 模块与商业模块的功能相同,但您必须重新编译 nginx。
它不是开箱即用的,因为 nginx 是一个(好的)网络服务器,但不是真正的 load-balancer。 load-balancing.
更喜欢 haproxy此外,您需要的不是散列。您需要在 session-id header 上持久化,并且您需要能够在源 IP 上持久化直到获得此 header。 这对于 HAProxy 来说非常简单。 HAProxy 还可用于检查 session id 是否由服务器生成或是否由客户端伪造。
后端 myapp # 在内存中创建一个 stick table #(注意:使用peers来同步table的内容) stick-table type string len 32 expire 1h size 1m # 在table中匹配客户端http-session-id做持久化 棒匹配 hdr(http-session-id) # 如果没有找到,则使用源IP地址 坚持 src,lower # 将 IP 地址转换为字符串的肮脏技巧
#学习服务器已经生成的http-session-id 坚持 store-response hdr(http-session-id)
# 如果 http-session-id 似乎是伪造的(在 table 中找不到),请添加一个 header #(注意:仅适用于 1.6-dev) acl 有-session-id req.hdr(http-session-id) -m 找到 acl 未知-session-id req.hdr(http-session-id),in_table(myapp) http-request set-header X-warning 未知\ session-id 如果有-session-id 未知-session-id
那么你就完全安全了:)
巴蒂斯特