CentOS7.2 负载均衡层nginx-1.10.1增加sticky session模块支持

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CentOS7.2 负载均衡层nginx-1.10.1增加sticky session模块支持相关的知识,希望对你有一定的参考价值。

大家的网站都难免会遇到验证码的议题,前台后台的登入,都需要有验证码来做登入校验。

因为有些应用的验证码是在系统缓存中产生的,如果你使用的是负载均衡,那可能就会出现和我一样的情况:在验证验证码时,负载均衡在起着作用,用户访问的页面因在两台服务器间承接跳转的,会导致用户一直无法验证成功,所以在负载均衡上需要做sticky session支持,才能解决此问题。

所以我就要着手去处理这个问题。

安装环境及软件版本:

操作系统版本:CentOS 7.2 64bit

负载均衡层:nginx-1.10.1

服务层:Tomcat 7.0.72

nginx-sticky-module版本:1.1


因为我之前在负载均衡层nginx已经编译完成并使用,所以要增加sticky session的话,就需要在Nginx上再安装支持粘性会话的插件即可

在官网上有看到Nginx plus对于应用模块的支持,但是对于开源免费版的nginx貌似却还没有,所以我们先去下载第三方支持的插件


1.下载地址:

https://nginx-sticky-module.googlecode.com/files/nginx-sticky-module-1.1.tar.gz

 

发现在nginx-sticky-module中最新的也是2012年出的nginx-sticky-module-1.1.tar.gz,之后就没有再出过新版了,所以就选择最新版本就好了,nginx-sticky-module-1.0.tar.gz好像不在支持使用了,而且1.1版本增加了权重的参数.


2.把下载好的安装包放到你想要放置的位置去解压:

我就把它放在经常放置的位置/data0/soft/,然后解压:

[[email protected]]# tar -xf nginx-sticky-module-1.1.tar.gz

在/data0/soft/nginx-sticky-module-1.1里需要做些准备工作,否则在后续编译nginx时会报错


为了明确了解看到错误提示,直接进行编译nginx查看,后续再处理也可以。所以为了方便了解错误,我就直接编译了。


3.在nginx上安装sticky模块

如果你和我一样之前也安装过nginx,又不记得曾经安装过哪些模块,但又不想影响原有的模块,有个指令可以帮到你。

就是到你现系统在跑的nginx目录的sbin里用./nginx -V查看曾经编译时所用的历史指令

[[email protected]~]# /data0/work/nginx/sbin/nginx -V

nginx version: nginx/1.10.1

built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) 

built with OpenSSL 1.0.1e-fips 11 Feb 2013

TLS SNI support enabled

configure arguments: 

--prefix=/data0/work/nginx 

--pid-path=/data0/work/nginx/logs/nginx.pid 

--lock-path=/var/lock/nginx.lock 

--user=nginx 

--group=nginx 

--with-http_ssl_module 

--with-http_flv_module 

--with-http_stub_status_module 

--with-http_gzip_static_module 

--http-client-body-temp-path=/var/tmp/nginx/client/ 

--http-proxy-temp-path=/var/tmp/nginx/proxy/ 

--http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ 

--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi 

--http-scgi-temp-path=/var/tmp/nginx/scgi 

--with-pcre 

--add-module=/data0/soft/nginx_upstream_check_module-master/


然后到你需要安装的nginx源码包当中去,编译语句参照原先的,只要末尾添加sticky session模块--add-module=/data0/soft/nginx-sticky-module-1.1/即可

[[email protected]~]# cd /data0/work/nginx-1.10.1

[[email protected] ]# ./configure --prefix=/data0/work/nginx 

--pid-path=/data0/work/nginx/logs/nginx.pid 

--lock-path=/var/lock/nginx.lock 

--user=nginx --group=nginx 

--with-http_ssl_module --with-http_flv_module 

--with-http_stub_status_module 

--with-http_gzip_static_module 

--http-client-body-temp-path=/var/tmp/nginx/client/ 

--http-proxy-temp-path=/var/tmp/nginx/proxy/ 

--http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ 

--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi 

--http-scgi-temp-path=/var/tmp/nginx/scgi 

--with-pcre 

--add-module=/data0/soft/nginx_upstream_check_module-master/ 

--add-module=/data0/soft/nginx-sticky-module-1.1/


接着进行make编译

[[email protected] ]# make && make install  


发现报错了:

cc1: all warnings being treated as errors

make[1]: *** [objs/addon/nginx-sticky-module-1.1/ngx_http_sticky_module.o] Error 1

