
概述服务拆分、Nacos 注册、Feign 调用都通了之后架构会露出一个空档每个微服务都直接暴露在外谁都能调。网关就是来堵这个口子的。这篇只讲网关是什么、为什么微服务架构里必须有它不写代码。纲要没有网关的世界客户端直连多服务的四类痛点网关的三大职责路由转发含服务发现与负载均衡、权限校验、限流外加入口层的跨域处理网关在架构中的位置以及它自己也是一个微服务网关长什么样gateway模块结构与application.yml技术选型Zuul / Spring Cloud Gateway / Nginx边界与常见误解没有网关的微服务世界服务拆分后的第一版做法通常很朴素让客户端直接请求各个微服务。浏览器 / Appuser-service :8081order-service :8088pay-service :8082第三方开放平台用户库订单库支付库图能跑起来但只是能跑。客户端要记住每个服务的地址。http://192.168.1.10:8081、...:8088全硬编码在客户端里。哪天order-service扩容成三实例或端口从 8088 改成 9090客户端都得跟着改并重新发版。App 的发版周期以周甚至月计这种改动是灾难。跨切面逻辑要在每个服务重复一遍。鉴权、限流、日志、耗时统计跟业务无关却每个服务都要有一份。在user-service写了 JWT 校验order-service抄一遍抄着抄着就抄歪——漏一处就是后门。攻击面太大。内部服务裸露在公网上谁都能扫端口、构造请求。“批量导出”内部对账这类接口压根不该对外开放但服务摆在那里默认就是放行的。协议与报文格式各自为政。有的返回{code, msg, data}有的返回裸对象客户端要为每个服务写一套适配代码。归结成一句服务拆开了入口没有统一。网关的三大职责讲义口径是三条请求路由、权限控制、限流。重点是没有它时会怎样。路由转发客户端只认网关地址比如http://gateway:10010。请求最终落到哪个服务由网关按规则判断后转发这个动作叫路由。判断依据叫断言Predicate路径是/user/**就扔给user-service是/order/**就扔给order-service。目标地址一般写lb://userservice而不是具体 IP 端口。lb是 LoadBalancer意思是去注册中心查userservice有哪些实例再挑一个。所以路由天然带着服务发现和负载均衡——服务起三个实例网关自己轮着转配置一行不改。Path/user/** 命中lb://userservice拉取实例列表客户端 GET /user/1Gateway :10010路由表LoadBalanceruser-service-1user-service-2Nacos 注册中心没有它会怎样退回上一节硬编码地址、扩容就改客户端、服务发现完全用不上。权限校验网关是唯一入口做认证鉴权最自然请求进来先判断你是谁、有没有资格访问。不通过就地返回 401 / 403请求到不了下游通过后把解析出的身份用户 ID、角色透传给下游通常写成请求头下游直接取用不再自己解析 token。没有它时每个服务各写一遍鉴权代码重复、版本不一致、漏一处就是漏洞。这里有个坑透传身份头之前必须先在网关删掉客户端可能自带的同名头。否则客户端手动塞一个X-User-Id: 1网关原样透传下游就以为是登录用户本人——典型的越权漏洞。限流跟游乐场控制入园人数一个道理场馆只装一万人周末来了一两万多出来的先在门口等或劝返。user-service的连接池、线程池能撑住 500 QPS网关却把 2000 个请求全放进去服务被打爆正常用户也用不了。限流就是让网关按下游能承受的速度放行超出的排队或拒绝429。它是对后端的保护措施也是网关最本质的价值——站在最外面替里面的服务挡流量。补充一条跨域处理前端常撞见CORS policy: No Access-Control-Allow-Origin。跨域校验在浏览器侧做需要服务端返回正确响应头。不在网关统一处理就得每个微服务配一遍 CORSOPTIONS预检还要单独放行。放网关做一处生效。它的定位是——入口层的事所以归网关。网关在架构中的位置业务服务层入口层发现服务实例注册 / 心跳注册 / 心跳注册 / 心跳客户端 浏览器 / App / 第三方Nginx 最外层负载与静态资源Gateway 网关集群路由 / 鉴权 / 限流 / 跨域user-serviceorder-servicepay-serviceNacos 注册中心两点容易忽略。网关自己就是一个微服务它也要注册到 Nacos也要有端口工程里是10010也要能集群跟user-service没有本质区别只是职责是转发而不是处理业务所以它同样需要监控和发布流程。网关从注册中心拿服务列表它不维护哪个服务在哪台机器上只选出服务名再去注册中心要实例列表两个组件的职责别混。网关长什么样看一眼课程里gateway模块的真实结构。cloud-demo ├── pom.xml # 父工程聚合各模块 ├── eureka-server ├── feign-api ├── gateway # 网关模块 │ └── src/main │ ├── java/cn/itcast/gateway │ │ ├── GatewayApplication.java │ │ └── AuthorizeFilter.java │ └── resources/application.yml ├── order-service └── user-service配置也就是声明路由server:port:10010spring:application:name:gatewaycloud:nacos:server-addr:nacos:8848# nacos地址gateway:routes:-id:user-service# 路由标识必须唯一uri:lb://userservice# 目标地址lb 表示走负载均衡predicates:-Path/user/**# 路径以 /user 开头则命中-id:order-serviceuri:lb://orderservicepredicates:-Path/order/**这段配置就是本文概念的具体化uri对应路由lb://对应服务发现 负载均衡predicates对应断言。看不懂没关系下一篇逐行拆。技术选型组件底层模型编程范式现状定位Zuul 1.xServlet阻塞式一请求一线程已停止维护早期方案新项目不用Zuul 2.xNetty异步非阻塞生态弱社区基本不用Spring Cloud GatewaySpring 5 WebFlux Reactor响应式、非阻塞官方主推业务网关首选课程使用NginxC 模块 / epoll事件驱动成熟稳定流量入口、静态资源、代理阻塞与非阻塞的差别在高并发下才明显Zuul 1.x 每请求占一个线程池满就排队Gateway 基于 Reactor 事件循环少量线程扛住大量连接这是它取代 Zuul 的核心原因。Gateway 和 Nginx 不是二选一是分层配合Nginx 在外层管 HTTPS 终止、静态资源、防 CC它不懂业务规则Gateway 在业务入口管按业务规则路由、鉴权、限流、跨域它是 Java 代码能读配置、能调服务。Nginx 管流量怎么进来Gateway 管请求该去哪、能不能去。边界与常见误解会加一跳延迟且本身是单点。请求多绕一次转发多数业务可忽略极致低延迟场景要单独评估所有流量都从它过它挂了全站不可用生产至少两个实例前面再挂 Nginx 或云 LB。别在网关里写业务逻辑。一看到能写过滤器就有人把用户查询、订单聚合全塞进去网关逐渐长成新的巨石。判断标准很简单这段逻辑跟具体业务有关吗有就不该在网关。限流熔断还要服务侧兜底。网关护的是入口但服务之间的 Feign 调用不走网关这条链路得靠 Sentinel 之类在服务侧防护两道防线互补而非重复。“网关就是 Nginx。”不是。Nginx 是反向代理配置是静态文件Gateway 是应用层网关规则能写成 Java 代码能动态改路由。“有网关就不需要注册中心了。”反了。lb://正是靠注册中心才能解析成具体实例否则网关只能硬编码地址。“网关可以缓存业务数据。”不该。缓存是业务服务的职责网关缓存会带来一致性问题和脏读。总结服务拆开后若没有统一入口客户端要记一堆地址、跨切面逻辑到处重复、内部服务裸露、协议不统一网关就是来收口这一处的。网关按讲义口径有三条职责路由转发统一入口 服务发现 负载均衡、权限校验统一鉴权后透传身份、限流按下游承受能力放行跨域这类入口层的事也归它。网关自己也是微服务要注册、要配端口10010、要集群实例列表从注册中心拿。业务网关选Spring Cloud GatewayWebFlux ReactorZuul 1.x 已停止维护不选Nginx 与 Gateway 是分层配合。网关会加延迟、本身是单点、不能往里写业务逻辑限流熔断仍需服务侧兜底。概念立到这里就够了。下一篇进入实战建 gateway 工程、写路由规则、断言与过滤器各有哪些以及怎么用它把跨域问题一次解决。