Nginx+Tomcat+Redis实现Session共享

文章目录
  1. 1. 1、软件准备
  2. 2. 2、配置tomcat
  3. 3. 3、配置Nginx
  4. 4. 4、测试页面
  5. 5. 5、启动测试

之前的博文中简单的介绍了一下Nginx的负载均衡配置,比较简单,但是如果实现多台服务器之间的session共享就是一个难题了。

经过查资料,找到了几种解决session共享的方案。

  • 不适用session,换作cookie

    1
    能把session改成cookie,就能避开session的一些弊端,也有资料表明在集群系统中不能使用session。但是博主思考再三,公司项目的session中存储一些比较重要的信息,在以后的业务中也会使用session中的数据,所以直接使用cookie这种方案果断舍弃。
  • 应用服务器自行实现共享

    1
    让服务器自行实现session共享,就需要提供一个后端服务器都能访问的公共容器来存储session,比如redis或者memcache,当系统需要获取session时,直接从redis或memcache中获取即可。

    以上两种方式都与Nginx没多大关系了。下面说说使用nginx如何处理

  • ip_hash

    1
    2
    3
    4
    之前的博客中对upstream的几种方式做了介绍,相信大家还记得ip_hash的介绍吧,每个请求按访问ip的hash结果分配,这样每个访问固定访问一个后端服务器。
    这样一来这个ip下的某个客户端和某个后端服务器就能建立稳固的session。这样每个客户端都只对应一个服务器,那就不存在需要共享session的需要了,不过只用ip这个因子来分配后端,所以还是存在一些缺陷,不能在以下情况下使用:
    1、nginx不是最前端的服务器。ip_hash要求nginx一定是最前端的服务器,否则nginx就得不到正确的ip,也就不能根据ip来分配后端了。比如squid(一个高性能的代理缓存服务器)作为最前端,那么nginx只能获取到squid所在服务器的ip地址,这种分流方式肯定会混乱的。
    2、nginx的后端还有其他方式的负载均衡。如果nginx后端又有其他的负载均衡,将请求又通过另外的方式分流了,那么某个客户端的请求肯定不能定位到同一台服务器上。
  • upstream_hash

    1
    2
    为了解决ip_hash的一些问题,可以使用upstream_hash这个第三方模块,这个模块大多数情况下是用作url_hash的,但是并不妨碍将它用来做session共享;
    这种方式不是很理解,就不做累述了,以后再慢慢研究。读者可自行查找资料学习。

来自于网络上的方案介绍完了,接下来说说博主项目中的实际操作。

博主最初的打算是使用redis来缓存系统数据,刚好也可以实现session共享。可惜,客户公司方面服务器资源不够,不让使用redis,上面第二种方案瞬间被阉割掉了,有点不爽。这里必须吐槽吐槽客户公司。

由于不让使用redis,所以只能使用第三种方式了,这里就不做太多的累述了,比较简单,配置nginx负载均衡的时候将upstream的方式配置为ip_hash即可,具体配置方式在上篇“Nginx负载均衡配置”中已有例子,可做参考。

简单的解释一下公司项目架构,公司项目采用前后台分离的架构,前端页面使用angularJS实现一种单页面应用,后台服务则使用SpringBoot为前端提供数据服务,后台开发者只需要关注后端逻辑,然后将前端需要的数据转为json传给前端,而不需要去考虑页面的跳转等,而前端人员也不需要关注后台逻辑,可以全身心的提供前端的用户体验度,最主要的是前后台分离后,系统开发职责划分的更加清晰。

关于前后台分离方案,这个博客讲的比较好,读者可做参考。

这样就完了?没有,这就完了这篇博客也太水了,虽然客户公司不让使用redis,但是博主还是自己抽时间使用nginx+tomcat+redis来自己实现session共享。

——————————————————————这是一个分隔线——————————————————————-

1、软件准备

因为是自己玩,所以直接在windows上开工了。

nginx-1.11.5,apache-tomcat-7.0.55,redis-2.6.12(windows版)

读者可从这里下载。其中有三个jar包最为重要:

commons-pool-1.6.jar,jedis-2.1.0.jar,tomcat-redis-session-manager-tomcat7.jar,在软件包中的tomcat的lib目录下可找到。

2、配置tomcat

在tomcat中的context.xml文件中加入以下内容

1
2
3
4
5
6
<Valve  className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />
<Manager className="com.radiadesign.catalina.session.RedisSessionManager"
host="localhost"
port="6379"
database="0"
maxInactiveInterval="60" />

将配置好的tomcat三份,分别命名为apache-tomcat-7.0.55-1,apache-tomcat-7.0.55-2,apache-tomcat-7.0.55-3,然后去将每个tomcat的端口改掉,分别改为8081,8082,8083

3、配置Nginx

将三个tomcat服务器用nginx代理,

1
2
3
4
5
upstream  localhost   {
server localhost:8081 weight=1;
server localhost:8082 weight=1;
server localhost:8083 weight=1;
}

4、测试页面

在tomcat的webapp目录下新建test目录,在test中新建index.jsp,然后给三个tomcat都拷贝一份

1
2
3
4
5
6
7
8
9
10
11
12
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
</head>
<body>
<%
out.println(request.getSession().getId());
%>
</body>
</html>

这可能是可与Hello,World媲美的页面了。

5、启动测试

先启动redis,在启动三个tomcat,最后再启动nginx,然后访问页面。

有两种访问方式:

好了,这种session共享完成。

这种Session共享是基于Tomcat完成的,不会侵入项目。当前还有一种实现Session共享的方式,Spring全家桶中,Spring Session框架就是专门做Session管控的。


关注我的微信公众号:FramePower
我会不定期发布相关技术积累,欢迎对技术有追求、志同道合的朋友加入,一起学习成长!


微信公众号

如果文章对你有帮助,欢迎点击上方按钮打赏作者