session 是服务器用来保存用户操作的一系列会话信息,由 Web 容器进行管理。单机情况下,不存在 session 共享的情况,分布式情况下,如果不进行 session 共享会出现请求落到不同机器要重复登录的情况 。单点登录可以用 cookie+redis 的方式,第一次登陆生成 token,将 token 和用户以键值对的方式存入 redis。并将 token 写入cookie 返回到浏览器。以后每次请求 cookie 都会携带上 token。服务端获取 token 然后去 redis 中查找是否存在此用户从而实现单点登录。
项目代码结构图结构
准备工作
启动 eureka 注册中心 eureka-register,然后新建两个 springboot 服务分别是 four-sample 和 five-sample。
以 four-sample 演示操作
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--spring boot 与redis应用基本环境配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring session 与redis应用基本环境配置,需要开启redis后才可以使用,不然启动Spring boot会 报错 -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
属性配置
在 application.yml 资源文件中添加 redis 和 eureka 相关配置
server:
port: 8086
spring:
application:
name: spring-cloud-producer1
redis:
host: 127.0.0.1
port: 6379
timeout: 5000ms
password:
database: 0
jedis:
pool:
max-active: 50
max-wait: 3000ms
max-idle: 20
min-idle: 2
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
主程序
package com.tuhu.foursample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* @author chendesheng
* @since 2019-08-06
*/
@SpringBootApplication
@EnableEurekaClient
@EnableRedisHttpSession
@RestController
public class FourSampleApplication {
public static void main(String[] args) {
SpringApplication.run(FourSampleApplication.class, args);
}
@GetMapping(value="/setSession")
public String setSession(HttpServletRequest request){
Map<String,Object> map = new HashMap(10);
map.put("name","超级管理员");
map.put("account","admin");
request.getSession().setAttribute("userSession",map);
String sessionId = request.getSession().getId();
return sessionId;
}
}
使用 @EnableRedisHttpSession
来开启 spring session 支持,使用 @EnableEurekaClient
将服务注册到注册中兴。five-sample 服务的配置如法炮制,只需修改端口号和程序名即可。
five-sample 服务配置完以后,我们需要在主程序拿到 userSession
,看看 session 是否与服务 four-sample 里的一致。five-sample 主程序代码如下:
package com.tuhu.fivesample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* @author chendesheng
* @since 2019-08-06
*/
@SpringBootApplication
@EnableEurekaClient
@RestController
@EnableRedisHttpSession
public class FiveSampleApplication {
public static void main(String[] args) {
SpringApplication.run(FiveSampleApplication.class, args);
}
@GetMapping(value="/getSession")
public Map<String,Object> getSession(HttpServletRequest request){
String sessionId = request.getSession().getId();
Object obj = request.getSession().getAttribute("userSession");
Map<String,Object> map = new HashMap(10);
map.put("sessionId",sessionId);
map.put("user",obj);
return map;
}
}
测试
现在我们启动注册中心 eureka-register 和两个服务 four-sample 和 five-sample
用 postman 请求 four-sample,我们可以看到
再用 postman 请求 five-sample,我们可以看到
ok 这样我们就实现了 session 共享,可以看到 SpringBoot 集成 redis 实现 session 共享是如此的简单,仅仅需要一个依赖就可以解决。我们写了一些代码,也做了一些配置,但是全都和 Spring Session 无关,配置是配置 Redis,代码就是普通的 HttpSession,和 Spring Session 没有任何关系!唯一和 Spring Session 相关的,可能就是我在一开始引入了 Spring Session 的依赖吧!