《Redis应用实例》Java实现(19):登录会话

58 阅读1分钟

使用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 无法跨服务器共享的问题。