话不多说直接上代码和配置
在springcloud微服务项目中,使用redis实现session共享是比较主流的,简单高效,直接代码实践:
1、在pom.xml中添加相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2、添加redis配置
service-user-session-redis-dev.yml
server:
port: 8831
management:
endpoints:
web:
exposure:
include: "*"
cors:
allowed-origins: "*"
allowed-methods: "*"
spring:
redis:
database: 0
host: 192.168.248.131
port: 6379
password:
timeout: 20000
#cluster:
#nodes: 192.168.211.134:7000,192.168.211.134:7001
#-
#max-redirects:
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
3、添加redis配置类启用redis代码spring默认session
RedisSessionConfig
package com.mayi.springcloud.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
@Configuration
@EnableRedisHttpSession
public class RedisSessionConfig {
}
4、UserManagementController中添加测试方法
package com.mayi.springcloud.controller;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RefreshScope
public class UserManagementController {
/**
* redis sesion共享
* @param request
* @return
*/
@GetMapping("/getUser")
public String getUser(HttpServletRequest request){
HttpSession session = request.getSession();
String username = (String)session.getAttribute("username");
if(StringUtils.isEmpty(username)){
session.setAttribute("username", "testSessionRedis|" + System.currentTimeMillis());
}
return username;
}
}
5、修改网关配置
springcloud项目中经过网关zuul转发请求后发生session失效问题,这是由于zuul默认会丢弃原来的session并生成新的session,解决方法网关配置文件
service-zuul-dev.yml 中添加 sensitiveHeaders: "*"
server:
port: 1100
zuul:
ignoredServices: '*' #忽略所有未配置的service
host:
connect-timeout-millis: 20000
socket-timeout-millis: 20000
routes:
user-service: #自定义名称
path: /user/**
serviceId: service-user #/user/开头的路径转发至service-user微服务
sensitiveHeaders: "*"
user-redis-session-service:
path: /user-session/**
serviceId: service-user-session-redis
sensitiveHeaders: "*"
hystrix: #hystrix配置
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 2500
ribbon: #ribbon负载均衡参数配置
ReadTimeout: 5000
ConnectTimeout: 5000
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
6、测试
依次启动EUREKA、SERVICE-CONFIG、SERVICE-USER-SESSION-REDIS、SERVICE-ZUUL
多次访问网关地址http://localhost:1100/user-session/getUser
1、发现redis中已经有了session的信息
2、session中的信息为redis中获取的,并且是同一个session
总结:springcloud整合redis实现session共享容易发生错误的地方就是经过网关转发会使原session失效,多数人会认为是整合没有成功,仔细看zuul的源码或者直接访问微服务去尝试,不难发现问题的所在。