zoukankan      html  css  js  c++  java
  • 【SpringBoot】spring-session-data-redis 解决集群环境下session共享

    为什么会产生Session共享问题

      集群情况下,session保存在各自的服务器的tomcat中,当分发地址至不同服务时,导致sesson取不到,就会产生session共享问题。

    解决方案

    • 负载均衡中,IP绑定策略。如nginx:ip_hash
    • tomcat的session共享
      •   优点:不需要额外开发,只需搭建tomcat集群即可
      •   缺点:tomcat 是全局session复制,集群内每个tomcat的session完全同步(也就是任何时候都完全一样的) 在大规模应用的时候,用户过多,集群内tomcat数量过多,session的全局复制会导致集群性能下降, 因此,tomcat的数量不能太多,5个以下为好。
    • cookie同步session:第一次请求将session存在服务器,并且存入cookie,再次请求,如果在服务器没取到session,则从cookie中取。
      •   优点:减轻服务器端的压力
      •   缺点:受到cookie的大小限制,可能占用一定带宽,因为每次请求会在头部附带一定大小的cookie信息,另外这种方式在用户禁止使用cookie的情况下无效,并且不安全
    • 数据库同步session,访问压力大
    • redis集中管理session
      •   优点:redis为内存数据库,读写效率高,并可在集群环境下做高可用

    spring-session + redis解决session共享问题

      1.maven依赖引入

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--spring boot 与redis应用基本环境配置 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!--spring session 与redis应用基本环境配置 -->
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
    </dependency>
    1. 创建SessionConfig类
    import org.springframework.context.annotation.Configuration;
    import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
    
    @Configuration
    //设置session的默认在redis中的存活时间
    @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60 * 60 * 8)
    public class SessionConfig {
    }
    1. 创建SessionInitializer类,初始化session配置
    import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
    import com.lb.config.SessionConfig;
    //初始化Session配置
    public class SessionInitializer extends AbstractHttpSessionApplicationInitializer {
        public SessionInitializer() {
            super(SessionConfig.class);
        }
    }
    1. application.yml
    server:
      port: 8081
    spring:
      redis:
        database: '0'
        host: 127.0.0.1
        password: 123456
        pool:
          max-active: 8
          max-idle: 5
          max-wait: 5000
          min-idle: 1
        port: 6379
        timeout: 0
      session:
        store-type: redis   #设置session保存为默认redis的方式
    1. controller实现
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @SpringBootApplication
    public class SessionController {
        @Value("${server.port}")
        private String port;
    
        @RequestMapping("/setsession")
        public String setSeesion(HttpServletRequest request, String key, String value) {
            HttpSession session = request.getSession();
            session.setAttribute(key, value);
            return "server port :" + port + "---- value :" + value;
        }
    
        @RequestMapping("/getsession")
        public String getSeesion(HttpServletRequest request, String key) {
            HttpSession session = request.getSession();
            String value = (String) session.getAttribute(key);
            return "server port :" + port + "---- value :" + value;
        }
    
        public static void main(String[] args) {
            SpringApplication.run(SessionController.class, args);
        }
    }

    测试用nginx做分发

        #负载均衡分发
        upstream sessionserver {
            server 127.0.0.1:8080;
            server 127.0.0.1:8081;
        }
    
        server {
            listen       80;
            server_name  localhost;
    
            #charset koi8-r;
    
            #access_log  logs/host.access.log  main;
    
            location / {
                proxy_pass   http://sessionserver;
                index  index.html index.htm;
            }
        }
  • 相关阅读:
    c# 使用MySql的MySqlBulkCopy 出现异常 Loading local data is disabled; this must be enabled on both the client and server sides
    DB2 使用EF Core 查询数据 报错 Object reference not set to an instance of an object.
    关于iis部署的网站访问类型设置
    ABP put与delete类型请求异常 TypeErorr: Failed to fetch
    This request has been blocked; the content must be served over HTTPS.
    Mysql Select的字段必须包含在Group By中如何解决
    企业微信小程序-临时登录凭证校验(code2Session)中获取的userid是加密的
    ABP System.ObjectDisposedException: Cannot access a disposed object.
    SQL server数据库文件(mdfldf)的迁移
    A second operation started on this context before a previous operation completed--ABP
  • 原文地址:https://www.cnblogs.com/aaron911/p/11282242.html
Copyright © 2011-2022 走看看