ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Kong网关实现Spring Cloud微服务接口级限流实践

Kong网关实现Spring Cloud微服务接口级限流实践 1. 为什么接口级限流要放到 Kong 层而不是微服务内部做微服务的同学基本都遇到过限流需求。我之前在 Spring Cloud 项目里第一版把限流写在业务服务里每个接口一套 AOP 注解有的服务还是 Python 写的规则和结果根本没法统一。后来把限流从业务代码里抽出来放到了 Kong 网关层才真正把“接口级限流”做成了平台能力。这篇就是这次改造的完整复盘为什么选 Kong、限流模型怎么理解、Spring Cloud 微服务怎么接、插件参数怎么配、多节点生产环境有哪些坑以及一套可以直接抄的配置模板。后端、架构、运维都能照着走。1.1 微服务内部做限流问题到底出在哪里微服务内部做限流听起来很直接每个服务加一个拦截器判断一下 QPS 有没有超过阈值超过了就返回 429。真这么干过的人应该懂后面全是麻烦。首先是标准不统一。订单服务用 Redis 固定窗口支付服务用的可能是本地限流用户服务如果换了语言还得重新实现一套。同样叫“每秒 100”实际算法可能完全不一样。到了线上压测你根本说不清楚“系统到底能扛多少 QPS”因为每个服务的限流阈值是各算各的。其次是跨服务配额没法表达。一个下单流程要调用用户、库存、支付三个服务假设每个服务都限制在 100 QPS用户视角真实体验并不是 100可能三个服务叠加反而能扛 300也可能某个服务先被触发把整条链路拖死。接口级限流真正关心的往往是“外部调用这个接口的整体速率”而不是某个服务内部的局部速率这个维度只有在统一入口才能看清楚。还有一点容易被忽视限流代码写在业务服务里意味着每次发版都要重新走一遍业务服务的 CI/CD而且限流逻辑会逐渐和业务代码纠缠到一起。今天加一个接口限流要改代码明天调一个阈值还要改代码运维同学想临时调参根本没戏。1.2 Kong 做接口级限流的优势是什么Kong 本质上是 OpenResty 和 Nginx 之上的 API 网关它站在微服务前面天然能看到所有进入微服务的流量。和 Spring Cloud Gateway 相比它最大的价值不是“能限流”而是“不占业务服务资源、配置热生效、对上游透明”。我见过不少团队一开始用 Spring Cloud Gateway 写限流也能用但限流逻辑基本都是自己写。要么基于 Redis 计数器要么接 Resilience4j要做成“每个接口一个阈值、每个调用方一个配额”这种模型代码量不小还要处理分布式同步、异常降级、header 透传。Kong 的 rate-limiting 插件把这些都收敛成了配置改一个参数就能调整一个接口的限流策略不用动一行业务代码。另外Spring Cloud 微服务体系本身可以通过 Nacos、Eureka 做服务发现但 Kong 不需要关心这个。它只需要知道“哪个外部路径转发到哪个上游入口”后续是 Spring Cloud Gateway、Dubbo 网关还是直接一个 Nginx对 Kong 来说都是“上游 target”。这种方式让微服务架构和 API 网关的演进解耦接口级限流也就能独立迭代。我最终选定 Kong 还有一个很实际的原因它可以按路由绑定插件。一个接口在 Kong 里就是一条或多条 Route限流插件挂在 Route 上天然就是“接口级”。你不需要在代码里维护接口路径和限流阈值的映射关系Kong 的配置本身就是映射关系。下面这张表是我当时做技术选型时的对比看下来就比较清楚对比项业务服务内部限流Spring Cloud Gateway 限流Kong 网关限流改动量高需要改业务代码中需要改网关代码低纯配置限流维度服务内部网关层可做部分IP / 消费者 / Header / Path跨服务统一很难统一可以统一天然统一动态调整发版发版秒级生效对 Spring Cloud 的侵入性高中低多节点一致性需要自己实现需要自己实现或依赖 Redis插件内置 Redis 支持2. 动手前先吃透Kong 的限流模型和“接口级”到底怎么切很多人上来就配插件配着配着发现限流没生效或者限流生效了但把全站都限制了。核心原因是没搞明白 Kong 的限流插件是按什么维度计数的以及“接口级”到底靠什么实现。先把这两个问题说清楚。2.1 rate-limiting 插件的核心参数是怎么工作的Kong 的 rate-limiting 插件负责“按固定时间窗口统计请求次数超过阈值就拒绝”。它有几个关键参数先记住second、minute、hour、day、month、year分别表示在多少秒/分钟/小时内允许请求多少次可以同时配置多个。比如second: 20, minute: 300意思是每秒最多 20每分钟最多 300任何一个先超了都会触发限流。limit_by计数按什么维度做 key可选consumer、credential、ip、header、path等。这个是“按谁限流”的关键。policy计数存储在哪里。单机测试用local多节点生产必须用redis否则每个 Kong 节点各计各数。window_type窗口类型默认是fixed固定窗口新版也支持sliding滑动窗口。hide_client_headers是否向前端隐藏X-RateLimit-Limit-Minute、X-RateLimit-Remaining-Minute这类响应头。默认隐藏建议开发时关掉方便排查。fault_tolerant当限流存储Redis不可用时是否放行请求。默认true是放行对可用性友好但对保护性不友好。窗口这个东西很像电梯限流固定窗口是“这分钟内最多进 60 个人”但第 59 秒和第 61 秒各进了 60 个实际 2 秒内进了 120 个。滑动窗口会尽可能平滑不让流量卡在窗口边界上跑出两倍量。生产环境如果要严格保护下游建议用sliding代价是 Redis 上的计算稍微复杂一点。2.2 “接口级”不是靠插件参数而是靠路由拆分Kong 的 rate-limiting 插件本身并没有一个叫“接口路径”的参数来指定限流哪个 Path。它的作用域是挂在某个实体上可以挂在全局、Service、Route、Consumer 上。真正的接口级限流是靠“一个接口对应一条 Route然后在 Route 上挂插件”来实现的。举个例子。Spring Cloud 里有一个订单服务对外暴露两个接口POST /order/createGET /order/query如果这两个接口都走同一个 Service在 Service 上挂限流插件那限流就是服务级的两个接口共享配额。想让它们各自独立限流就要在 Service 下面创建两条 Route路径分别匹配/order/create和/order/query再分别给两条 Route 挂插件。我在生产环境里强烈建议你一个接口一条 Route并且把methods一起配上。因为同一个路径 GET 和 POST 的负载可能差异很大只按路径限流会直接把 GET 的配额当作 POST 的配额用。还有一种做法是在同一个 Route 上配置limit_by: path让插件按请求路径计数。这个功能新版本支持但在配置多个路径时很容易搞混。我的经验是别绕弯直接用路由拆分这样限流阈值、响应头、后续的熔断和日志都能独立管理。另外要注意一个机制同一个插件如果既配在全局又配在某个 Route 上请求命中 Route 时Route 上的配置会覆盖全局配置而不是两张配置叠加。所以“全局兜底 接口精细化”这种组合要理解成“有 Route 配置的接口按 Route 配置来没有 Route 配置的接口按全局来”而不是先算全局再加接口。2.3 别忘了 response-ratelimiting 这个容易混淆的插件Kong 里还有一个叫 response-ratelimiting 的插件很多新同学会搞混。rate-limiting 是“请求进来时先检查有没有超过限制”response-ratelimiting 是“上游响应返回后根据响应里的消耗值来扣减配额”。前者适合做接口入口保护后者适合做“按业务用量计费”一类的场景比如按响应行数、按 token 消耗数来计量。我们做微服务接口级限流绝大多数需求是流量保护直接用 rate-limiting 就够了。除非你的 Spring Cloud 服务会通过响应头动态告诉网关“本次请求用了多少配额”才需要去看 response-ratelimiting。不要一上来就把两个插件都挂了容易把配额模型搞乱。3. 部署 Kong 并接入 Spring Cloud 微服务纸上谈兵环节结束开始环境搭建。我会给一套 Docker Compose 的最小可运行方案然后讲清楚 Spring Cloud 微服务怎么接入。这里为了演示方便使用 Kong 3.x 版本因为 3.x 对sliding窗口和 Redis 策略的支持比较成熟。3.1 用 Docker Compose 拉起一套最小环境最小环境需要三个组件PostgreSQLKong 的控制面配置存储也可以换成 Cassandra但生产用 PostgreSQL 最多、Redis限流计数存储、Kong 本体。我先给一个可以直接跑起来的 docker-compose.yml实际使用你把版本号调整一下就行。services: kong-db: image: postgres:13-alpine environment: POSTGRES_USER: kong POSTGRES_PASSWORD: kong POSTGRES_DB: kong networks: - kong-net volumes: - kong-db-data:/var/lib/postgresql/data healthcheck: test: [CMD-SHELL, pg_isready -U kong] interval: 5s timeout: 5s retries: 10 redis: image: redis:7-alpine networks: - kong-net kong-migrate: image: kong:3.4 command: kong migrations bootstrap environment: KONG_DATABASE: postgres KONG_PG_HOST: kong-db KONG_PG_PASSWORD: kong KONG_PG_DATABASE: kong networks: - kong-net depends_on: kong-db: condition: service_healthy restart: on-failure kong: image: kong:3.4 environment: KONG_DATABASE: postgres KONG_PG_HOST: kong-db KONG_PG_PASSWORD: kong KONG_PG_DATABASE: kong KONG_PROXY_LISTEN: 0.0.0.0:8000 KONG_ADMIN_LISTEN: 0.0.0.0:8001 KONG_ADMIN_ACCESS_LOG: /dev/stdout KONG_ADMIN_ERROR_LOG: /dev/stderr KONG_PROXY_ACCESS_LOG: /dev/stdout KONG_PROXY_ERROR_LOG: /dev/stderr KONG_PLUGINS: bundled,rate-limiting ports: - 8000:8000 - 8001:8001 networks: - kong-net depends_on: kong-migrate: condition: service_completed_successfully networks: kong-net: volumes: kong-db-data:执行步骤分三步docker compose up -d kong-db redis docker compose run --rm kong-migrate docker compose up -d kong如果日志里没有报错执行curl http://127.0.0.1:8001/status能看到 Kong 的 status 信息就说明好了。要注意kong-migrate只是初始化数据库结构不能反复执行它会提示已经被初始化这时候用kong migrations up升级即可。3.2 Spring Cloud 微服务怎么让 Kong 找到流量入口这里先画一张最清晰的拓扑图外部客户端 - Kong(8000) - Spring Cloud Gateway(8080) - Nacos/Eureka 注册中心 - Spring Cloud 微服务如果你的微服务已经通过 Spring Cloud Gateway 作为内部网关那么 Kong 根本不需要直接对接 Nacos。Kong 在 Docker 网络里只需要访问到 Spring Cloud Gateway 的地址比如http://spring-gateway:8080把它当作 Kong 的一个上游。后面 Spring Cloud 服务怎么拆分、怎么注册都和 Kong 无关。如果你的项目用的是 Spring Cloud Alibaba Nacos千万不要一开始就想着让 Kong 去读 Nacos 服务列表。Kong 社区版没有内置 Nacos 服务发现插件硬接要引入第三方插件或者写 Lua维护成本很高。最省心的做法是让流量先经过 Spring Cloud Gateway让 Gateway 去做服务路由和负载均衡。如果微服务规模不大没有内部网关也可以直接让 Kong 的 upstream 指向某个固定服务实例例如http://order-service:8080。这种情况下要注意Kong 容器必须能解析到order-service这个主机名否则会连接失败。生产环境建议用内部负载均衡域名而不是某个具体实例 IP。3.3 在 Kong 中创建 Service 和 Route环境起来以后在数据库模式下用 Admin API 创建配置是最直接的。先把一个 Spring Cloud 服务注册成 Kong 的 Servicecurl -s -X POST http://127.0.0.1:8001/services \ -H Content-Type: application/json \ -d { name: order-service, url: http://spring-gateway:8080 }然后在这个 Service 下面创建两条 Route分别对应两个接口。这里面的关键参数是paths、methods和strip_path。strip_path是我最想提醒你的参数。如果 Kong 对外路径和上游路径完全一致比如POST /order/create要原样转发给 Spring Cloud Gateway 的/order/create那就设置strip_path: false。如果你希望对外隐藏内部路径比如外部访问/api/order/create内部转发/order/create就需要strip_path: true并且paths配置成/api/order/create。很多同学在这里会把strip_path和paths搞反导致上游收到一个多余的前缀返回 404。创建 Routecurl -s -X POST http://127.0.0.1:8001/routes \ -H Content-Type: application/json \ -d { name: order-create-route, service: { id: order-service的id用上一步返回的值 }, methods: [POST], paths: [/order/create], strip_path: false }创建完以后先不要挂限流插件直接测试一下代理链路是否通curl -i -X POST http://127.0.0.1:8000/order/create如果能看到 Spring Cloud 服务返回的业务响应说明基本链路已经通。此时再看限流插件的配置思路会清晰很多。4. 接口级限流插件配置全过程链路通了之后限流就只是配置问题。下面我会用具体示例说明怎么给一个接口挂插件以及限流键、参数应该如何选择。4.1 给单个接口绑定 rate-limiting 插件假设我要给POST /order/create这个接口做一个“每分钟最多 300 次”的限流并希望多节点共享计数可以这样调用 Admin APIcurl -s -X POST http://127.0.0.1:8001/routes/order-create-route/plugins \ -H Content-Type: application/json \ -d { name: rate-limiting, config: { limit_by: ip, policy: redis, redis_host: redis, redis_port: 6379, redis_database: 0, minute: 300, window_type: sliding, hide_client_headers: false } }这里解释几个决策点第一policy用redis而不是local。如果你只有一个 Kong 节点用local没问题但只要生产环境有两个或更多 Kong 节点用local就会导致每个节点各计各数。假设配置每分钟 300后面挂了 3 个 Kong 节点实际放过去的请求可能达到每分钟 900。第二window_type用sliding。下创建订单接口不允许瞬时量突破滑动窗口比固定窗口更平滑。压测时你会看到滑动窗口的瞬时突发明显更小代价是 Redis 的命令执行频率会更高但这个量级对 Redis 来说压力完全可以接受。第三hide_client_headers设置成false只是为了方便排查。生产环境如果不想暴露内部限制策略可以设回true。4.2 限流键怎么选IP、消费者还是自定义 Headerlimit_by决定同一个窗口内谁和谁共享配额。这是接口级限流最需要想清楚的地方。最常见的维度是 IP。配置limit_by: ip后同一个客户端 IP 在一个时间窗口内共享一个配额。优点是接入成本低不需要用户体系缺点是 NAT 或公司出口 IP 会让大量用户共享同一个 IP配额很容易被打满。如果前面再加一层负载均衡Kong 拿到的可能是负载均衡的 IP这一点在后面的“真实 IP”排查里会细说。如果想按用户维度限流就需要先用 key-auth、jwt 之类的认证插件识别消费者然后把limit_by改成consumer。举个例子登录用户每人的下单接口限流是每分钟 30 次配置limit_by: consumer就能实现。没有登录态的请求因为没有 consumer会走不到这类限流逻辑里所以还要考虑匿名流量怎么处理。如果你已经在请求头里带了业务用户 ID比如X-User-Id也可以把limit_by设为header并指定header_name: X-User-Id。但这么做有风险一旦某些请求没有这个 headerKong 会把这些请求归到一个空 key 下等于所有缺失用户信息的请求共享同一个配额很容易集体被限。我的经验是能走消费认证就走消费认证实在不行再用 header。下面这张表能帮你快速选型限流维度limit_by 值适合场景风险点按 IPip匿名接口、防单 IP 爬虫出口 NAT 会把很多人变同一 IP按消费者consumer登录用户接口需要先加认证插件按 Headerheader已有业务用户标识Header 缺失会导致误限按路径path同一个 Route 多路径接口级建议别省 Route4.3 参数计算与策略配置参考限流阈值不能拍脑袋定我一般会先按下面公式估算接口容量 单实例 QPS × 实例数 × 冗余系数 限流阈值 接口容量 × 保护比例比如订单创建接口单实例压测能扛 200 QPS生产部署了 3 个实例冗余系数取 1.3那么接口容量大约是 200 × 3 × 1.3 780 QPS。为了保护下游数据库和缓存我会把限流阈值设在容量的 70% 左右也就是 540 QPS。注意这是一瞬间的窗口上限通常还会搭配一个分钟级阈值防止慢速耗尽型请求。比如配置second: 500, minute: 18000超过任何一个都会拒绝。如果是按用户配额那就要从业务上定。下单接口一个正常用户不可能一秒钟下几十单通常按分钟和小时来限制就够了。我常用的配置是业务场景推荐配置匿名 IP 访问普通查询接口minute: 60, hour: 600匿名 IP 访问创建类接口second: 10, minute: 120登录消费者访问下单接口minute: 30内部调用接口second: 500配置时还要注意不要把一个接口的几个窗口都设得太接近。比如second: 100, minute: 120后者明显不合理一分钟 120 次远低于 100 × 60结果这个接口永远只会被分钟窗口限制秒级窗口形同虚设。4.4 全局限流与接口限流叠加的玩法前面说过同名插件在全局和 Route 上是覆盖关系不是叠加。那还需要不需要设置全局限流我的习惯是在全局挂一个很宽松的兜底策略防止某个新接口忘记挂限流插件就暴露出去。比如全局配置minute: 10000这个值对单个接口来说基本不会触发但能防止整个服务被不明流量打爆。然后在核心接口上用 Route 级插件覆盖成更严格的策略。如果你真的希望“接口 A 本身每分钟最多 100 次”和“整个服务每分钟最多 1000 次”两个限制同时生效靠社区版的单个 rate-limiting 插件实现不了。要么升级到企业版用 Rate Limiting Advanced要么自己写一个简单的自定义插件。大多数业务其实只需要做到接口级限流全局兜底那条可以直接省略。5. 集群模式下限流配置的坑与同步策略生产环境基本不会只部署一个 Kong 节点。多节点之后限流的“一致性”就成了最影响实际效果的问题。5.1 多节点共享计数Redis 策略是必须的Kong 的 rate-limiting 插件支持local、redis两种主流策略。local是在每个 Kong 节点的内存里维护计数器性能最好但完全不共享。当负载均衡把同一个客户端 IP 的请求分到不同节点时每个节点都认为是“新用户”实际限流阈值等于节点数乘以配置阈值。所以我建议只要生产环境没有特殊理由一律使用policy: redis。Redis 会存储类似“当前窗口、限流 key、剩余次数”的结构化数据所有 Kong 节点读写同一个 Redis计数才是全局统一的。这里还要考虑 Redis 的单点问题。限流的 Redis 和生产环境的业务 Redis 最好分开部署至少用独立的 DB因为限流操作的读写比较频繁大量INCR和EXPIRE有可能影响业务缓存的延迟。如果条件允许给限流 Redis 配置高可用主从或者 Redis Cluster。5.2 固定窗口和滑动窗口的实际选择固定窗口的优点是实现简单Redis 压力小。但固定窗口有一个明显问题在窗口边界请求量可能瞬间翻倍。比如限流每分钟 60 次第 59 秒来了 60 次第 61 秒又来了 60 次中间只隔了 2 秒实际打到了 120 次。对 Spring Cloud 微服务来说如果保护的上游数据库扛不住这种突发还是要用滑动窗口。滑动窗口在统计时要计算多个子窗口的数据比如按秒切片拿到最近 60 秒内的累计值。Kong 只需要你设置window_type: sliding它会自己处理这些细粒度计数。我在生产环境实际压测中发现同样设置second: 100固定窗口经常测出 200 的瞬时量滑动窗口能控制在 120 以内。所以对核心交易类接口强烈建议开滑动窗口。有一点要注意滑动窗口并不能完全消除瞬时并发它只是让配额分布更均匀。比如很多用户在同一毫秒发起请求始终会有一批请求同时通过。如果想要严格的均匀控制需要配合 Kong 的请求排队或限流器但那是另一个话题了。5.3 老版本里的 cluster 策略和 sync_rate 不要再用了如果你在网上搜 Kong 限流资料会看到老版本资料里经常出现policy: cluster和sync_rate。这是 Kong 2.x 时代用数据库同步计数的方式性能很差而且高并发下数据库会成为瓶颈。Kong 3.x 之后cluster策略已经不再推荐使用社区版的实际正确姿势是policy: redis。所以配置插件时不要照着老博客把cluster抄进去。看到sync_rate这类参数先确认一下你查的是不是企业版或者过时文档。老老实实用 Redis最简单也最稳定。6. 生产环境实战经验与排查手册配置写完才是刚开始。真正上线后你会遇到各种“看起来没生效”的问题。我把我踩过的坑整理成了一份排查顺序按这个顺序走大部分问题都能定位。6.1 限流不生效先看这几个地方很多限流不生效的情况其实是请求根本没命中你挂插件的 Route。比如请求到的是/order/create/但 Route 只配了/order/createKong 默认对末尾斜杠的处理可能和你预期不一样。遇到问题时第一步不是看插件而是看请求走的是哪条 Route。可以通过 Kong 的响应头确认。如果用curl -i请求接口看到类似这样的响应头X-RateLimit-Limit-Minute: 300 X-RateLimit-Remaining-Minute: 297 X-RateLimit-Remaining-Second: 19说明插件已经生效。如果完全没有这些响应头基本可以断定请求没有进入绑定插件的 Route。接着看插件列表curl -s http://127.0.0.1:8001/routes/order-create-route/plugins确认rate-limiting确实挂在该 Route 上而不是挂在别的 Service 上。还要确认config.policy是redis而不是local因为如果你有多个节点local会造成“看起来限流了但总量没限住”的错觉。最后看 Redis 是否连通。限流插件连接 Redis 失败时如果fault_tolerant: true会直接放行这在日志里很容易被忽略。生产环境我把限流 Redis 的监控单独做了告警因为限流存储挂了系统不是拒绝风险反而是失去保护。6.2 限流按 IP 却把所有人都限了大概率是真实 IP 没处理好这是我在生产环境遇到最多的问题。Kong 前面通常还有云负载均衡、CDN 或一层 NginxKong 拿到手的remote_addr实际上是负载均衡的 IP。配置limit_by: ip之后所有用户都被当成同一个 IP共享同一个配额一个用户冲量全站跟着 429。解决办法是让 Kong 信任上游负载均衡并且从X-Forwarded-For里取出真实客户端 IP。Kong 启动时设置KONG_TRUSTED_IPS10.0.0.0/8这里把负载均衡所在网段加进去Kong 才会认X-Forwarded-For头。如果KONG_TRUSTED_IPS配的是0.0.0.0/0等于信任任意来源客户端可以自己伪造X-Forwarded-For来绕过限流这一点必须谨慎。配置好真实 IP 后再用几个不同“伪造 IP”的请求去测限流你会发现每个 IP 都独立计数说明取 IP 的逻辑已经正常。6.3 被限流时的返回码、响应头和前端处理Kong rate-limiting 插件默认在超过配额时返回429 Too Many Requests响应体大概是{message:API rate limit exceeded}同时会带上Retry-After响应头表示多少秒后可以重试。前端如果拿到 429最好直接读取Retry-After做倒计时而不是让用户无脑刷新。对于移动端和浏览器端我建议前端的请求库统一处理 429显示“操作太频繁请稍后再试”并禁止按钮重复提交。后端接口如果被限流也建议在日志里记录限流 key 和窗口信息方便后续分析是不是有人在刷接口。如果你想自定义 429 的响应内容社区版插件比较受限。很多团队会在 Kong 前面再放一层 Nginx 做响应体改写或者用企业版插件。我的建议是先不要把精力放在这上面把状态码、Retry-After、X-RateLimit-Remaining这套标准机制用好前端基本就够用了。6.4 和 Spring Cloud Gateway 并存时的角色分界我现在的项目里外部流量先到 Kong再进 Spring Cloud Gateway最后到 Spring Cloud 微服务。这两个网关职责必须有明确分界否则会出现重复限流、双倍检查、日志混乱的问题。我的划分方式是Kong 负责平台级流量管控包括对外接口的路由、基础认证、IP 黑名单、接口级限流、全局监控Spring Cloud Gateway 负责业务级处理包括服务发现、内部路由、header 改写、业务鉴权、灰度路由。业务服务内部不再做限流除非有基于业务粒度的配额需求比如按订单数量限流这种业务语义放网关层并不合适。这样划分的好处是外部被限流时流量根本不会打到 Spring Cloud 微服务业务服务可以安心处理真实业务。如果你把限流放在 Spring Cloud Gateway 上虽然也能挡住一部分但 Kong 作为更前置的入口挡住恶意流量后才不会白白消耗网关线程。6.5 一套可以直接抄的声明式配置模板最后分享一个我常用的配置模板。如果你希望“配置即代码”可以用 Kong 的声明式配置文件数据库模式用deck工具同步或者干脆跑一个 DB-less 模式。下面是用声明式表达接口级限流的完整示例_format_version: 3.0 services: - name: order-service url: http://spring-gateway:8080 routes: - name: order-create-route paths: - /order/create methods: - POST strip_path: false plugins: - name: rate-limiting config: limit_by: ip policy: redis redis_host: redis redis_port: 6379 redis_database: 0 second: 50 minute: 300 window_type: sliding hide_client_headers: false - name: order-query-route paths: - /order/query methods: - GET strip_path: false plugins: - name: rate-limiting config: limit_by: consumer policy: redis redis_host: redis redis_port: 6379 redis_database: 0 minute: 60 window_type: sliding这套模板的思路很直观创建接口时复制一条 Route调整路径、方法和限流配置提交到 Git再用 deck 同步到 Kong。多环境部署时测试环境可以把阈值调低生产环境按压测结果调高配置本身不会漂移。我在实际部署中还有一个体会接口级限流只是 API 保护的第一层后面最好再配链路跟踪和监控大盘。Kong 返回 429 只是结果真正要关注的是为什么这个接口会被打满是不是上游响应变慢了、是不是有爬虫、是不是某个客户端异常重试。限流配置解决的是“不要让系统挂掉”而监控解决的是“下一次怎么避免被打满”。这两件事一起做Spring Cloud 微服务的稳定性才算是真正兜住。
返回列表