从单体到微服务:重新理解 Gateway、Spring Security 与请求入口职责

发布时间:2026/7/2 19:16:32

从单体到微服务:重新理解 Gateway、Spring Security 与请求入口职责 在学习后端认证体系的时候很容易遇到一个问题后端接口请求到底是不是一定先进入 Gateway然后再进入 Controller以前我也容易把这件事想混前端请求 ↓ Gateway ↓ Controller好像所有后端接口前面都应该有一个 Gateway。但真正理解单体应用和微服务架构之后会发现这个理解并不准确。更准确的说法是有 Gateway 的架构请求才会先进入 Gateway没有 Gateway 的单体应用请求会直接进入 Spring Boot 应用再由 Spring Security 和 Spring MVC 处理。一、先看单体应用的请求链路单体应用通常是一个 Spring Boot 项目。里面虽然也有很多 Controller、Service、Mapper比如AuthController UserController OrderController ProductController AdminController以及AuthService UserService OrderService ProductService AdminService但是它们都在同一个 Spring Boot 进程里面。所以单体应用的请求链路通常是App / Web ↓ Nginx ↓ Spring Boot 单体应用 ↓ Spring Security Filter Chain ↓ DispatcherServlet ↓ Controller ↓ Service ↓ Mapper / DB / Redis比如请求GET /user/info进入 Spring Boot 之后Spring MVC 会根据 URL 找到对应的 ControllerRestController RequestMapping(/user) public class UserController { GetMapping(/info) public UserInfoVO getUserInfo() { return userService.getUserInfo(); } }也就是说GET /user/info ↓ Spring Boot ↓ Spring MVC ↓ UserController.getUserInfo()如果请求是GET /order/list那就是GET /order/list ↓ Spring Boot ↓ Spring MVC ↓ OrderController.list()这里不需要 Gateway。因为这些 Controller 本来就在同一个应用里Spring MVC 自己就可以完成接口分发。二、单体应用为什么通常用 Spring Security单体应用真正要解决的问题不是这个请求要转发到哪个服务而是当前请求是谁发的 用户有没有登录 Token 是否有效 Redis 中的登录态是否存在 用户有没有权限访问这个接口 Controller 或 Service 中怎么拿到当前用户这些问题正是 Spring Security 擅长解决的。单体应用中的认证链路一般是请求 ↓ Spring Security Filter Chain ↓ JwtAuthenticationFilter ↓ 解析 JWT ↓ 校验 Token 是否过期 ↓ 校验 Redis 登录态 ↓ 构造 Authentication ↓ 放入 SecurityContextHolder ↓ 进入 Controller比如一个常见的安全配置Configuration EnableWebSecurity public class SecurityConfig { Bean public SecurityFilterChain securityFilterChain( HttpSecurity http, JwtAuthenticationFilter jwtAuthenticationFilter ) throws Exception { http .csrf(csrf - csrf.disable()) .authorizeHttpRequests(auth - auth .requestMatchers(/auth/login, /auth/register).permitAll() .requestMatchers(/admin/**).hasRole(ADMIN) .requestMatchers(/user/**).authenticated() .requestMatchers(/order/**).authenticated() .anyRequest().authenticated() ) .addFilterBefore( jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class ); return http.build(); } }这里表达的意思是/auth/login 不需要登录 /auth/register 不需要登录 /admin/** 需要 ADMIN 角色 /user/** 需要登录 /order/** 需要登录 其他接口 默认需要登录JWT Filter 负责解析 Token并把用户信息放入 Spring Security 的上下文Authentication authentication new UsernamePasswordAuthenticationToken( loginUser, null, loginUser.getAuthorities() ); SecurityContextHolder.getContext().setAuthentication(authentication);后面在 Controller 或 Service 中就可以获取当前登录用户。这就是 Spring Security 的价值认证 鉴权 用户上下文 角色权限 方法权限 安全异常处理所以在单体应用中Spring Security 更合适。三、那 Gateway 到底解决什么问题Gateway 主要解决的是多个后端服务的统一入口和路由转发问题这通常出现在微服务架构中。微服务不是一个 Spring Boot 应用而是多个独立运行的 Spring Boot 服务。比如auth-service 8081 user-service 8082 order-service 8083 payment-service 8084 message-service 8085每个服务都是一个独立进程。每个服务都有自己的 Controller。比如auth-service 里面有 AuthController user-service 里面有 UserController order-service 里面有 OrderController payment-service 里面有 PaymentController这时候如果前端直接调用各个服务就会变得很乱登录接口调用 auth-service 用户接口调用 user-service 订单接口调用 order-service 支付接口调用 payment-service前端不应该关心后端拆成了多少个服务也不应该知道每个服务的地址和端口。所以微服务架构中通常会加一层 GatewayApp / Web ↓ Nginx ↓ Gateway ↓ auth-service ↓ user-service ↓ order-service ↓ payment-serviceGateway 对外暴露统一地址https://api.xxx.com然后根据路径做路由转发/auth/** → auth-service /user/** → user-service /order/** → order-service /pay/** → payment-service /message/** → message-service比如前端请求GET https://api.xxx.com/order/listGateway 收到后判断/order/** 应该转发给 order-service于是请求链路变成App ↓ Gateway ↓ order-service ↓ OrderController.list()这就是 Gateway 的核心价值之一服务路由转发。四、Gateway 的“转发”和 Spring MVC 的“分发”不是一回事这个区别非常关键。1. Gateway 的转发Gateway 的转发是跨服务、跨进程的。比如Gateway 收到 /order/list ↓ 转发到 order-service这里的order-service是另一个独立运行的 Spring Boot 应用。所以 Gateway 解决的是这个请求应该交给哪个微服务2. Spring MVC 的分发Spring MVC 的分发是在当前 Spring Boot 应用内部完成的。比如单体应用中Spring Boot 收到 /order/list ↓ Spring MVC 匹配 URL ↓ 找到 OrderController.list()这里没有跨进程也没有跨服务。所以 Spring MVC 解决的是当前应用内部哪个 Controller 方法处理这个请求所以可以这样记Gateway把请求转发给哪个服务 Spring MVC把请求分发给哪个 Controller再直白一点Gateway 是应用之间的转发 Spring MVC 是应用内部的分发五、为什么微服务更需要 Gateway因为微服务拆分之后会出现很多公共问题。比如每个服务都要校验 Token 吗 每个服务都要查 Redis 判断登录态吗 每个服务都要做限流吗 每个服务都要处理黑白名单吗 每个服务都要记录入口日志吗如果每个服务都重复做一遍就会出现几个问题代码重复 规则分散 维护困难 容易不一致 安全策略不好统一所以微服务中通常会把这些公共入口能力放到 Gateway统一认证 统一鉴权 统一限流 统一跨域 统一日志 统一黑白名单 统一路由 统一灰度发布比如认证链路可以设计成App 请求接口 ↓ Gateway ↓ 读取 Authorization Token ↓ 校验 JWT ↓ 校验 Redis 登录态 ↓ 校验接口权限 ↓ 通过后转发到具体微服务如果 Token 无效Gateway 可以直接返回401 Unauthorized请求根本不会进入后面的 Controller。这就是 Gateway 作为统一入口的价值。六、微服务有了 Gateway还需要 Spring Security 吗需要看场景但很多企业项目里仍然会保留。更合理的设计是Gateway 做第一层入口校验 具体微服务内部做第二层业务权限控制Gateway 适合做粗粒度校验用户有没有登录 Token 是否有效 这个接口是否需要登录 请求是否被限流 是否在黑名单中但是具体业务权限很多时候还是要在服务内部判断。比如订单服务中用户能不能查看这个订单 这个订单是不是当前用户的 当前用户有没有商户权限 当前用户有没有管理员权限 当前用户能不能导出订单这些判断和业务强相关Gateway 不一定知道。所以微服务中常见的安全结构是App / Web ↓ Gateway ↓ 统一认证、限流、路由 ↓ order-service ↓ Spring Security / Method Security ↓ OrderController ↓ OrderService也就是说Gateway 管入口 Spring Security 管服务内部安全不是有了 Gateway后面的服务就可以完全裸奔。七、那单体能不能用 Gateway能用。单体也可以这样部署App / Web ↓ Nginx ↓ Gateway ↓ Spring Boot 单体应用但是大多数普通单体项目没有必要这么做。因为单体只有一个后端应用没有多个服务需要路由转发。很多事情在单体内部就可以完成认证鉴权Spring Security 接口拦截Filter / Interceptor 日志记录AOP / Filter 跨域处理Spring MVC / Nginx 限流控制Nginx / Redis / Sentinel如果只是一个普通后台系统使用Nginx Spring Boot Spring Security通常已经够了。单体强行加 Gateway反而会增加部署复杂度。八、最终怎么判断要不要 Gateway可以按下面几个问题判断。1. 后端是不是只有一个 Spring Boot 应用如果是通常不需要 Gateway。App ↓ Nginx ↓ Spring Boot ↓ Spring Security ↓ Controller2. 后端是不是拆成了多个独立服务如果是通常需要 Gateway。App ↓ Gateway ↓ user-service / order-service / pay-service3. 是否需要统一入口治理如果需要可以考虑 Gateway。比如统一鉴权 统一限流 统一日志 统一跨域 统一灰度 统一黑白名单 统一路由4. 是否只是普通单体后台如果只是普通单体后台Spring Security 基本够用。九、最终总结单体应用和微服务最大的区别不是 Controller 和 Service 数量多少而是是不是多个独立进程。单体应用虽然也有很多 Controller 和 Service但它们都在同一个 Spring Boot 进程中。所以单体应用中请求进入 Spring Boot ↓ Spring Security 做认证鉴权 ↓ Spring MVC 分发到 Controller ↓ Controller 调用 Service微服务架构中每个服务都是独立进程。所以微服务中请求进入 Gateway ↓ Gateway 做统一入口治理 ↓ Gateway 根据路径转发到具体微服务 ↓ 微服务 Controller 处理请求最终可以记住这句话Gateway 解决的是多个服务的统一入口和路由转发问题 Spring Security 解决的是当前应用内部的认证授权问题。再压缩一下单体 Nginx → Spring Boot → Spring Security → Controller 微服务 Nginx → Gateway → 微服务 → Controller所以不是所有后端接口都必须先经过 Gateway。更准确的理解是单体应用通常以 Spring Security 为主微服务架构通常以 Gateway 作为统一入口同时各个服务内部仍然可以保留 Spring Security 做业务权限保护。

相关新闻