1、批量发送概述

批量发送,说白了就是一次把多条消息打包发出去,而不是一条一条地发。我刚开始做后端开发时,总觉得这玩意儿没啥技术含量——不就是循环调用嘛。直到有一次线上事故,让我彻底改变了看法。

那是一个推送营销活动的场景,用户量大概 50 万。同事用了个 for 循环,一条一条调第三方 API。结果呢?跑了 3 个小时还没跑完,中间还超时了十几次。用户收到消息的时间差了一个多小时,投诉电话直接打爆了客服。嗯,从那以后,我再也不敢小看批量发送了。

什么是批量发送

批量发送,就是把多条独立的消息或请求,合并成一次或少数几次操作,统一发送出去。它的核心思想很简单:减少交互次数,提升吞吐量。

举个例子:

// 逐条发送 —— 性能差
for (User user : userList) {
    sendEmail(user.getEmail(), "你好," + user.getName());
}

// 批量发送 —— 性能好
List<EmailRequest> batch = new ArrayList<>();
for (User user : userList) {
    batch.add(new EmailRequest(user.getEmail(), "你好," + user.getName()));
    if (batch.size() >= 100) {
        sendBatchEmail(batch);  // 一次发 100 条
        batch.clear();
    }
}
if (!batch.isEmpty()) {
    sendBatchEmail(batch);
}

你看,代码结构差不多,但性能差距可能是几十倍。为什么会这样?因为每次网络请求都有开销——建立连接、握手、传输、解析。把这些开销平摊到多条消息上,效率自然就上去了。

核心要点:批量发送的本质是用「一次网络开销」承载「多条业务消息」,从而降低单位消息的处理成本。

批量发送的应用场景

说实话,批量发送几乎无处不在。我整理了几个最常见的场景:

场景 典型例子 批量规模
消息推送 App 推送、短信、邮件 几千到几百万
数据同步 ES 批量写入、数据库批量 insert 几百到几万
日志上报 业务日志、监控指标 几十到几千
API 调用 第三方接口批量查询 几十到几百
文件处理 批量生成 PDF、图片压缩 几百到几千

我在做电商系统时,遇到过最典型的场景就是大促后的订单通知。几万笔订单要在 5 分钟内完成短信和邮件发送。如果逐条发,光网络延迟就得十几分钟。用批量发送后,配合线程池,3 分钟就搞定了。

个人经验:批量规模不是越大越好。我见过有人一次塞 10 万条数据到批量请求里,结果内存直接 OOM。建议根据业务场景和系统资源,先压测找到合适的 batch size。

批量发送的核心挑战

批量发送看起来简单,但真正做好并不容易。我总结下来,主要有三大挑战:

性能

性能是批量发送的首要目标,但也是最容易出问题的地方。你想想看:

  • 吞吐量:每秒能处理多少条消息?
  • 延迟:单条消息从提交到发送完成,需要多久?
  • 资源消耗:CPU、内存、网络带宽,会不会被撑爆?

我记得有一次优化短信发送,发现瓶颈不在代码逻辑,而在数据库连接池。批量查询用户信息时,连接池被打满了,其他业务也跟着受影响。后来加了缓存和连接池隔离,才把问题解决。

稳定性

批量发送最怕什么?怕部分失败。一条消息发送失败,要不要重试?重试会不会影响其他消息?

我曾经踩过一个坑:批量发送邮件时,其中一封邮件因为收件人地址格式错误,整个批次都抛异常了。结果那批 500 封邮件,一封都没发出去。用户等了一整天没收到通知,直接投诉到老板那里。

从那以后,我养成了一个习惯:批量操作一定要做「部分失败处理」。要么跳过错误继续发,要么把失败的消息单独捞出来重试。

避坑指南:千万不要把「批量发送」和「事务」混为一谈。批量发送追求的是高吞吐,事务追求的是强一致性。两者目标不同,强行结合往往两头不讨好。

可维护性

这个点容易被忽视,但长期来看最要命。批量发送的代码,如果写得不好,后期维护起来简直想哭。

常见的问题包括:

  • 批量逻辑和业务逻辑耦合在一起,改一处动全身
  • 没有日志和监控,出问题只能靠猜
  • 配置写死在代码里,改个 batch size 都要重新部署

我个人习惯是把批量发送抽象成独立的模块,提供统一的接口。这样业务方只需要关心「发什么」,不需要关心「怎么发」。后面几章我会详细讲这个设计思路。

本章知识体系

下面这张图,帮你快速理清批量发送的核心脉络:

批量发送知识体系 批量发送 性能 稳定性 可维护性 吞吐量 延迟 资源消耗 部分失败 重试机制 幂等性 模块化 监控日志 配置化 核心思路:用「一次网络开销」承载「多条业务消息」,降低单位消息处理成本 三大挑战需要同时兼顾,不能只优化一个而忽略另外两个

从这张图可以看出来,批量发送不是简单的「把多条数据拼在一起发」。它涉及性能、稳定性、可维护性三个维度,每个维度下面又有具体的子问题。后面的章节,我会逐一深入讲解这些内容。