使用Redis存储Nginx+Tomcat负载均衡集群的Session

环境:Cent OS 7.0(虚拟机环境)、Nginx 1.9.8、Redis 3.2.1

一、背景

在使用Nginx+Tomcat实现负载均衡的时候,由于Nginx对不同的请求分发到某一个Tomcat,Tomcat在运行的时候分别是不同的容器里,因为会出现session不同步或者丢失的问题。


二、Nginx安装与配置

1、Nginx安装网上的资源对于安装Nginx的介绍比较多,例如最简单的为:

(1) 获取nginx,在http://nginx.org/download/上可以获取当前最新的版本下载,例如:wget http://nginx.org/download/nginx-1.9.8.tar.gz

(2)解压缩tar -xvf nginx-1.9.8.tar.gz包。

(3)进入解压缩目录,执行./configure --prefix=/usr/local/nginx-1.9.8 将Nginx安装到/usr/local/nginx-1.9.8目录下

(4)make & make install

安装的过程会将Nginx安装到/usr/local/nginx-1.9.8目录下,启动Nginx测试是否可以正常启动。

2、修改Nginx配置多Tomcat服务器2.1、修改conf/nginx.conf文件,在server标签上边添加upstream如下:

这里指定了本机下的两个Tomcat实例,端口分别为8080,8060,权重都为1,后边配置Tomcat实例,mynginxserver这个是自己随意命名的,下边要用到。

2.2、配置server标签:

2.3、配置之后的完整内容如下(1.9.8版本删去了注释后的配置内容):

2.4、具体的配置项和配置项的具体意义请参考:

https://www.nginx.com/resources/wiki/start/topics/examples/full/


三、Tomcat多实例的配置

1、解压apache-tomcat-7.0.67.zip 得到apache-tomcat-7.0.67

[root@localhost www]# unzip apache-tomcat-7.0.67.zip

2、将apache-tomcat-7.0.67重命名为tomcat1

[root@localhost www]# mv apache-tomcat-7.0.67 tomcat1

重复1、2过程得到tomcat1和tomcat2如下所示:

3、修改Tomcat1的端口为8080和部署项目文件编辑tomcat下的conf/server.xml,修改端口号为8080,自己写的用于测试Nginx反向代理的web项目war包下载地址:

http://download.csdn.net/detail/u010870518/9585683

下载好之后将解压之后的编译好的项目文件放到tomcat1/webapps/ROOT/目录下:

修改index.jsp和login.jsp文件分别标识为具体的Tomcat容器

4、修改Tomcat2的端口为8060和部署项目文件编辑tomcat下的conf/server.xml,修改端口号为8060,然后和上述3中的一样,下载war内容,放在tomcat2/webapps/ROOT/下,修改index.jsp和login.jsp用于标识具体的Tomcat容器。

5、分别启动tomcat1和tomcat2。

6、重启Nginx服务,访问IP地址:192.168.1.149:80(这个是访问的虚拟机IP地址)。

7、观看效果

可以看出,Nginx已经进行了请求分发,转发到具体的某一个Tomcat


四、Redis的安装与配置

由于篇幅过长,请参考本人写的:

http://blog.csdn.net/xlgen157387/article/details/52022793


五、tomcat-redis-session-manager开源项目的使用

1、开源项目地址:

https://github.com/jcoleman/tomcat-redis-session-manager

2、下载代码之后需要进行重新编译,生成所需要的jar,任意创建maven项目,将src下的代码拷贝到具体位置,如下:

maven的pom.xml文件如下:

3、然后打开terminal,执行mvn clean 和mvn install 将编译好的代码打包为:tomcat-redis-session-1.0-SNAPSHOT.jar

4、将**tomcat-redis-session-1.0-SNAPSHOT.jar、jedis-2.7.2.jar、commons-pool2-2.0.jar** 三个jar包分别放在tomcat1和tomcat2实例下的lib目录下。

免费下载这三个jar:

http://download.csdn.net/detail/u010870518/9585716

5、修改tomcat实例下conf/contex.xml文件

<?xml version='1.0' encoding='utf-8'?> <Context> <WatchedResource>WEB-INF/web.xml</WatchedResource> <!-- tomcat-redis-session共享配置 --> <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" /> <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager" host="192.168.1.149" port="6379" database="0" maxInactiveInterval="60" /> </Context>

如果不设置密码会报错,如下:


六、效果演示

案例演示的一个登陆请求,登陆成功之后将用户信息放在session中,在界面中显示出来(tomcat1实例,tomcat2的实例中只是在 **h2** 标签中做了一下标识)

1、login.jsp文件:

<body>

<h2>Session Demo in Tomcat1</h2>

<form action="/user?type=login" method="post"> 用户名:<input type="text" name="userName"/><br/> 密码:<input type="password" name="userPassword"/><br/> <input type="submit" value="login">

</form>

</body>

2、index.jsp 将登录之后的信息显示在界面上

<body><h2>Session Demo in Tomcat1</h2>

