文档章节

nginx 解决session一致性

zhu_kai1
 zhu_kai1
发布于 11/21 22:39
字数 792
阅读 16
收藏 10
  1. session 粘滞性
  • 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 
  • upstream backserver {
    ip_hash;
    server 192.168.0.14:88;
    server 192.168.0.15:80;
    }
  • 但是有缺点,这存在单点风险,倘若我已经在192.168.0.14:88端口登录后,过段时间发现14服务器挂了(session时间未过期),那么这时候会访问到15服务器,那这时候需要重新登录,因为在拿14服务器上的JsessionId去15服务器请求发现不存在。

2、session 复制

  • 可以通过tomcat的server.xml文件进行配置,这样每个tomcat都会同步对应的session,那么此时即使某个tomcat被宕机了,也不影响服务。
  • 具体的tomcat可以参见如下 ,tomcat 官网对应的tomcat集群配置
  • <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                     channelSendOptions="8">
    
              <Manager className="org.apache.catalina.ha.session.DeltaManager"
                       expireSessionsOnShutdown="false"
                       notifyListenersOnReplication="true"/>
    
              <Channel className="org.apache.catalina.tribes.group.GroupChannel">
                <Membership className="org.apache.catalina.tribes.membership.McastService"
                            address="228.0.0.4"
                            port="45564"
                            frequency="500"
                            dropTime="3000"/>
                <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                          address="auto"
                          port="4000"
                          autoBind="100"
                          selectorTimeout="5000"
                          maxThreads="6"/>
    
                <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
                  <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
                </Sender>
                <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
                <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
              </Channel>
    
              <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                     filter=""/>
              <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
    
              <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                        tempDir="/tmp/war-temp/"
                        deployDir="/tmp/war-deploy/"
                        watchDir="/tmp/war-listen/"
                        watchEnabled="false"/>
    
              <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
            </Cluster>

3、session 共享(springboot)

  •   对应的项目中pom文件添加
  • <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-redis</artifactId>  
    </dependency>  
    <dependency>  
            <groupId>org.springframework.session</groupId>  
            <artifactId>spring-session-data-redis</artifactId>  
    </dependency>  
  • 在对应的application.properties中配置redis信息
  • spring.redis.host=localhost  
    spring.redis.port=6379  
  • 添加开启spring session支持的注解@EnableRedisHttpSession
  • @Configuration  
    @EnableRedisHttpSession  
    public class RedisSessionConfig {  
    } 
  • 添加验证的接口
  • @Value("${server.port}")
        String port;
    
        @GetMapping("/session")
        public Object getSession(HttpServletRequest request){
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("SessionId", request.getSession().getId());
            map.put("ServerPort", "服务端口号为 "+port);
            return map;
        }
    
  • 访问 http://localhost:8080/session
  • 我们看下redis缓存的数据
  • 可以发现sessionId已经缓存在redis数据库中
  • 下面我们换个端口再访问一次看看
  • 这次我把端口换成了8888 访问:http://localhost:8888/session
  • 刷新了redis数据库,缓存的数据也没变
  • 结果中的SessionId是一致的,却是由两个不同项目工程来提供服务。这样子,SpringSession 利用拦截器 Filter 帮我们在每个请求前进行了同步设置,达到了分布式系统中 session 共享。

4、session 共享(springmvc 版本)

首先在pom.xml文件中添加对应的jar

 <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>

在对应springmvc-context.xml文件中配置

<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" />
        <property name="testOnBorrow" value="true" />
    </bean>

    <bean id="connectionFactory"  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
        <property name="poolConfig" ref="jedisPoolConfig" />
        <property name="port" value="6379" />
        <property name="hostName" value="192.168.1.11" />
        <property name="password" value="xxx" />
        <property name="timeout" value="30000" ></property>
    </bean >

    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="keySerializer">
            <bean  class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
    </bean >

    <bean id="redisUtil" class="com.isea533.mybatis.service.RedisUtil" >
        <property name="redisTemplate" ref="redisTemplate" />
    </bean >

其次在web.xml中配置(非常重要,filter的名字必须是springSessionRepositoryFilter)

  <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>

访问项目路径呈现结果

© 著作权归作者所有

共有 人打赏支持
zhu_kai1
粉丝 5
博文 27
码字总数 21385
作品 0
私信 提问
分布式Session一致性解决方案

1、session的作用? 服务器为每个用户创建一个会话,存储用户的相关信息,以便多次请求能够定位到同一个上下文。当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢...

凌晨一点
08/14
0
0
[Nginx][笔记]Keepalived\LVS\Nginx\tomcat 经典基本架构演变过程

KeepalivedLVSNginxtomcat 经典架构演变过程-需要一定基础 Nginx 背景问题: 如上图所示,正常情况下,我们直接访问tomcat一台服务器,但是并发量增多的情况下,需要设置多台tomcat来分流 解...

zemel
2016/09/04
300
0
Nginx--Session共享问题

在Nginx做反向代理时,面对集群,如何保证Session的一致性。 第一种是以负载均衡服务器本身提供的session共享策略,每种服务期的配置是不一样的并且nginx本身是没有的。 第二种是利用web容器...

btwangzhi
2017/11/26
0
0
分布式Session共享的4类技术方案,与优劣势比较

Session概念集合 服务器为每个用户创建一个会话,存储用户的相关信息,以便多次请求能够定位到同一个上下文。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会...

游人未归
09/19
0
0
Nginx+Tomcat负载平衡,Redis管理session存储

开篇 使用Nginx作为Tomcat的负载平衡器,Tomcat的会话Session数据存储在Redis,能够实现0当机的7x24运营效果。因为将会话存储在Redis中,因此Nginx就不必配置成stick粘粘某个Tomcat方式,这样...

hanfeng
2015/11/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

rabbitmq学习

使用docker安装rabbit docker run -d --hostname my-rabbit --name rabbit -p 8080:15672 rabbitmq:management--hostname:指定容器主机名称--name:指定容器名称-p:将mq端口号映射到本地...

元谷
20分钟前
0
0
想知道谁是你的最佳用户?基于Redis实现排行榜周期榜与最近N期榜

本文由云+社区发表 前言 业务已基于Redis实现了一个高可用的排行榜服务,长期以来相安无事。有一天,产品说:我要一个按周排名的排行榜,以反映本周内用户的活跃情况。于是周榜(按周重置更新...

腾讯云加社区
22分钟前
1
0
函数计算性能福利篇(二) —— 业务冷启动优化

继前一篇《函数计算性能福利篇——系统冷启动优化》,我们再来看看近期函数计算推出的 Initializer 功能之后,带来的一波高能性能优化成果。 背景 函数计算是一个事件驱动的全托管 serverle...

阿里云官方博客
27分钟前
1
0
开源版本说明

1527
29分钟前
2
0
Mysql经验-------持续更新

单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。 说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。

DoLo-lty
31分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部