zoukankan      html  css  js  c++  java
  • 分布式Session管理

    https://www.cnblogs.com/goodAndyxublog/p/13327412.html

    一个用户的 Session 信息如果存储在一个服务器上,那么当负载均衡器把用户的下一个请求转发到另一个服务器,由于服务器没有用户的 Session 信息,那么该用户就需要重新进行登录等操作。

    一、粘滞会话 Sticky Sessions

      需要配置负载均衡器,使得一个用户的所有请求都路由到同一个服务器,这样就可以把用户的 Session 存放在该服务器中。缺点:当服务器宕机时,将丢失该服务器上的所有Session。

    二、复制会话 Session Replication

      在服务器之间进行 Session 同步操作,每个服务器都有所有用户的 Session 信息,因此用户可以向任何一个服务器进行请求。缺点:占用过多内存;同步过程占用网络带宽以及服务器处理器时间。

    三、Session Server

      使用一个单独的服务器存储 Session 数据,可以使用传统的 MySQL,也使用 Redis 或者 Memcached 这种内存型数据库。

      优点:为了使得大型网站具有伸缩性,集群中的应用服务器通常需要保持无状态,那么应用服务器不能存储用户的会话信息。Session Server 将用户的会话信息单独进行存储,从而保证了应用服务器的无状态。

      缺点:需要去实现存取 Session 的代码。

     例如 tomcat + redis(依赖web服务器,如果更换服务器的话还要重新配置)

      基于 tomcat 原生的 session 支持即可,然后就是用一个叫做 Tomcat RedisSessionManager 的东西,让所有我们部署得 tomcat 都将 session 数据存储到 redis 即可。
      在 tomcat 的配置文件中配置:
    <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
    
    <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
             host="{redis.host}"
             port="{redis.port}"
             database="{redis.dbnum}"
             maxInactiveInterval="60"/>

     更好的方法:Spring session + redis

    ① pom.xml 添加依赖

    <dependency>
      <groupId>org.springframework.session</groupId>
      <artifactId>spring-session-data-redis</artifactId>
      <version>1.2.1.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.8.1</version>
    </dependency>

    ② spring配置文件中配置

    <bean id="redisHttpSessionConfiguration"
         class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <property name="maxInactiveIntervalInSeconds" value="600"/>
    </bean>
    
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="100" />
        <property name="maxIdle" value="10" />
    </bean>
    
    <bean id="jedisConnectionFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
        <property name="hostName" value="${redis_hostname}"/>
        <property name="port" value="${redis_port}"/>
        <property name="password" value="${redis_pwd}" />
        <property name="timeout" value="3000"/>
        <property name="usePool" value="true"/>
        <property name="poolConfig" ref="jedisPoolConfig"/>
    </bean>

     ③ web.xml配置过滤器

    <filter>
        <filter-name>springSessionRepositoryFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSessionRepositoryFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

     ④ TestController

    @Controller
    @RequestMapping("/test")
    public class TestController {
    
        @RequestMapping("/putIntoSession")
        @ResponseBody
        public String putIntoSession(HttpServletRequest request, String username) {
            request.getSession().setAttribute("name",  “leo”);
    
            return "ok";
        }
    
        @RequestMapping("/getFromSession")
        @ResponseBody
        public String getFromSession(HttpServletRequest request, Model model){
            String name = request.getSession().getAttribute("name");
            return name;
        }
    }

      上面的代码就是 ok 的,给 sping session 配置基于 redis 来存储 session 数据,然后配置了一个 spring session 的过滤器,这样的话,session 相关操作都会交给 spring session 来管了。接着在代码中,就用原生的 session 操作,就是直接基于 spring sesion 从 redis 中获取数据了。

      实现分布式的会话,有很多种很多种方式,我说的只不过比较常见的两种方式,tomcat + redis 早期比较常用,但是会重耦合到 tomcat 中;近些年,通过 spring session 来实现。

  • 相关阅读:
    sqlServer的主键只能自增不能手动增加
    TP函数
    TP复习17
    TP复习16
    TP复习15
    TP复习14
    TP复习13
    TP复习12
    TP复习11
    TP复习10
  • 原文地址:https://www.cnblogs.com/qmillet/p/12487408.html
Copyright © 2011-2022 走看看