springboot项目Nginx+Tomcat实现负载均衡结合Redis实现session共享问题
对于分布式使用Nginx+Tomcat实现负载均衡,当同一个用户登入后,再次访问可能分发到不同的服务,这样我们就取不到之前登入session,出现未登入现象。所以我们必须解决共享session问题。
方式一:存储在数据库中 , 用户登入时,把session信息储存在数据库中,然后再需要获取session的地方进行读取。
方式二 :cookie 共享session ;当用户登入时,把 cookie储存在客户端,当用户需要session判断是否登入时,首先判断本服务器是否有session,如果没有同步cookie信息。(购物车在数据库和cookie都存,就是为了把用户未登入时产生的购物车同步到登入用户上)
方式三: 服务器共享session ,使用一台作为用户的登录服务器,当用户登录成功之后,会将session写到当前服务器上,我们通过脚本或者守护进程将session同步到其他服务器上,这时当用户跳转到其他服务器,session一致,也就不用再次登录。
方式四 :通过缓存同步session,用户登入时,把登入信息放在redis或者memcache中,我们取session信息的时候都从缓存中取。(重写session创建 获取 销毁 方法 创建存缓存中 获取从缓存中获取 销毁缓存中记录和服务器记录)
本文大致分两步:
1.springboot中如何使用redis。
2.redis如何解决session共享
pom依赖
[code]<!--redis配置开始--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>${spring-data-redis.version}</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>${jedis.version}</version> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <!--redis配置结束-->
添加redis配置类
该配置类同样可以配置缓存失效时间等。
[code]package com.mos.quote.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; /** * @author Administrator */ @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Bean public KeyGenerator KeyGenerator(){ return (target, method, params) -> { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); }; } @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(factory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } @Bean public CacheManager cacheManager(RedisTemplate<String,String> redisTemplate) { RedisCacheManager rcm = new RedisCacheManager(redisTemplate); //设置缓存过期时间 rcm.setDefaultExpiration(600000); return rcm; } }
在application.propreties中配置redis
[code]# Redis数据库索引(默认为0) spring.redis.database=0 # Redis服务器地址 spring.redis.host=192.168.1.118 # Redis服务器连接端口 spring.redis.port=6381 # Redis服务器连接密码(默认为空) spring.redis.password= # 连接池最大连接数(使用负值表示没有限制) spring.redis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.pool.max-wait=-1 # 连接池中的最大空闲连接 spring.redis.pool.max-idle=8 # 连接池中的最小空闲连接 spring.redis.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.timeout=0
单元测试
1、set值(字符串)
[code]@Test public void put(){ stringRedisTemplate.opsForValue().set("test001","test001"); Assert.assertEquals("test001", stringRedisTemplate.opsForValue().get("test001")); }
往redis放一个key为test001、value为test001的值,然后查看redis
2、set值(object)
[code]@Test public void testObj() throws Exception { SysUser user=new SysUser(); user.setId("123456"); user.setName("张三"); ValueOperations<String, SysUser> operations=redisTemplate.opsForValue(); operations.set("user1", user); operations.set("user2", user,5, TimeUnit.SECONDS); Thread.sleep(6000); Assert.assertFalse(redisTemplate.hasKey("user2")); }
往redis分别放key为user1和user2的对象,user2设置5秒失效,线程等待6秒再完成,期望结果:redis中有user1,没有user2,bingo!!!
解决session共享
使用spring-session-data-redis实现session共享,pom中引入该依赖(上文已添加),添加SessionConfig配置类。
对,没看错,只需要这个就够了。最长有效时间根据自己情况随意配置即可。
[code]package com.mos.quote.config; import org.springframework.context.annotation.Configuration; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; /** * @author Administrator */ @Configuration @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3000) public class SessionConfig { }
测试
写一个简单Controller,如下
[code]@RequestMapping("testSessionTimeOut") public String testSessionTimeOut(String id,HttpSession session,Model model){ Area area = areaService.getById(id); System.out.println("sessionId-------->"+session.getId()); model.addAttribute("area",JSON.toJSONString(area)); session.setAttribute("area",JSON.toJSONString(area)); return "demo/test1"; }
阅读更多
- Nginx+Redis+Tomcat实现负载均衡项目session共享
- tomcat+nginx+redis实现均衡负载、session共享---项目默认路径找不到
- tomcat+nginx+redis实现均衡负载、session共享
- tomcat+nginx+redis实现均衡负载、session共享(二)
- 转 tomcat+nginx+redis实现均衡负载、session共享(二)
- tomcat+nginx+redis实现均衡负载、session共享(二)
- nginx+tomcat+redis集群实现负载均衡和session同步的步骤和问题处理方法
- tomcat+nginx+redis实现均衡负载、session共享(二)
- tomcat+nginx+redis实现均衡负载、session共享(一)
- tomcat+nginx+redis实现均衡负载、session共享(二)
- tomcat+nginx+redis实现均衡负载、session共享(二)
- tomcat+nginx+redis实现均衡负载、session共享
- tomcat+nginx+redis实现均衡负载、session共享
- tomcat+nginx+redis实现均衡负载、session共享(二)
- Nginx+Tomcat+Redis实现负载均衡、资源分离、session共享
- tomcat+nginx+redis实现均衡负载、session共享(二)
- (转)tomcat+nginx+redis实现均衡负载、session共享(二)
- 负载均衡之Nginx+tomcat+redis实现session共享的负载均衡
- tomcat+nginx+redis实现均衡负载、session共享
- tomcat+nginx+redis实现均衡负载、session共享(二)