环境:Cent OS 7.0(虚拟机环境)、Nginx 1.9.八、Redis 3.2.1html
在使用Nginx+Tomcat实现负载均衡的时候,因为Nginx对不一样的请求分发到某一个Tomcat,Tomcat在运行的时候分别是不一样的容器里,由于会出现session不一样步或者丢失的问题。nginx
一、Nginx安装git
网上的资源对于安装Nginx的介绍比较多,例如最简单的为:github
(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配置多Tomcat服务器web
2.一、修改conf/nginx.conf文件,在server标签上边添加upstream以下:redis
upstream mynginxserver { #weigth参数表示权值,权值越高被分配到的概率越大 #本机上的Squid开启3128端口 server 127.0.0.1:8080 weight=1; server 127.0.0.1:8060 weight=1; }
2.二、配置server标签;apache
server { listen 80; server_name 192.168.1.149; #charset koi8-r; #access_log logs/host.access.log main; location / { # root html; # index index.html index.htm; proxy_pass http://mynginxserver; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; }
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream mynginxserver { server 127.0.0.1:8080 weight=1; server 127.0.0.1:8060 weight=1; } server { listen 80; server_name 192.168.1.149; location / { proxy_pass http://mynginxserver; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
https://www.nginx.com/resources/wiki/start/topics/examples/full/tomcat
一、解压apache-tomcat-7.0.67.zip 获得apache-tomcat-7.0.67服务器
[root@localhost www]# unzip apache-tomcat-7.0.67.zip
[root@localhost www]# mv apache-tomcat-7.0.67 tomcat1
三、修改Tomcat1的端口为8080和部署项目文件session
编辑tomcat下的conf/server.xml,修改端口号为8080,
本身写的用于测试Nginx反向代理的web项目war包下载地址:http://download.csdn.net/detail/u010870518/9585683
下载好以后将解压以后的编译好的项目文件放到tomcat1/webapps/ROOT/目录下:
修改index.jsp和login.jsp文件分别标识为具体的Tomcat容器
四、修改Tomcat2的端口为8060和部署项目文件
编辑tomcat下的conf/server.xml,修改端口号为8060,而后和上述3中的同样,下载war内容,放在tomcat2/webapps/ROOT/下,修改index.jsp和login.jsp用于标识具体的Tomcat容器
五、分别启动tomcat1和tomcat2
六、重启Nginx服务,访问IP地址:192.168.1.149:80(这个是访问的虚拟机IP地址)
七、观看效果
能够看出,Nginx已经进行了请求分发,转发到具体的某一个Tomcat
因为篇幅过长,请参考本人写的:http://blog.csdn.net/xlgen157387/article/details/52022793
一、开源项目地址:https://github.com/jcoleman/tomcat-redis-session-manager
二、下载代码以后须要进行从新编译,生成所须要的jar,任意建立maven项目,将src下的代码拷贝到具体位置,以下:
maven的pom.xml文件以下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ufind.session</groupId> <artifactId>tomcat-redis-session</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina</artifactId> <version>7.0.27</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.7.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.0</version> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> </project>
四、将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
五、修改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>
<?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" password="redispassword" maxInactiveInterval="60" /> </Context>
案例演示的一个登录请求,登录成功以后将用户信息放在session中,在界面中显示出来(tomcat1实例,tomcat2的实例中只是在 h2 标签中作了一下标识)
一、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>
<body> <h2>Session Demo in Tomcat1</h2> <% User user = (User) request.getSession().getAttribute("USER"); if (user == null) { %> 用户为空,没有登陆!!! <% } else { %> 欢迎: <%=user.getUserName()%> <% } %> </body>
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"; } }
能够看出在登陆界面的时候刷新请求的tomcat已经由Nginx进行分发请求,登陆以后再两个tomcta中已经共享了session
五、查看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数据存储的操做