使用redis來解決nginx--tomcat負載均衡部署session不一致
阿新 • • 發佈:2019-02-11
從上圖中我們可以看出,session是不同步的
- 解決方案
- 使用IP來限定每次訪問的伺服器
- ip_hash
- 只需要在配置nginx的時候加上上述配置即可
- 缺點
- 萬一使用者正在訪問的伺服器突然宕機了,就不好了
- 使用redis來實現session共享
- 使用統一認證
- 使用IP來限定每次訪問的伺服器
我們來講講怎麼是用redis來實現tomcat的session共享的?
- 開啟redis服務
- 裝置
- Tomcat7
- 把上述的連結中的三個jar包copy到tomcat到lib/目錄中
- 修改conf/context.xml檔案,新增
- <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
- <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
- host="192.168.56.103"
- port="6379"
- database="0"
- maxInactiveInterval="60" />
- 重啟tomcat
- 第二個tomcat重複第一個tomcat的步驟
- Tomcat8.5
- 把上述連結三個jar包copy到tomcat的lib/目錄下
- 修改conf/context.xml檔案,新增
- <Valve className="com.s.tomcat.redissessions.RedisSessionHandlerValve"/>
- <Manager className="com.s.tomcat.redissessions.RedisSessionManager"
- host="192.168.56.103"
- port="6379"
- database="0"
- maxInactiveInterval="60" />
- <Valve className="com.s.tomcat.redissessions.RedisSessionHandlerValve"/>
- 重啟tomcat
- 第二個tomcat亦如此
- Tomcat8.5的開源專案還提供了tomcat8.0redis session共享的解決
- 開啟nginx,發現如下
- Spring boot 專案使用redis實現共享會話
- 新增maven依賴
- <!--redis-->
- <dependency>
- <groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- <version>1.5.4.RELEASE</version>
- </dependency>
- <!-- redis session -->
- <dependency>
- <groupId>org.springframework.session</groupId>
- <artifactId>spring-session-data-redis</artifactId>
- <version>1.3.1.RELEASE</version>
- </dependency>
- 新建三個相關類
- import org.springframework.data.redis.cache.RedisCachePrefix;
- import org.springframework.data.redis.serializer.RedisSerializer;
- import org.springframework.data.redis.serializer.StringRedisSerializer;
- public class RedisPrefix implements RedisCachePrefix {
- private final RedisSerializer serializer;
- private final String delimiter;
- public RedisPrefix(String delimiter) {
- this.serializer = new StringRedisSerializer();
- this.delimiter = delimiter;
- }
- @Override
- public byte[] prefix(String cacheName) {
- return this.serializer.serialize(this.delimiter != null ? this.delimiter.concat(":").concat(cacheName).concat(":") : cacheName.concat(":"));
- }
- }
- package com.wpg.test.config;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.cache.CacheManager;
- import org.springframework.cache.annotation.CachingConfigurerSupport;
- import org.springframework.cache.annotation.EnableCaching;
- 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 redis.clients.jedis.JedisPool;
- import redis.clients.jedis.JedisPoolConfig;
- import java.util.Map;
- import java.util.concurrent.ConcurrentHashMap;
- @Configuration
- @EnableCaching
- public class RedisCacheConfigextends CachingConfigurerSupport {
- Logger logger = LoggerFactory.getLogger(RedisCacheConfig.class);
- @Value("${spring.redis.host}")
- private String host;
- @Value("${spring.redis.port}")
- private int port;
- @Value("${spring.redis.timeout}")
- private int timeout;
- @Value("${spring.redis.pool.max-idle}")
- private int maxIdle;
- @Value("${spring.redis.pool.max-wait}")
- private long maxWaitMillis;
- @Value("${spring.redis.password}")
- private String password;
- @Bean
- public JedisPool redisPoolFactory() {
- logger.info("JedisPool注入成功!!");
- JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
- jedisPoolConfig.setMaxIdle(maxIdle);
- jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
- JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
- return jedisPool;
- }
- @Bean
- public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
- RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
- redisTemplate.setConnectionFactory(cf);
- return redisTemplate;
- }
- @Bean
- public CacheManager cacheManager(RedisTemplate redisTemplate) {
- //todo 設定快取過期時間
- RedisCacheManager manager = new RedisCacheManager(redisTemplate);
- manager.setUsePrefix(true);
- RedisCachePrefix cachePrefix = new RedisPrefix("com.wpg.mybatis");
- manager.setCachePrefix(cachePrefix);
- // 整體快取過期時間
- manager.setDefaultExpiration(100L);
- // 設定快取過期時間。key和快取過期時間,單位秒
- Map<String, Long> expiresMap = new HashMap<>();
- expiresMap.put("com.wpg.mybatis", 100L);
- manager.setExpires(expiresMap);
- return manager;
- }
- }
- package com.wpg.test.config;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
- @Configuration
- //maxInactiveIntervalInSeconds session超時時間,單位秒
- @EnableRedisHttpSession(maxInactiveIntervalInSeconds =600)
- public class RedisSessionConfig {
- }
- 測試
- @RestController
- @RequestMapping("/session")
- public class IndexController {
- @GetMapping("/set")
- public Object setSession(@RequestParam(value = "name",defaultValue = "聞品高") String name, HttpServletRequest request){
- request.getSession().setAttribute("name",name);
- return "ok";
- }
- @GetMapping("/get")
- public Object getSession(HttpServletRequest request){
- Object name = request.getSession().getAttribute("name");
- return name;
- }
- }
- 新增maven依賴
- 把guns專案部署到兩個tomcat上
- 不行,guns專案不是使http session來記錄使用者狀態的
- 由於guns使用了shiro,Session都跑shiro去了
- 終於找到方法了
- 把guns-admin pom檔案中被註釋對的依賴開啟
- 在主類上添加註解
- @EnableRedisHttpSession
- 取消SpringSessionConfig類上的註釋
- 修改配置值