make[1]: Leaving directory `/data0/work/nginx-1.10.1‘

make: *** [build] Error 2


处理办法:

a.根据资料把ngx_http_sticky_misc.c 的281行修改如下即可解决问题

[[email protected]~ ]vim /data0/soft/nginx-sticky-module-1.1/ngx_http_sticky_misc.c


281         digest->len = ngx_sock_ntop(in, digest->data, len, 1);


原digest->len = ngx_sock_ntop(in,digest

        ->data, len, 1);

改后digest->len = ngx_sock_ntop(in,sizeof(struct sockaddr_in),digest

        ->data, len, 1);


b.还要把ngx_http_sticky_module.c 的322行修改如下可解决问题

[[email protected]~ ]vim /data0/soft/nginx-sticky-module-1.1/ngx_http_sticky_module.c 

332          #if defined(nginx_version) && nginx_version >= 1009000   ---加

333                 iphp->rrp.current = peer;       --加

334          #else              --加

335                 iphp->rrp.current = iphp->selected_peer; --原有内容

336          #endif   --加

备注:其实就是找到iphp->rrp.current = iphp->selected_peer;在其前后添加内容

 

接着继续进行make&& make install编译即可

[[email protected] ]# make && make install

 

4.在nginx的配置文档里配置启用sticky模块功能

因为我是在原有的基础上进行编译安装,且没有更换版本升级,直接安装,所以原有的nginx.conf配置文件不会被覆盖,只是nginx的执行档会重新生成一个

那nginx的upstream如何使用sticky呢,很简单,方法如下:

[[email protected]~]# vim /data0/work/nginx/conf/nginx.conf

找到upstream模块添加sticky;

 upstream information{

         sticky;  

         server 172.16.22.3:80  max_fails=2 ;

         server 172.16.22.4:80  max_fails=2 ;

         check interval=3000 rise=2 fall=5 timeout=1000 type=http; 

        }

注: sticky; 是针对--sticky模块的设定

     check interval=3000 rise=2 fall=5 timeout=1000 type=http; 是针对upstream后台健康检查使用,增加模块是nginx_upstream_check_module-master

    当然你还没有安装nginx_upstream_check_module-master模块,可以先注释掉这个设定。等到后续有需求再进行开启。

 

5.nginx sticky其他语法使用说明

sticky [name=route] [domain=.foo.bar] [path=/] [expires=1h] [hash=index|md5|sha1] [no_fallback];

name: 可以为任何的string字符,默认是route

domain:哪些域名下可以使用这个cookie

path:哪些路径对启用sticky,例如path/test,那么只有test这个目录才会使用sticky做负载均衡

expires:cookie过期时间,默认浏览器关闭就过期,也就是会话方式。

no_fallbackup:如果设置了这个,cookie对应的服务器挂了,那么将会返回502(bad gateway 或者 proxy error),不建议启用


nginx sticky expires用法:

upstream information {

     sticky expires=1h;

     server 172.16.22.3:80  max_fails=2 ;

     server 172.16.22.4:80  max_fails=2 ;

}

启用了过期,cookie 1个小时才过期


6.经过上述的相关设定后,便可查看stitcky session的问题是否成功解决

#注:下列谈及的tomcat服务器是在做了集群(即session共享的前提下)

a.重启nginx服务

先测试配置文件是否准确无误

[[email protected]~ ]# /data0/work/nginx/sbin/nginx -t

nginx: the configuration file /data0/work/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /data0/work/nginx/conf/nginx.conf test is successful

#如果有问题,请按照它给的提示进行查找和修改即可

 

重启nginx服务 

[[email protected]~ ]# /data0/work/nginx/sbin/nginx -s reload


b.为了方便查看,我们就在后端的那两台tomcat服务上设定下

因为我后端是两台tomcat服务器,每台服务器的JESSIONED值都有特殊的标志。

所以在我的两台后端Tomcat服务器上,我都做了些准备工作来方便我辨别,并通过浏览器访问负载均衡层来查看实际是哪一台机器在提供服务。

请到你的tomcat服务器上进行下列操作:

[[email protected]~ ]# vim  /data0/work/tomcat01/conf/server.xml

找到里面的第103行

 <!-- You should set jvmRoute to support load-balancing via AJP ie :

    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">

    -->

取消掉注释,并修改成如下内容:

 <Engine name="Catalina" defaultHost="localhost" jvmRoute="Tomcat01">

 #注:为了好辨别,我就把jvmRoute改成Tomcat01,同样Tomcat02的服务器也做同样的上述操作,不同的是把jvmRoute设置成Tomcat02

 

在tomcat服务器的发布文档里的编写放置一个index.jsp页面,内容如下:

[[email protected]~ ]# vim  /data0/work/tomcat01/webapps/ROOT/jsp/index.jsp

<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<html>

  <head>

<title>tomcat01</title>

  </head>

<body>

<h1><font color="red">Session serviced by tomcat </font></h1>

<table aligh="center" border="1">

<tr>

<td>Session ID </td>

              <td><%=session.getId() %></td>

<% session.setAttribute("abc","adc");%>

           </tr>

<tr>

<td>Created on</td>

<td><%=session.getCreationTime() %></td>

</tr>

   </table>

</body>

<html>


然而tomcat02服务器做同样的动作,只是把index.jsp页面中tomcat01替换成tomcat02


c.比如172.16.22.3这台是tomcat01,172.16.22.4这台是tomcat02.当你访问http://172.16.22.2/index.jsp页面时,在为开启sticky session模块前,不管怎么刷新访问页面,JESSIONED值都是不变的,但是承载的tomcat会交替变化.

如下图所示:

在tomcat01上承接服务:

技术分享

刷新页面后,发现是tomcat02上承接服务,且session ID不变

技术分享


但是如果Nginx配置档开启了sticky模块,我们可以看到JESSIONED值也不会发生变化.但无论你怎么刷新,它都死死的粘滞在其中一台tomcat服务器上.

技术分享

备注:每台后端真实服务器都会有一个唯一的route值,所以不管你真实服务器前端有几个装了sticky的nginx代理,他都是不会变化的. 这个cookie是会话方式的,所以你浏览器关闭了,服务器会给你重新分配一台服务器。


经过上述操作,发现sticky模块添加成功!

本文出自 “10793382” 博客,请务必保留此出处http://10803382.blog.51cto.com/10793382/1924766

以上是关于CentOS7.2 负载均衡层nginx-1.10.1增加sticky session模块支持的主要内容,如果未能解决你的问题,请参考以下文章

四层负载均衡和七层负载均衡的区别

四层负载均衡与七层负载均衡区别

HAproxy七层负载均衡四层/七层负载均衡

nginx负载均衡

四层负载均衡和七层负载均衡的探究

最接地气的版本 30个字讲透 四层负载均衡 七层负载均衡