使用redis实现分布式登录会话已经是标配功能了。 传统的 Session 是存储在单个服务器的内存中的。当你的应用部署在多台服务器上(负载均衡)时,如果用户第一次请求被分发到服务器 A,Session 创建在 A 上;第二次请求可能被分发到服务器 B,但 B 上没有这个 Session,用户就需要重新登录,这就是“有状态”服务带来的问题。
Redis 解决方案的核心思想是:将 Session 从应用服务器的内存中“抽离”出来,统一存储到一个所有应用服务器都能访问的中央缓存——Redis 中。
这样,无论用户的请求被分发到哪台服务器,服务器都可以去 Redis 中查询和验证 Session,从而实现“无状态”的应用服务器,便于水平扩展。
package com.foxbill.redisinaction;
import redis.clients.jedis.Jedis;
import java.util.UUID;
/**
* 登录会话
*/
public class Chapter19 {
static String key_prefix_lgointoken="chapter19:login:token";
static public void start(Jedis jedis) {
String token = login(jedis, "zhangsan", "123456");
System.out.println("zhangsan login token:"+token);
String user = checkToken(jedis, token);
System.out.println("checkToken result:"+user);
}
//登录,创建会话token,同时设置会话失效时间
private static String login(Jedis jedis, String username, String password) {
boolean isOk = false;
if (password.equals("123456")) {
isOk = true;
}
if (isOk) {
//验证通过,创建token,存放到redis中
String token = UUID.randomUUID().toString();
String key = key_prefix_lgointoken + ":" + token;
long expires = 10 * 60; //10分钟
jedis.setex(key,expires,username);
return token;
}
return null;
}
//验证token,返回userName
private static String checkToken(Jedis jedis, String token) {
String key = key_prefix_lgointoken + ":" + token;
String username = jedis.get(key);
return username;
}
}
小结: 使用 Redis 来实现分布式登录会话是一个非常经典且高效的方案。它能解决单体应用中 Session 无法跨服务器共享的问题。