编程自学指南:java程序设计开发,会话管理进阶(分布式 Session/Token),分布式 Session 解决方案的原理与实现, JWT Token 的工作流程与实战应用

编程自学指南:java程序设计开发,会话管理进阶(分布式 Session/Token)

一、课程信息

学习目标

  1. 理解分布式系统中会话管理的核心挑战
  2. 掌握 3 种分布式 Session 解决方案的原理与实现
  3. 掌握 JWT Token 的工作流程实战应用
  4. 能根据场景选择合适的会话管理方案

二、课程导入:单体 vs 分布式

🌰 场景对比

环境会话管理方式问题点
单体应用本地 Session无(单服务器)
分布式集群本地 Session服务器 A 的 Session 无法在服务器 B 访问

三、分布式 Session 核心问题

🔍 1. 问题根源

  • 服务器无状态性:HTTP 协议本身不保存状态
  • 负载均衡:请求可能被分发到不同服务器,导致 Session 丢失

🔍 2. 典型场景

graph LR
    User -->|请求1| ServerA[服务器A]
    User -->|请求2| ServerB[服务器B]
    ServerA --> SessionA[Session@A]
    ServerB --> SessionB[Session@B]

问题:请求 1 在 A 服务器创建的 Session,请求 2 到 B 服务器时无法访问

四、分布式 Session 解决方案

🔥 方案 1:粘性会话(Sticky Session)

原理

通过负载均衡器将同一个用户的所有请求路由到同一台服务器

实现(Tomcat)
  1. 修改负载均衡配置(如 Nginx):
    upstream tomcat_cluster {
        ip_hash; # 基于 IP 哈希实现粘性
        server 192.168.1.10:8080;
        server 192.168.1.11:8080;
    }
    
  2. 验证:
    @WebServlet("/session")
    public class SessionServlet extends HttpServlet {
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
            HttpSession session = req.getSession();
            session.setAttribute("server", req.getLocalAddr());
            resp.getWriter().write("当前服务器:" + session.getAttribute("server"));
        }
    }
    

🔥 方案 2:Session 复制

原理

多台服务器之间同步 Session 数据

实现(Tomcat 集群)
  1. 配置 server.xml
    <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
    
  2. 验证:
    在 ServerA 创建 Session,ServerB 可读取相同数据

🔥 方案 3:Session 共享(集中存储)

原理

将 Session 统一存储到第三方存储(如 Redis)

实现(Redis + Spring Session)
  1. 添加依赖:
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
    </dependency>
    
  2. 配置 Redis:
    @Configuration
    @EnableRedisHttpSession
    public class SessionConfig {
        @Bean
        public RedisConnectionFactory connectionFactory() {
            return new JedisConnectionFactory();
        }
    }
    

五、Token 会话管理(JWT 详解)

🔍 1. JWT 核心概念

  • 定义
    JWT(JSON Web Token)是无状态的会话管理方式,通过签名的 JSON 字符串在客户端与服务器间传递状态
  • 结构
    Header.payload.Signature
    

🔥 2. JWT 工作流程

sequenceDiagram
    User->>Server: 提交用户名/密码
    Server->>Server: 验证通过
    Server->>User: 返回 JWT Token
    User->>Server: 携带 Token 请求资源
    Server->>Server: 验证 Token 有效性
    Server->>User: 返回资源

🔥 3. 实战案例:基于 JWT 的登录

① 生成 Token(LoginServlet)
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
        throws IOException {
        
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        
        if ("admin".equals(username) && "123".equals(password)) {
            // 生成 JWT(使用 jjwt 库)
            String token = Jwts.builder()
                .setSubject(username)
                .setExpiration(new Date(System.currentTimeMillis() + 30*60*1000)) // 30分钟过期
                .signWith(SignatureAlgorithm.HS256, "secretKey")
                .compact();
            
            resp.setContentType("application/json");
            resp.getWriter().write("{\"token\":\"" + token + "\"}");
        }
    }
}
② 验证 Token(Filter)
@WebFilter("/api/*")
public class JwtFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, 
                        FilterChain chain) throws IOException, ServletException {
        
        String token = ((HttpServletRequest) req).getHeader("Authorization");
        try {
            Jwts.parser().setSigningKey("secretKey").parseClaimsJws(token);
            chain.doFilter(req, res);
        } catch (Exception e) {
            ((HttpServletResponse) res).sendError(HttpServletResponse.SC_UNAUTHORIZED);
        }
    }
}

六、分布式 Session vs Token 对比

特性分布式 SessionToken
状态存储服务器端(Redis/DB)客户端(Cookie/Header)
扩展性好(集中存储)极好(无状态)
安全性高(数据在服务器)中(需防 Token 泄露)
典型场景传统 Web 应用集群前后端分离、微服务

七、关联知识:Token 与前后端分离

🔗 1. 前端存储 Token

// 登录成功后存储 Token
localStorage.setItem('token', response.data.token);

// 每次请求携带 Token
fetch('/api/data', {
  headers: {
    'Authorization': 'Bearer ' + localStorage.getItem('token')
  }
});

🔗 2. 与 Spring MVC 的集成

@RestController
@RequestMapping("/api")
public class ApiController {
    @GetMapping("/user")
    public User getUser(HttpServletRequest request) {
        String username = Jwts.parser()
            .setSigningKey("secretKey")
            .parseClaimsJws(request.getHeader("Authorization"))
            .getBody().getSubject();
        return userService.getUser(username);
    }
}

八、课堂练习

练习 1:粘性会话配置

任务

  1. 使用 Nginx 配置两个 Tomcat 实例的粘性会话
  2. 验证同一用户的请求是否路由到同一台服务器

练习 2:JWT 过期处理

任务

  1. 修改 JWT 有效期为 1 分钟
  2. 编写 Filter 在 Token 过期时返回 401 状态码

九、课程总结

知识图谱:

分布式会话管理  
   ↳ 三大方案:  
      ✅ 粘性会话(简单易用,单点故障)  
      ✅ Session 复制(数据同步,性能开销大)  
      ✅ 集中存储(Redis/DB,推荐方案)  
   ↳ Token 方案:  
      ✅ JWT 原理与实战  
      ✅ 前后端分离场景应用  

口诀记忆:

“分布式会话有三招,粘性复制集中存,
Token 无状态效率高,前后分离离不了,
方案选择看场景,安全扩展要权衡!”

十、课后作业

必做 1:分布式 Session 集群

要求

  1. 搭建两个 Tomcat 实例,使用 Redis 共享 Session
  2. 实现用户在任一节点登录后,其他节点可访问其 Session

必做 2:JWT 权限管理

任务

  1. 在 JWT 中添加角色信息(如 admin/user)
  2. 在 Filter 中根据角色控制访问权限
    • admin 可访问 /api/admin
    • user 禁止访问
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zl515035644

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值