点赞
评论
收藏
分享
举报
Nginx与HAProxy会话保持的区别(一)
发表于2022-10-15 20:13

浏览 2k

会话保持

    会话保持在负载均衡中是一个非常重要的功能,目前开源的组件Nginx和HAProxy都具备会话保持的功能,但是在实现上,两个组件又有些许区别,下面我们将分章节对这两个组件的实现对下比较。

Nginx的会话保持

    Nginx的会话保持一般有两种实现方式,一种是原生的ip_hash,一种是来自第三方的模块

nginx-sticky-module。

  • ip_hash:即源地址哈希,nginx会将客户端IP地址进行哈希,将来自于同一个客户端IP的请求,转发到同一台后端服务器;
  • sticky:是一个第三方模块提供的功能,利用cookie实现会话保持。客户端请求的后端服务器的响应在经过nginx时,会被nginx插入一个cookie标识,该标识会与后端服务器做唯一的映射。在有效期内,当客户端携带该cookie第二次向nginx发起请求时,nginx会把该请求根据cookie标识,转发至同一台后端服务器;

Sticky模块的编译

  • 步骤1:获取 nginx-sticky-module模块:

https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/src/master/

  • 步骤2:获取开源nginx src.rpm包:

https://dl.fedoraproject.org/pub/epel/7/SRPMS/Packages/n/

  • 步骤3:将步骤2获取的nginx-1.20.1-9.el7.src.rpm包解压,并将步骤1获取的nginx-sticky-module-ng-master源码包上传至解压后的nginx-1.20.1源码目录下;
  • 步骤4:在步骤2解压后的nginx.spec文件中,添加编译sticky模块:

--add-module=%{_builddir}/nginx-%{version}/nginx-sticky-module-ng-master

  • 步骤5:通过rpmbuild命令对步骤3中解压的nginx源码包进行编译;
  • 步骤6:将编译好的nginx rpm包进行安装后,执行nginx -V命令,可以看到 configure arguments 中已成功加载 nginx-sticky-module-ng-master 模块:
[root@localhost ~]# nginx -V
nginx version: nginx/1.20.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-compat --with-debug --with-file-aio --with-google_perftools_module --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_perl_module=dynamic --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --add-module=/builddir/build/BUILD/nginx-1.20.1/nginx-sticky-module-ng-master --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-threads --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/bclinux/bclinux-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/bclinux/bclinux-hardened-ld -Wl,-E'

Nginx配置轮询模式

    配置nginx的反向代理,其拓扑结构如下图所示:

在nginx的upstream段,首先配置默认的轮询转发策略,其详细配置如下:

 upstream test {
server 192.168.80.131:80;
server 192.168.80.132:80;
}

server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

location / {
proxy_pass http://test;
}

