Распределенный сеанс SpringBoot
В сегодняшней ситуации кластера серверов сохранение состояния сеанса входа пользователя также изменилось с одного компьютера на распределенное требование.Ниже приводится подробное описание нескольких распределенных решений для хранения сеансов.
- Репликация сеанса: выполнение на сервере, поддерживающем репликацию сеанса, синхронизация сеансов и поддержание согласованности сеансов.
план:tomcat-redis-session-manager
- Закрепленная сессия: принудительно распределять сессии на каждый сервер
Решение: балансировка нагрузки
- Сеанс хранения файлов cookie: хранить идентификатор сеанса в файле cookie (небезопасно, файл cookie легко украсть, он может хранить неважные данные)
- Централизованное управление сеансом: храните сеанс пользователя в кеше одного или кластерного сервера, и все веб-серверы берут сеанс с него для реализации совместного использования сеанса.
Решение: Redis сохраняет идентификатор сеанса, сгенерированный пользователем, или сохраняет файл cookie, который сохраняет идентификатор сеанса.
Здесь объясняется только четвертая схема, которая является наиболее стабильной и наиболее часто используемой.
Redis кэширует сеанс постоянного хранения
Redis хранит файлы cookie, в которых хранится uuid, сгенерированный пользователем (токен как sessionId)
- имя файла cookie и срок действия
public static final String COOKIE_NAME_TOKEN = "token";
private static final ex = 3600;
- Создать cookie и сохранить в Redis
private String addCookie(HttpServletResponse response,SeckillUser user){
String token = UUIDUtil.uuid();
redisService.set(token,user);//使用redis把token作为键存储user作为值 我使用jedis自己实现的也可以使用redisTemplate
Cookie cookie = new Cookie(COOKIE_NAME_TOKEN, token);//设置cookie 名称为token
cookie.setMaxAge(ex);//设置过期时间
cookie.setPath("/");
response.addCookie(cookie);
return token;
}
- uuid как инструмент генерации sessionid
public class UUIDUtil {
public static String uuid(){
return UUID.randomUUID().toString();
}
}
Интегрировано с использованием Широcrazy-cake
(Используйте Redis для хранения SessionId)
- Shiro — это фреймворк веб-безопасности для аутентификации при входе в систему, авторизации удостоверения пользователя, простой в использовании.
spring-security
, вы также можете наследовать сеанс, распределенное хранилище файлов cookie
Если вы не знаете, вы можете прочитать этот пост в блоге:Использование Shiro и интеграция Redis для кеширования
тайник
- Использовать кеш для хранения сессий (один сервер использует EhCacheManager)
- Однако в распределенной системе, в случае кластеров серверов, EhCacheManager не может решить проблему совместного использования данных (база данных будет запрашиваться несколько раз), поэтому выберите использование Redis в качестве кеша.
Redis реализует кеш Широ
- Распределенный обмен информацией о сеансе и авторизации должен сохранять сеанс и авторизацию в базе данных или кэшировать кластер Shiro, чтобы предотвратить множественные вставки и запросы к базе данных.
-
Пользовательский класс реализации: или используйте shiro-redis с открытым исходным кодом Crazycake для реализации хороших инструментов.
- RedisSessionDAOМожет наследовать EnterpriseCacheSessionDAO для управления сеансом.
- RedisCacheНаследуйте класс Cache для реализации конкретных кэшей операций Redis (удаление, получение, установка, ключи и т. д.).
- RedisCacheManagerРеализовать getCache интерфейса CacheManager, чтобы получить RedisCache и передать его в securityManager для управления.
Используйте ConcurrentMap для более эффективного управления данными и кешем
- существует
ShiroConfig
класс конфигурацииsessionManager
сдаватьDefaultWebSecurityManager
управлять
@Bean
public DefaultWebSessionManager sessionManager(){
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
//session时间
sessionManager.setGlobalSessionTimeout(redisConfig().getTimeout());
//删除无效session
sessionManager.setDeleteInvalidSessions(true);
log.info("sessionManager注入成功");
sessionManager.setSessionIdCookie(cookie());
// sessionDao 分布式共享session和授权信息需要把session和授权持久化到数据库或者缓存 shiro集群为了防止多次插查询数据库
sessionManager.setSessionDAO(redisSessionDao());
return sessionManager;
}
- существует
sessionManager
Внедрить хранилище cookie вjsessionId
@Bean
public SimpleCookie cookie() {
SimpleCookie cookie = new SimpleCookie("JSESSIONID");
cookie.setHttpOnly(true);
cookie.setPath("/");
return cookie;
}
- снова
sessionManager
инъекцияredisSessionDao
Отвечает за сохранение сеанса
@Bean
public RedisSessionDAO redisSessionDao(){
RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
redisSessionDAO.setRedisManager(redisManager());
redisSessionDAO.setSessionIdGenerator(sessionIdGenerator());
return redisSessionDAO;
}