FunctionGraph 并发扩容打爆 RDS 连接数:先算连接数,再谈扩容
FunctionGraph 做 API 后端,并发一扩,RDS 连接数先被打满,函数反而开始报错。这是我自己真实踩过的一例,当时那篇论坛回答还被提问者采纳了。下面把这例拆开讲:现象长什么样、连接数这笔账怎么算、处理按什么顺序来。
1. 现象:报错在函数这边,病根在 RDS 那边
场景是 FunctionGraph 做后端直连 RDS。流量一突发,函数并发实例数上去,RDS 连接数跟着上去,RDS 的 max_connections 先到顶,函数拿不到连接就报错。
最容易误判的地方是:只看函数日志,看到的全是连接失败,会以为是函数本身或网络出了问题;去看 RDS 才会看到连接数已经打满。两边要一起看,单看一边定位不到。
2. 连接数这笔账:并发实例数 × 单实例池大小
机制不复杂,但要把数算出来。函数并发扩容时,每个实例都可能新建数据库连接,连接数大约等于并发实例数乘以每个实例的连接池大小。
举个算账的例子:假设函数并发上限是 100,每个实例的连接池默认开到 10,那连接数峰值就是 100 × 10 = 1000。如果 RDS 的 max_connections 只有 500,流量一突发,实例数还没扩满,连接数先到顶了。函数扩得越快,死得越快。
所以上量之前要先算这笔账:并发上限 × 单实例池大小,对照 RDS 的 max_connections,留出余量。没算过这笔账就上量,等于没看油表就上高速。
3. 处理顺序:四步,按顺序来
这四步不要调换顺序,每一步都是下一步的前提:
- 先限制函数并发上限,把扩容速度压住,别让它无限扩。这是止血,先让连接数不再往上冲。
- 把每个实例的连接池调小,连接数按“并发上限 × 单实例池大小”重新算一遍,对照 RDS 的 max_connections,算到余量够了为止。
- 突发流量改异步削峰:函数只负责接请求、写消息队列,后面再慢慢消费,别让函数直连 RDS 去扛尖峰。尖峰过去了,连接数自然下来。
- 再看是不是该把这条链路换形态:持续高并发的核心链路,本来就不适合用函数直连 RDS,ECS 或 CCE 加连接池更可控。函数适合的是触发离散、单次执行短、突发多的场景,不是常驻高并发。
4. 选型之前,先过四问
上面这例其实也是选型问题。决定用不用 FunctionGraph 之前,先答四个问题,每条只答是或不是:
| 问题 | 答“是”说明什么 |
|---|---|
| 触发是否离散(事件来了才跑,平时没流量) | 是,适合;不是,常驻服务更合适 |
| 单次执行能不能在超时内完成 | 能,适合;不能,要拆任务或换形态 |
| 是否需要进程内常驻状态(内存缓存、本地磁盘、长连接) | 不需要,适合;需要,不适合 |
| 流量波动是否大、突发是否多 | 是,适合;一直平稳高并发,算算账再定 |
四个都满足,FunctionGraph 通常合适;有一个不满足,就要再看。超时那条要先看数字:有回复说默认 3 秒、可配到 900 秒,单次执行超过上限的长任务必须拆,不要硬塞。
不适合的清单都是一样的:长任务超超时上限、常驻内存缓存或本地磁盘状态、WebSocket 长连接、延迟极其敏感且持续高并发的核心链路、毫秒级稳定低延迟在线推理、超大内存或长时间运行、大批量离线 ETL,替代方案是 ECS、CCE 或容器、专门的批处理服务。
5. 还有一层容易漏掉:VPC
函数要访问 VPC 里的 RDS,就要走 VPC 这一层,函数和数据库要在同一个 VPC、安全组要放行,函数这一侧也要配好 VPC 访问。只看触发器和超时,是看不出这层问题的。
我要先说清楚边界:这一节是我根据上面那例 RDS 问题的推断,不是官方文档原文,具体配置项以官方文档为准。
- 函数进 VPC 之后,冷启动会更重,初始化(建连接、加载模型)要放在函数初始化阶段,别放在每次请求里。
- 如果函数还要访问公网(比如调第三方接口),进 VPC 之后要另外看出口怎么走,不要默认进 VPC 就什么都能通。
所以选型时除了四问表,还要多问一句:后端在不在 VPC 里?在的话,先把 VPC、安全组、连接数这三项一起核对,再决定函数放不放这里。
6. 落地顺序:先试点,再推广
- 先从一个非核心的定时或事件任务试点,比如每天凌晨跑报表、清理过期文件。
- 跑通监控、日志、超时和重试,再看冷启动和并发。
- 上 RDS 之前,先按第 3 节把连接数算好,限制并发上限,配好连接池。
- 跑稳了再推广到更多场景,不要一上来就把核心链路迁过来。
配置和密钥放环境变量或凭据管理里,不要写死在代码里;一个函数只做一件事,方便单独排障。超时后平台可能重试,非幂等的操作(写库、发通知)要先做幂等,比如用对象名加时间戳做唯一键,重复触发时直接跳过。
不确定的地方,直接说清楚
- 超时默认 3 秒、可配到 900 秒这个数值是论坛其他回复给的,我没有去官方文档逐字核对过,以官方文档为准。
- VPC 这一节是根据我上面那例 RDS 问题的推断,不是官方文档原文,具体配置项以官方文档为准。
- 连接数“并发实例数 × 单实例池大小”是个估算,实际情况里连接复用、空闲回收都会让真实数字有出入,估算要按峰值留余量,不能按平均值算。
- 点赞
- 收藏
- 关注作者
评论(0)