<% User user = (User) request.getSession().getAttribute("USER");

if (user == null) { %>用户为空,没有登录!!!<% } else { %>欢迎: <%=user.getUserName()%><% } %></body>

3、servlet处理请求代码

public class UserServlet extends BaseServlet {

public String login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

User user = new User(); user.setUserName(request.getParameter("userName")); user.setUserPassword(request.getParameter("userPassword")); request.getSession().setAttribute("USER", user); return "index.jsp"; } }

4、效果如下:

可以看出在登录界面的时候刷新请求的tomcat已经由Nginx进行分发请求,登录之后再两个tomcta中已经共享了session

5、查看Redis对session的存储在对contex.xml文件进行配置的时候默认使用的database为0,通过redis-cli工具可看到


七、总结

tomcat-redis-session-manager是一个对用户完全透明的分布式session存储框架,用户只需要在tomcat中进行简单的配置,就可以使用,我们的业务代码是完全和单实例的时候的代码是一样的的,也就是写代码的时候完全不用担心你写的是一个多tomcat实例的代码,完全透明。

如何对框架的原理进行简单的理解,我们首先要知道,在请求过程中的session操作,首先要解析请求中的sessionId信息,然后将sessionId存储到request的参数列表中。然后再从 request获取session的时候,如果存在sessionId那么就根据Id从session池中获取session,如果sessionId不存在或者session失效,那么则新建session并且将session信息放入session池,供下次使用。

如果我们想自己写一个类似于tomcat-redis-session-manager的项目,我们应该知道Tomcat的Session管理机制,在默认的情况下Tomcat的Session管理,如果不进行设置的话是由Tomcat自带的StandardManager类进行控制的,我们可以根据这个类自定义一个Manager,**主要重写的就是org.apache.catalina.session.ManagerBase里边的具体写的操作**,这也是tomcat-redis-session-manager的基本原理,将tomcat的session存储位置指向了Redis

RedisSessionManager继承了org.apache.catalina.session.ManagerBase并重写了add、findSession、createEmptySession、remove等方法,并将对session的增删改查操作指向了对Redis数据存储的操作有兴趣可参考一篇Tomcat中session的管理机制:

http://www.cnblogs.com/interdrp/p/4935614.html

原文发布于微信公众号 - Java后端技术(JavaITWork)

原文发表时间:2016-09-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏雨过天晴

原 PHPStrom 9系列激活码

22640
来自专栏腾讯云Elasticsearch Service

Elasticsearch跨集群数据迁移之离线迁移

用户在腾讯云上自建的ES集群或者在其它云厂商购买的ES集群,如果要迁移至腾讯云ES,用户可以根据自己的业务需要选择适合自己的迁移方案。如果业务可以停服或者可以暂...

4.1K90
来自专栏我的小碗汤

vmware上安装linux过程记录

以前的电脑上安装过vmware+redhat,但是奈何电脑太老,配置太低,打开的时候超级卡,没法用。换了电脑后,再装上玩玩,故此记录一下安装过程。需要安装的小伙...

14710
来自专栏云计算教程系列

如何在Ubuntu 14.04上使用Unicorn和Nginx部署Rails应用程序

当您准备部署Ruby on Rails应用程序时,需要考虑许多有效的设置。本教程将帮助您部署Ruby 在 Rails应用程序中的生产环境,使用PostgreSQ...

10000
来自专栏云计算教程系列

如何在Ubuntu 16.04上将Redis服务器设置为PHP的会话处理程序

Redis是一个开源键值缓存和存储系统,由于其对多种数据类型(如散列,列表,集合和位图等)的高级支持,也称为数据结构服务器。它还支持群集,使其在高度可用和可扩展...

15530
来自专栏吴伟祥

单点登录原理与简单实现 原

web应用采用browser/server架构,http作为通信协议。http是无状态协议,浏览器的每一次请求,服务器会独立处理,不与之前或之后的请求产生关联...

13950
来自专栏苦逼的码农

Linux达人养成计划2---虚拟机下的网络配置

当然也可以选择其他模式,不过这里,我们只讲桥接模式的,至于三种模式的区别,可以自行百度一下。

14530
来自专栏钟绍威的专栏

浅谈spring security 403机制一、无权限访问二、匿名访问三、有权限访问原因机制指定AccessDeniedHandler指定error-page情景原因结论

403就是access denied ,就是请求拒绝,因为权限不足 三种权限级别 一、无权限访问 <security:http security="none"...

783100
来自专栏Java架构沉思录

单点登录原理与简单实现

web应用通常采用browser/server架构,http作为通信协议。http是无状态协议,浏览器的每一次请求,服务器会独立处理,不与之前或之后的请求产生关...

18520
来自专栏别先生

JSP连接mysql数据库的重点

1:用mysql驱动把mysql与tomcat的连接起来。把mysql驱动包(不用解压)放到Tomcat安装目录中lib文件夹下即可。 ? 2:然后在自己的新...

35180

扫码关注云+社区

领取腾讯云代金券