Stateless vs Stateful:一次性彻底了解差异

发布: (2026年3月9日 GMT+8 11:10)
4 分钟阅读
原文: Dev.to

Source: Dev.to

在设计应用的后端时,选择 Stateful(有状态)还是 Stateless(无状态)架构是最根本的决策之一。这一选择直接影响系统的扩展方式以及认证的处理方式。

Stateful

类比

想象你每天都去同一家咖啡馆。你一到门口,服务员已经微笑着说:
“早上好,奥塔维奥!要和往常一样的咖啡吗?”

服务员记得你,因为他把你的名字和常点的咖啡记在了记忆里。如果你只说“再来一杯”,他也能准确知道该准备什么,因为在交互之间 保持了状态

概念

服务器与用户保持“会话”,把会话信息存储在自己的内存(RAM)或临时数据库中。

实际例子

PHP、Java(HttpSession)或 ASP.NET 中的经典会话,服务器在用户登录期间保存用户数据。

优缺点

  • 优点: 直观,易于在小型(单体)应用中管理。
  • 缺点: 水平扩展困难;需要使用 Sticky Sessions 或外部存储(如 Redis)让多实例共享状态。

代码示例(.NET)

// 服务器将名称保存在会话中(状态保存在服务器的 RAM 中)
HttpContext.Session.SetString("UsuarioNome", "Otávio");

// 要获取时,服务器从自己的内存中读取:
var nome = HttpContext.Session.GetString("UsuarioNome");

Stateless

类比

现在想象一家自助咖啡馆。你到达后,告诉服务员你的名字和咖啡种类,拿到饮料后服务员立刻忘记了你的信息。如果想再来一杯,你必须重新提供所有信息。

概念

服务器 不在请求之间保存任何客户端信息。处理任务所需的全部信息必须随请求一起发送(通常在 header 中)。

实际例子

现代的 REST API 和基于 JWT(JSON Web Token)的认证。

优缺点

  • 优点: 高度可扩展,适合微服务和云环境。
  • 缺点: 每次请求会稍微“重”,因为每次调用都要携带认证数据(token)。

代码示例(Spring Boot)

@GetMapping("/perfil")
public ResponseEntity getPerfil(@RequestHeader("Authorization") String token) {
    // 服务器是“冷的”:不在 RAM 中维护已登录用户列表。
    // 解码客户端发送的 JWT 以识别用户。

    if (token != null && token.startsWith("Bearer ")) {
        String jwt = token.substring(7);
        String username = jwtService.extractUsername(jwt); // 从 payload 中提取 "sub"

        return ResponseEntity.ok("Usuário identificado via Token: " + username);
    }

    return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

对比

特性StatefulStateless
存储位置服务器(内存/RAM)客户端(Token/Cookie)
可扩展性困难(需要 Sticky Sessions 或外部存储)容易(面向云和微服务)
真实案例PHP 会话、旧版购物车REST API、JWT、OAuth2
连接方式保持对话历史每次请求都是新对话

结论

现代 Web 开发的黄金法则是 优先使用 Stateless。在 AWS、Azure、Google Cloud 等环境,或使用 Docker/Kubernetes 时,无状态模型可以在不担心会话丢失的情况下轻松扩展到 10、100 台实例。

Stateful 仍然在某些遗留系统或非常特定的单体应用中有其用武之地,但大多数应用的现在和未来都是 Stateless

0 浏览
Back to Blog

相关文章

阅读更多 »