error_page 404 /404.html;
location = /404.html {
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

启动反向代理nginx服务,客户端对nginx发起请求,nginx对客户端的请求进行轮询转发,其响应如下:

Nginx配置Sticky

    在nginx的upstream段配置sticky,此处设置了sticky中cookie的名称为route,有效期为3小时,配置详情如下:

 upstream test {
sticky name=route expires=3h;
server 192.168.80.131:80;
server 192.168.80.132:80;
}

重新加载nginx服务, 客户端对nginx发起请求,nginx对客户端的请求进行轮询转发,在响应中添加Set-Cookie HTTP头部信息,并包含名称为route的标识值。其响应结果如下:

[root@localhost nginx]# curl http://192.168.80.130 -v
* About to connect() to 192.168.80.130 port 80 (#0)
* Trying 192.168.80.130...
* Connected to 192.168.80.130 (192.168.80.130) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 192.168.80.130
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.20.1
< Date: Sat, 15 Oct 2022 11:18:23 GMT
< Content-Type: text/html
< Content-Length: 22
< Connection: keep-alive
< Set-Cookie: route=2c0838f2239d41f4dcde831cd005ab35; Expires=Sat, 15-Oct-2022 14:18:23 GMT; Path=/
< Last-Modified: Mon, 26 Sep 2022 08:35:53 GMT
< ETag: "63316469-16"
< Accept-Ranges: bytes
<
192.168.80.132 reply!
* Connection #0 to host 192.168.80.130 left intact
[root@localhost nginx]# curl http://192.168.80.130 -v
* About to connect() to 192.168.80.130 port 80 (#0)
* Trying 192.168.80.130...
* Connected to 192.168.80.130 (192.168.80.130) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 192.168.80.130
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.20.1
< Date: Sat, 15 Oct 2022 11:18:24 GMT
< Content-Type: text/html
< Content-Length: 22
< Connection: keep-alive
< Set-Cookie: route=abcc5f5967f15b928b0e88223f35ad6e; Expires=Sat, 15-Oct-2022 14:18:24 GMT; Path=/
< Last-Modified: Mon, 26 Sep 2022 08:35:09 GMT
< ETag: "6331643d-16"
< Accept-Ranges: bytes
<
192.168.80.131 reply!

此时在后端服务器上抓包,查看服务器收到的nginx转发请求及响应的情况,如下图所示:

通过对比客户端收到的响应,以及后端服务器收到及响应的结果可知,配置了sticky模块的nginx反向代理,在将后端服务器的响应返回给客户端时,在服务器原有的HTTP响应头部基础上添加了Set-Cookie头部信息。

Sticky测试

我们在第二次的客户端请求中,添加首次请求的Cookie信息,经过多次请求,nginx均将请求转发至同一个后端服务器,达到了会话保持的效果。此时nginx反向代理的响应如下图所示:

此时,在后端服务器192.168.80.132上抓包,可以看到,后端服务器上收到了客户端传递的Cookie: route标识的头部信息,如下图所示:

与HAProxy会话保持的不同

    经过上述验证得知,sticky模块支持的会话保持,会在首次请求的响应中添加Set-Cookie标识,用以记录请求转发至特定的后端服务器。当第二次请求携带该Cookie标识时,nginx会将该请求转发至上述特定的服务器,此时后端的服务器收到的请求头会包含该Cookie标识。

    与Nginx的sticky不同的是,HAProxy的cookie会话保持,支持后端服务器对HAProxy设置的Cookie会话保持标识不可见,即其屏蔽了反向代理层会话保持标识的存在,还原了客户端原始的请求头部信息。该部分讨论内容,我们将在下一期为大家进行分析,敬请期待~


已修改于2023-03-07 17:29
本作品系原创
创作不易,留下一份鼓励
lwl

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(0)

按点赞数排序

按时间排序

关于作者
lwl
这家伙很懒还未留下介绍~
3
文章
0
问答
5
粉丝
相关文章
前文提要  上文中我们提到,Nginx的第三方模块nginx-sticky-module支持的会话保持,当第二次请求携带第一次请求响应的Nginx插入的Cookie标识时,Nginx会将该请求转发至后端特定的服务器,此时后端的服务器收到的请求头会包含该Cookie标识。  HAProxy支持的会话保持,与Nginx第三方模块sticky的实现有些许差别,其支持插入的cookie标识对后端服务器不可见,下面我们将进行进一步的说明。HAProxy插入COOKIE  HAProxy支持cookieinsert,即当客户端首次请求时,HAProxy后在请求响应中,添加Set-Cookie的HTTP头部信息,并将该Cookie与后端服务器的关系存于缓存的cookie表中。结合配置indirect选项,当第二次客户端携带该Cookie发起请求时,HAProxy通过查询本地缓存的cookie表,删除请求头中自行设置的Cookie标识,将请求转发至对应的服务器。此时后端服务器接受到的请求,不会包含HAProxy设置的Cookie
点赞 4
浏览 1.4k
原文作者:林静 原文链接:分享实录 | NGINX QUIC & HTTP/3 最新进展 转载来源:NGINX 开源社区 NGINX 唯一中文官方社区 ,尽在 nginx.org.cn 编者按——本
点赞 0
浏览 864
原文作者:Derek DeJonghe of F5原文链接:全球首发 | 《NGINX 完全指南》中文版转载来源:NGINX 开源社区NGINX唯一中文官方社区 ,尽在 nginx.org.cn在社区
点赞 1
浏览 6.9k