spring-session-data-redis 解决集群环境下session共享

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

解决方案

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

浏览器输入:http://127.0.0.1/setsession?key=name&value=zhangsan 分发至8080的tomcat中创建session
在这里插入图片描述
浏览器输入:http://127.0.0.1/getsession?key=name 分发至8081的tomcat取到了session
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_34929019/article/details/86368912
今日推荐