负载均衡时使用Spring Session和SpringData来实现多台tomcat服务器的session同步

来源:互联网 发布:tomcat和apache整合 编辑:程序博客网 时间:2024/05/22 12:17

在使用负载均衡的时候,前端使用nginx来平衡负载。
决定http请求到底由哪个tomcat服务器来响应和处理。
但是这样就会产生一个问题。如果用户在登录的状态下,登录的信息保存在tomcat 的httpSession中。
那么如果两次请求分别被两台tomcat处理。
那么另外一台tomcat上的内存中很可能没有session,更有可能有session,但是与之前的tomcat的内存中的session内容不一致。
所以这里我们将吧Session统一放到redis中。
而不是单个放在tomcat内存中。

笔者在之前浏览spring.io时,无意发现了Spring Session这个项目,该项目正好解决了该方面的问题。
于是,笔者将spring.io官网的demo下载了下来,并运行。
先将完整的demo地址贴出来吧

http://download.csdn.net/detail/u013803262/9822940

这里笔者redis是在Windows下使用的。
主机是:localhost
端口是:6379

而且这里需要说的一点就是Spring Session 是无需依赖于springframework的可以单独使用的。
我们先将demo的依赖加入进来吧

<dependency>      <groupId>org.springframework.session</groupId>      <artifactId>spring-session-data-redis</artifactId>      <version>1.3.0.RELEASE</version>      <type>pom</type>    </dependency>    <dependency>      <groupId>biz.paluch.redis</groupId>      <artifactId>lettuce</artifactId>      <version>3.5.0.Final</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-web</artifactId>      <version>4.3.4.RELEASE</version>    </dependency>    <dependency>      <groupId>javax.servlet</groupId>      <artifactId>javax.servlet-api</artifactId>      <version>3.1.0</version>    </dependency>

只需要写三个Java文件即可
config.java

import org.springframework.context.annotation.Bean;import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;@EnableRedisHttpSessionpublic class Config {    @Bean    public LettuceConnectionFactory connectionFactory() {        return new LettuceConnectionFactory();    }}

Initializer.java

import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;public class Initializer extends AbstractHttpSessionApplicationInitializer {    public Initializer() {        super(Config.class);    }}

SessionServlet.java

import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebServlet("/session")public class SessionServlet extends HttpServlet {    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp)            throws ServletException, IOException {        /**         * 将tomcat关闭掉一次后,再重新启动下,看能否拿到数据,如果能,就说明将Session存入redis中成功,         * 如果没有则说明还没有成功         */        System.out.println("redis中的信息是: " + req.getSession().getAttribute("hello"));        String attributeName = req.getParameter("p");        String attributeValue = req.getParameter("v");        System.out.println(attributeName);        System.out.println(attributeValue);        req.getSession().setAttribute(attributeName, attributeValue);//      resp.sendRedirect(req.getContextPath() + "/");        req.getRequestDispatcher("/").forward(req, resp);    }    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        this.doPost(req, resp);    }    private static final long serialVersionUID = 2878267318695777395L;}

代码写完了,但是如何验证我们的session存入到redis中去了呢??
我们可以事先调用

session.setAttribute("hello","thisIsTheSessionValueInRedis");

再将我们的tomcat关闭掉,在直接get

session.getAttribute("hello");

如果有的话,说明将session托管给redis成功,否则就是失败。

0 0