你按每百万次请求四十美分来编制消息服务的预算,结果 AWS 账单来了,比你根据消息数量推算的金额高出三倍。罪魁祸首不是涨价,而是 64 KB 分块规则:AWS 不按逻辑消息计费,而是对每次触及该消息的 API 调用按每个 64 KB 负载块计费。一条 200 KB 的订单事件,你发送时算四次可计费请求,工作进程接收时再算四次,工作进程删除时又算四次。一条消息产生十二次计费,这还没算上 SNS 扇出再次放大的部分。
这篇文章解释 SQS 和 SNS 实际如何计算请求、在真实业务量下成本是多少、为什么生产环境的消消息服务属于销货成本而不是间接费用,以及如何记账才能让毛利率讲出真相。
SQS 如何把一条消息变成多次可计费请求
SQS 的定价看起来简单得令人放松警惕:Standard 队列约每百万次请求四十美分,FIFO 队列约每百万次五十美分,每月前一百万次 Standard 请求免费。复杂之处藏在"请求"的定义里。
每个 64 KB 块都算一次请求
负载中每一个已开始的 64 KB 块都各自算作一次请求。30 KB 的消息算一次请求。64 KB 的消息算一次请求。65 KB 的消息算两次。200 KB 的消息算四次,256 KB 的消息算四次,1 MB 的负载算十六次。
最后这个数字比过去更重要了。2025 年 8 月,AWS 将 Standard 和 FIFO 队列的 SQS 最大消息大小从 256 KB 提高到 1 MB。这点余量偶尔用于大事件很方便,但任何超过 64 KB 的负载在每次被触及的时候都要承担分块乘数。一个团队把平均负载从 50 KB 提高到 200 KB,即使一条消息都没多发,SQS 请求数也会变成四倍。
每个 API 操作单独计数
对队列的每个 API 操作都是一次请求,分块乘数对每一次操作都适用。发送、接收、删除和修改消息可见性,各自独立计量。
走一遍 Standard 队列上一条 200 KB 消息的完整生命周期。发送是四次可计费请求。工作进程的接收再算四次。处理成功后删除又是四次。一条逻辑消息,十二次可计费请求,按标价约每千次半美分。同样生命周期对一条 30 KB 的消息只算三次请求。在大多数 SQS 账单里,负载大小才是主导变量,而不是消息数量。
还有两个计量项会让第一次运营的人吃惊。空接收也要计费:每次未返回消息的轮询仍算一次请求,所以在空闲队列上激进地短轮询,就是在白白烧钱。而 FIFO 队列在每个量级上都比 Standard 贵约 25%,当分块乘数已经在跟你作对时,这笔费用涨得很快。只在确实需要顺序和精确一次处理的地方用 FIFO,其他地方都用 Standard。
SNS 如何再放大一次
SNS 增加了第二个计费维度,因为发布的消息在到达时计量一次,在每次投递时再计量一次。
发布和投递是独立的计量项
向主题发布约每百万次请求五十美分,同样按块计费:一次 256 KB 的发布算四次。随后,对每个订阅者的每次投递也按每 64 KB 块计量,费率取决于投递协议。
并非所有投递成本都一样。投递到 SQS 队列、Lambda 函数和 Firehose 流不收取投递费,这使得 SNS 到 SQS 的扇出在投递侧几乎免费。HTTP 和 HTTPS 投递、电子邮件和移动推送都要计量,SMS 则按每个消息段单独定价。因此,一条 256 KB 的事件扇出到三个 SQS 队列和一个 HTTP webhook,成本为四次发布请求、三个 SQS 投递零费用,以及四次 HTTP 投递。把这条事件缩小到 64 KB 以下,同样的扇出成本是一次发布加一次 HTTP 投递。
SNS 在 2026 年 9 月跟随 SQS 支持更大负载,通过主题级最大大小设置允许 1 MB 的消息。配置超过 256 KB 的主题只能投递到 SQS、Lambda 和 Firehose,且最多一百个订阅。这个限制暗示了预期模式:大事件应放在以队列为后端的管道中,而不是广播到所有协议。
为什么扇出仍然更划算
投递计量会诱使团队跳过 SNS,直接给每个消费者发送重复的 SQS 消息。别这么做。重复发送会放大整个周期中最贵的部分,即每个消费者的发送加接收加删除,而 SNS 到 SQS 的扇出只需为每个订阅者支付一次发布且无 SQS 投递费。当多个消费者需要同一事件时,扇出既是更清晰的架构,也是更便宜的账单。
真实业务量下的成本
标价是按百万计的数字,只有乘开才有意义,所以这里给出三种真实场景。
一个副业项目每月通过一个 Standard 队列发送 200 万条小消息,几乎不花钱。每条 64 KB 以下的消息花费一次发送、一次接收和一次删除,共 600 万次请求。前一百万次免费,剩下 500 万次按每百万四十美分算:约两美元。
一个中型 SaaS 平台每月向一个 Standard 主题发布 500 万条 10 KB 的通知,有 3 个 SQS 订阅者加 1 个 HTTP webhook,SNS 那一侧的花费只有个位数。发布约两美元五十美分。三个 SQS 投递免费。HTTP 投递按每十万次六美分算约三美元。下游 SQS API 操作大约让总额翻倍,整个通知管道每月不到十五美元。这是消息服务确实可以忽略不计的场景。
现在把这个 SaaS 工作量换成 200 KB 的负载,因为每条事件都嵌入了完整订单文档。每个计量项都变成四倍。发布跳到十美元,HTTP 投递到十二美元,下游 SQS 的接收和删除也变成四倍。管道每月接近六十美元,绝对值仍然很小,但是同样工作量用精简事件时成本的近四倍,而且随着业务量增长,差距会复合放大。在每月五亿次分块请求时,精简事件和臃肿事件之间的差别就是一笔四位数的年度开支。
存在量级阶梯,但对小企业很少有意义:Standard 请求在每月超过 1000 亿和 2000 亿次时降价。你现实中能撬动的杠杆不是量级,而是平均分块系数。
为什么生产消息服务是可变销货成本,而非间接费用
把你产品交付给付费客户的消息服务是直接收入成本。它随用量增长,没有销售时它就消失,投资者期望看到它和生产的计算、数据库、存储、带宽一起列在毛利率线之上。
会计准则在这里留有空间:公认原则没有精确定义销货成本,SaaS 毛利率实践用直接成本检验来填补空白。问一问这笔支出是否是为了在生产环境中服务客户。承载订单事件的生产队列、扇出到面向客户工作进程的通知主题,以及投递到客户端点的 webhook,都通过检验。预发布队列、负载测试主题、开发者沙盒订阅,以及正在排空上季度负载测试数据的死信队列,则不通过。那些属于研发或一般间接费用。
生产边界就是全部关键。一张 AWS 账单把所有队列和主题混在一起,所以要给生产资源打标签并每月拆分发票。跳过拆分的团队通常朝着对自己有利的方向犯错,把基础设施埋进间接费用,报告一个单位经济学根本站不住脚的毛利率。尽职调查审查会在一个下午就把它重新分类,而重述后的毛利率从来不会更高。
按你实际支付的净额记账。免费额度是账单折扣,不是收入,所以没有需要总额还原的东西。如果你想了解免费额度吸收了多少工作量,在指标中单独跟踪可计费请求,让账务分录保持现金成本。
如何记账才能让毛利率讲出真相
给消息服务一个自己的销货成本科目,而不是混进一个通用的云或软件科目。用一个专门的科目,比如云消息服务,你可以用当月支出除以当月可计费请求,看到你真正的每分块请求成本,这个数字告诉你负载增长是否在侵蚀毛利率。
AWS 扣款在月末之后才结算,所以要计提。月末结账时根据请求指标估算消息服务部分,发票到了再做调整,并让沙盒部分留在销货成本之外。下面是一个完整周期,这个月生产消息服务花了十八美元四十美分,沙盒增加了两美元十美分:
2026-01-01 open Assets:Cash:Operating USD
2026-01-01 open Expenses:CostOfSales:Cloud-Messaging USD
2026-01-01 open Expenses:Research:Cloud-Sandbox USD
2026-01-01 open Liabilities:Accrued:AWS USD
2026-01-31 * "AWS" "January SQS prod 8.2M chunked requests plus SNS publishes and HTTP deliveries"
Expenses:CostOfSales:Cloud-Messaging 18.40 USD
Liabilities:Accrued:AWS -18.40 USD
2026-02-03 * "AWS" "January AWS charge settles, prod messaging plus 2.10 sandbox"
Liabilities:Accrued:AWS 18.40 USD
Expenses:Research:Cloud-Sandbox 2.10 USD
Assets:Cash:Operating -20.50 USD至少每月将计提金额与按服务和用量类型分组的成本浏览器核对一次。SQS 和 SNS 应显示为单独的行,这样其中一个的激增就不会藏在另一个平稳趋势里。如果你用纯文本记账,文档中的成本跟踪模式可以自然地扩展到按服务的消息服务拆分。
一个要避免的分类陷阱:FIFO 溢价和延长保留存储仍然是消息服务成本,但超出你真实重驱动窗口的延长保留是存储选择,不是投递成本。要么缩短保留期,要么把存储部分移到它该在的地方,而不是让一个十四天的保留策略悄悄抬高销货成本。
通常能把账单削减 30% 到 50% 的五项控制
从长轮询和批处理开始。它们合起来通常能把 SQS 支出削减近一半,而且一个下午就能实现。
1. 在所有地方开启长轮询
把每个队列的接收等待时间设为二十秒。工作进程会保持连接打开,而不是猛打空轮询,这能大幅压缩主导空闲队列账单的空接收行,并平滑消费者的 CPU 峰值。
2. 批处理每一个允许批处理的 API 调用
发送、接收和删除都支持最多十条消息的批次。每次调用处理一条消息的工作进程,其请求数是每次排空十条的工作进程的十倍。批量删除是最常被遗漏的:认真批处理发送的团队经常一条一条地删除。
3. 给负载瘦身
让每条事件保持在一个 64 KB 块以内。把完整文档存在对象存储中,发送一个带消费者所需标识符的引用,即认领检查模式。在引用不实用时压缩,并从热路径中剥离内嵌的二进制块、重复的客户记录和冗长的调试上下文。你每移除一个块,这个节省会在发送、接收、删除、发布和投递中成倍放大。
4. 在主题层过滤
附加过滤策略,让每个订阅者只收到它处理的事件。未过滤的扇出会为消费者到达即丢弃的消息支付投递和下游处理费用。这完全是浪费,而每个订阅只需改一行就能解决。
5. 只在顺序真正重要时才用 FIFO
审计哪些队列真正需要顺序和去重。FIFO 的溢价适用于队列上的每次分块请求,所以一个承载无人关心顺序的事件的 FIFO 队列就是一笔常驻的 25% 附加费。审计时,设置短保留期并用死信队列处理失败,而不是让毒消息重试成大量请求数。
监控两个能预测账单的指标:大致发送消息数和空接收数。当空接收超过总接收的一小部分时告警,并每季度审查每个队列的平均负载大小。负载增长是渐进的,逐月容易忽略,但逐年看足够显著。
消息服务成本的月末检查清单
每个月用同样的方式闭环,让数字保持可信:
- 从账单明细中拉取 SQS 和 SNS 的分块请求数,而不是从应用日志中取逻辑消息数。
- 用每个服务的支出除以其分块请求数,得到真实单位成本,并与四十和五十美分的标价基准比较。
- 用可计费请求除以逻辑消息,计算每个队列的平均分块系数;任何超过 1.2 的都值得做负载审查。
- 使用资源标签拆分生产与预发布和沙盒支出,确认只有生产部分进入了销货成本。
- 将上个月的计提调整到已结算发票,并把差异结转进你的估算。
- 检查空接收占总接收的比例,确认任何基础设施变更后长轮询仍然开启。
- 确认当月创建的每个新队列和主题都继承了生产标签和过滤策略。
今天就从事你的账单控制台拉取本月的 SQS 和 SNS 行,计算平均分块系数。如果它高于 1.2,你最便宜的那个毛利率胜利是更小的负载,而不是更大的套餐。





