废话不多说,直接上教程。本教程不涉及java代码后台处理session,直接修改配置即可实现。
一、环境搭建
首先,我是在windows平台搭建的环境,所以,这篇文章主要讲述windows下tomcat集群的搭建,以及session的共享问题
- jdk版本:1.7
下载链接:https://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html
- tomcat版本:7.0
下载链接:https://tomcat.apache.org/download-70.cgi
- nginx版本:1.14
我所采用的是window版本的nginx, 选择稳定版的( Stable version) nginx/Windows 即可。
下载链接:http://nginx.org/en/download.html
- redis版本:2.8
我所采用的是window版本的redis,这个版本是微软维护的。
关键地方:
- 为了解决分布式session共享问题,需要一下几个jar包,放在 tomcat 的 lib 文件夹下
tomcat-redis-session-manager 下载地址:https://github.com/jcoleman/tomcat-redis-session-manager/releases
该文件下载后是 jar包的源码,并没有提供编译好的jar 包,可根据自己的业务需求更改源码,不更改也可以使用。
- 这里我提供一个上述所有的jar包,从这里下载。
下载地址 :https://download.csdn.net/download/lovelifelovecoding/10990378
jdk需要安装,tomcat、nginx、redis解压即可使用。
二、配置文件
1.nginx配置及启动
nginx 常用命令
dos窗口进入 nginx的安装目录
- 启动 start nginx.exe
如果修改了 nginx.conf 需要输入 重新加载 命令 重启生效
- 重新加载 nginx -s reload
- 停止 nginx -s quit
如果成功启动nginx服务启动后,在浏览器输入 localhost:80 可以看到以下界面,表示nginx服务器安装成功。
注意安装的目录不要含有中文,如果有可能会无法访问到到成功页面。
nginx 配置
在 conf 文件夹下找到 nginx.conf 配置文件。配置文件不再说明,网上一搜一大堆,主要说我修改的地方。
在 http {} 内 对比着 原配置文件 添加 如下 代码。
http {
#tomcat集群
upstream myTomcatServers{
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8088 weight=1;
server 127.0.0.1:8089 weight=1;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
proxy_pass http://myTomcatServers;
#设置主机头和客户端真实地址,以便服务器获取客户端真实IP
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
upstream 集群名{} weight 表示权重,数值越大代表访问到这台服务器的几率就越高。
server 127.0.0.1:8080 tomcat 服务器部署地址,后面是tomcat服务器 的端口号。
listen 80 监听80端口,就是 nginx的服务端口
server_name localhost; nignx服务地址,通常就是部署 nginx 服务器的 ip 地址。proxy_pass http://集群名; 这个 集群名 就是与上面的一致即可。主要就是这个配置实现了请求的分发。
2.tomcat配置
这里使用了三台 tomcat 服务器最为例子,每一个服务器更改 下方的 port 配置。下面以我的三台 服务器为例。
修改 conf 目录下的 server.xml 文件下 的 port 配置。
tomcat-aaa的 配置
<Server port="8005" shutdown="SHUTDOWN">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="UTF-8"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
tomcat-bbb的 配置
<Server port="8006" shutdown="SHUTDOWN">
<Connector port="8088" protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="UTF-8"
redirectPort="8443" />
<Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />
tomcat-ccc的 配置
<Server port="8007" shutdown="SHUTDOWN">
<Connector port="8089" protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="UTF-8"
redirectPort="8443" />
<Connector port="8011" protocol="AJP/1.3" redirectPort="8443" />
同一台机器同时启动这三台tomcat就不会产生端口冲突问题。
这里添加了 URIEncoding="UTF-8" 的配置,解决中文乱码问题。
为了区分nginx分发请求到不同的服务器,这里修改一下 webapps\ROOT 目录下的 index.jsp 页面。
<div id="asf-box">
<h1>${pageContext.servletContext.serverInfo}-aaa</h1>
</div>
主要在 ${pageContext.servletContext.serverInfo} 添加了 -aaa, 同理,tomcat-bbb,添加-bbb tomcat-ccc,添加-ccc,三台服务器,分别对应修改区别。
三、验证是否配置成功
分别启动三台tomcat。启动nginx服务器。访问localhost:80 端口。
每次请求,如果 Apache Tomcat/7.0.81-xxx ,是不同的,则证明nginx把请求分发到了不同的服务器上了。
四、解决session共享
1.简述为什么产生session共享问题
上面讲述了,nginx把用户的请求分发到了不同的服务器上,但是对于请求量比较大的应用,往往要部署几十台的tomcat服务器来处理高并发的请求。对于单台的tomcat应用来说,用户请求到了应用,服务器直接存储了用户信息,不管访问几次,始终都是这一台服务器,用户的信息不会丢失。对于分布式应用来说,用户的请求是随机分发到不同的tomcat服务器上的,假设你成功登陆到了一台服务器上,只有该服务器存储了你的信息,如果再次请求,通过nginx可能分配到另一台服务器上,在这台服务器上你并没有登陆过,所以就会提示你去登陆。如果每次请求恰巧都分配到没有登陆过的服务器上,那么用户就要连续登陆数次,这简直就是灾难。所以产生了分布式session问题,sesssion就是存储用户信息的回话机制。
2.如何解决
网上有多种解决方案,这里就不再造轮子了。这里主要简述利用 redis 来解决分布式 Session 问题。
以我的理解来说,用户成功登陆后之后,把用户的 sessionid 作为 redis 的key, session信息作为 value ,存储进 redis内存数据库。当用户请求时,拿到用户的sesssionid 去redis 数据库查找,如果有就直接拿到 session信息。如果没有,就存储用户的sessionid 和session信息到内存数据库。在一次会话中同一用户的sessionid不会改变,所以一旦存进redis数据库session信息,就可以session信息共享。另一个用户登陆,会产生新的sessionid,所以不同用户的session是不同的。也就是redis存储的session信息不会混乱。
3.配置实现session共享
- 首先把我上面说的几个jar包放到 每台tomcat lib 文件夹下。
- 添加配置
在每一个 tomcat 的 conf 文件夹下的 context.xml 中 在<Context> </Context>标签内 添加如下配置
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="127.0.0.1"
port="6379"
database="0"
maxInactiveInterval="60" />
host: 为redis 服务器所在的主机 ip 地址
port: 为 redis 服务器的 端口
database: 为redis 默认的 0 号库
- 添加访问应用
在每一个tomcat 的 webapps 目录下 新建一个session 的文件夹,文件夹内 放一个index.jsp文件,index.jsp文件编码为utf-8
把一下内容放在 index.jsp内
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>tomcatAAA</title>
</head>
<body>
<%
HttpSession mySession = request.getSession(false);
if (mySession.getAttribute("username") == null) {
mySession = request.getSession(true);
mySession.setAttribute("username", session.getId() + "用户的session");
out.println("new session:" + mySession.getAttribute("username"));
} else {
out.println("old session:" + mySession.getAttribute("username"));
}
%>
<br>
<br>sessionID:<%=session.getId() %></br>
<br> tomcatAAA
</body>
</html>
根据不同的tomcat ,更改 <title>tomcat XXX</title> 和 <br> tomcatXXX 这两块内容,用于区分访问到了不同的tomcat服务器。
- 更改tomcat默认访问主页
我们访问tomcat服务器 ,默认会访问到 webapps/root目录下的index.jsp 页面。为了能够体现是同一个session,所以有了上一个添加访问应用的步骤。接下来,在tomcat conf 目录的 server.xml 中 <Host> </Host> 标签内 添加 一下代码,就可以实现更改tomcat默认主页到自己指定的页面了。每一个部署的tomcat 都需更改!
<Context docBase="G:\apache-tomcat-7.0.81-aaa\webapps\session" path="" debug="0" reloadable="true"/>
docBase : 为自己新建的应用路径地址,以在自己电脑部署的路径为准,这里贴出来的是我的配置。
注意:每一个tomcat的 文件夹名称 --aaa --bbb --ccc 一定要更改。否则一直不会 看到访问页面的变化。更改完要重启tomcat.
然后就可以验证session是否共享。需要启动以下服务来验证。
- 启动redis 服务器。
- 启动tomcat 服务器。
- 启动nginx 服务器。
访问localhost:80 端口,即可。
请求转发到部署的三台中某一台tomcat服务器,然后根据 nginx 的server 配置,例如:访问到了 server 127.0.0.1:8088 台服务器,前面替换了默认的首页,所以就直接访问到了自定义的jsp页面。
以下是我的访问页面,证明了session的共享。每一次刷新都会访问一次,根据nginx权重会分配到不同的服务器中。
redis 服务器中 查看存储的session 信息。
双击 redis 安装目录的 redis-cli.exe 文件。
redis命令
- kes * 查看所有key
- get key 获取指定key 的值
五、多台服务器实现共享session
上面在自己的电脑上实现了session的共享。能不能模仿一下实际的环境,于是乎开始了两台电脑之间的session共享。
前提条件:
两台电脑都是在同一个局域网下,才能保证能够把请求分发到另一台电脑的服务器上。
准备工作:
把我自己配置好的的三台tomcat服务器copy到另一台电脑上。在另一台电脑修改以下几个地方。
tomcat conf 目录下的 context.xml 配置文件,三个tomcat都要更改
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="redis 服务器所在电脑的 IP 地址"
port="6379"
database="0"
maxInactiveInterval="60" />
更改host 地址,我的局域网 ip 为 192.168.1.106 ,并且redis服务器在我电脑开启。 所以改为 host="192.168.1.106"
tomcat conf 目录下的 server.xml 配置文件,三个tomcat都要更改
<Context docBase="G:\apache-tomcat-7.0.81-xxx\webapps\session" path="" debug="0" reloadable="true"/>
这里的更改主要是因为 不同电脑的路径不同,所以要更改路径。切记 --xxx 要对应更改。
tomcat webapps/root/session 目录下的index.jsp 文件,三个tomcat都要更改
<br>
<br>sessionID:<%=session.getId() %></br>
<br> tomcatAAA 来自另一台电脑的服务器
这块主要是 为了区分到底是访问了那台电脑上的服务器。三台对应添加上区别的文字即可。
nginx conf目录的 nginx.conf 配置文件
这块开始为另外的三台服务器配置,另一台电脑的IP为 192.168.1.105,所以配置如下。
upstream myTomcatServers{
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8088 weight=1;
server 127.0.0.1:8089 weight=1;
#另一台电脑的服务器
server 192.168.1.105:8080 weight=5;
server 192.168.1.105:8088 weight=5;
server 192.168.1.105:8089 weight=5;
}
测试
到这里就配置完了,访问localhost:80 即可。或者 自己电脑的ip地址:80.
在别人电脑上访问 nginx服务器部署电脑的ip:80 就可以了。
请求成功一次,刷新一次,就会发现你请求到不同的电脑上了。
到此,多台电脑部署服务器session共享问题就结束了。
六、思考
- nginx 转发到的 tomcat服务器 挂了怎么处理?
- redis 挂了怎么处理?
- nginx 挂了怎么处理?