springboot+spring-session
1. 实现背景
测试环境上部署了一个单机项目,项目的context-path为空,之后再经过nginx的转发进行部署,项目可以正常进行登录等等一系列操作;生产环境跟测试环境代码完全相同,只是相关的项目配置包括nginx配置不同,项目可以正常启动,但登录失败。原本以为是nginx相关的配置有问题,导致调完登录接口,返回的cookie中携带的项目名不一致导致的。经过检查发现登录接口返回的cookie中跟后续请求的cookie中的参数一致,所以跟配置无关。最后发现生产配置的项目是集群模式,所以根本还是出现在session共享上面。
2.具体实现
这里做的共享session用的是redis,所以要安装redis并引入相关依赖;
<!--session--> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <!-- redis依赖配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
其次application.yml中添加相关配置
spring: session: store-type: redis #是否将session存到redis none/redis timeout: 1800 # 配置session在redis中的过期时间 redis: flush-mode: immediate #保存时刷新,即响应结束后刷新。默认是 on_save;immediate实时刷新 namespace: smith:session #默认是spring:session redis: host: 127.0.0.1 # Redis服务器地址 database: 0 # Redis数据库索引(默认为0) port: 6379 # Redis服务器连接端口 password: # Redis服务器连接密码(默认为空) timeout: 3000ms # 连接超时时间
到这里配置工作就完成了,启动项目即可。
3. 错误信息
org.springframework.boot.autoconfigure.session.SessionRepositoryUnavailableException: No session repository could be auto-configured, check your configuration (session store type is 'redis')
因为当store-type配置为redis的时候,redis是需要序列化的,所以我们还需要对restTemplate进行序列化,至此问题解决,项目可成功启动。
@Configuration public class RedisConfiguration { /** * @param redisConnectionFactory:配置不同的客户端,这里注入的redis连接工厂不同: JedisConnectionFactory、LettuceConnectionFactory * @功能描述 :配置Redis序列化,原因如下: * (1) StringRedisTemplate的序列化方式为字符串序列化, * RedisTemplate的序列化方式默为jdk序列化(实现Serializable接口) * (2) RedisTemplate的jdk序列化方式在Redis的客户端中为乱码,不方便查看, * 因此一般修改RedisTemplate的序列化为方式为JSON方式【建议使用GenericJackson2JsonRedisSerializer】 */ @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); // key采用String的序列化方式 redisTemplate.setKeySerializer(StringRedisSerializer.UTF_8); // value序列化方式采用jackson redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // hash的key也采用String的序列化方式 redisTemplate.setHashKeySerializer(StringRedisSerializer.UTF_8); //hash的value序列化方式采用jackson redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setConnectionFactory(redisConnectionFactory); return redisTemplate; } }
4. 总结
当集群模式时候,需要将登录相关信息储存在redis或其他数据库中实现共享,也就是说sessionid保存在客户端的cookie里面,然后将该sessionid作为key将session保存在redis服务端。当部署很多个项目时候,因为session-namespace是默认值,所以可以修改namespace的值,把不同项目区分开。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律