基于nginx-sticky-module-ng实现会话保持

方案

对服务进行集群部署,前端进行负载均衡时,需要实现会话保持,对于同一会话的多个请求,通过集群中的一个节点来提供服务。系统的部署结构如图所示,通过Resin部署Web应用提供服务,通过Nginx进行负载均衡。基于nginx-sticky-module-ng实现会话保持。

方案

安装

Nginx已安装(版本为1.7.9),此处介绍如何添加nginx-sticky-module-ng。

  1. nginx-sticky-module-ng下载源码压缩包并解压;
  2. “nginx -V”查看原先安装Nginx时的配置信息:

    1
    2
    3
    4
    # /usr/local/nginx/sbin/nginx -V
    nginx version: nginx/1.7.9
    built by gcc 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC)
    configure arguments: --prefix=/usr/local/nginx --with-pcre=/opt/soft/pcre-8.36 --with-zlib=/opt/soft/zlib-1.2.8
  3. 在Nginx源码目录下使用上述配置信息进行配置,并添加nginx-sticky-module-ng:

    1
    ./configure --prefix=/usr/local/nginx --with-pcre=/opt/soft/pcre-8.36 --with-zlib=/opt/soft/zlib-1.2.8 --add-module=/opt/soft/nginx-sticky-module-1.1
  4. “make”进行编译,若编译时报“src/core/ngx_sha1.h:19:17: fatal error: sha.h: No such file or directory”错误,则先执行“yum install openssl-devel”安装OpenSSL包再配置;

  5. 编译成功后,备份/usr/local/nginx/sbin/nginx,并使用objs/nginx覆盖/usr/local/nginx/sbin/nginx:
    1
    2
    mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.backup
    cp objs/nginx /usr/local/nginx/sbin/

配置

使用Resin启动两个Web应用进程,端口分别是8082和8089,两个Web应用中都包含一个jsp页面session_sticky/test.jsp:

1
2
3
4
5
6
7
8
9
10
11
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试Session Sticky</title>
</head>
<body>
Service 1

Session Id: <%=request.getSession().getId()%>
</body>
</html>

test.jsp在两个Web应用中的不同在于一个输出“Service 1”,另一个输出“Service 2”。
在Nginx中配置upstream和location,实现反向代理和会话保持:

1
2
3
4
5
6
7
8
9
10

upstream session_sticky-server {
sticky;
server xx.xx.xx.xx:8082;
server xx.xx.xx.xx:8089;
}

location ^~/session_sticky/ {
proxy_pass http://session_sticky-server;
}

测试

  1. 删除upstream中的“sticky”,使用默认的轮询方式进行反向代理,访问test.jsp,页面输出中交替出现“Service 1”和“Service 2”,说明请求交替发往两个Web应用,会话未保持:
    1
    2
  2. 在upstream中添加“sticky”,访问test.jsp,页面输出中一直出现“Service 1”,说明请求发往第一个应用,会话保持:
    1
  3. 在2的基础上,停掉第一个应用,继续访问test.jsp,页面仍有响应,输出中一直出现“Service 2”,说明请求在检测到失败后,会自动发往第二个应用,并在第二个应用会话保持:
    2