代购系统的可扩展通知机制:从硬编码到观察者模式,借鉴taocarts的事件总线

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: 本文分享代购系统通知模块的演进之路:从硬编码通知到基于Spring事件总线的解耦设计。通过抽象订单事件、注解式监听器、异步执行与Webhook动态订阅,实现高可扩展、易维护的通知体系,彻底告别“改一处崩全局”的困境。

三年前我写第一个代购系统的时候,所有的邮件、短信、站内信都直接写在业务逻辑里。后来运营要增加钉钉机器人通知,我改代码改到吐。再后来要加 Webhook 推送给第三方仓库系统,更是痛苦。直到我研究了 taocarts 的事件总线设计,用观察者模式彻底重构了通知模块,才终于解脱。

一、代购系统有哪些通知需求?
一套完整的反向海淘平台需要通知的场景非常多:

用户下单后,通知采购员(钉钉/飞书)

淘宝卖家发货后,通知用户(邮件 + 站内信)

包裹到达代购转运仓,提醒用户合箱(短信)

国际集运出库后,推送轨迹给用户的微信

财务需要订阅所有订单状态变更(Webhook 到内部对账系统)

如果用 if (status == 3) sendEmail() 这种方式,三个月后代码就没人敢动了。

二、taocarts的事件驱动设计
taocarts 实现了一个轻量级的 EventDispatcher,支持多个监听器订阅同一个事件。我把它翻译成了 Java 版本(我们主栈是 Spring):

首先定义一个事件抽象类:
```public abstract class OrderEvent extends ApplicationEvent {
private final Long orderId;
private final OrderState newState;

public OrderEvent(Object source, Long orderId, OrderState newState) {
    super(source);
    this.orderId = orderId;
    this.newState = newState;
}
// getters

}


具体事件:OrderShippedEvent, ParcelArrivedEvent, ConsolidationCompletedEvent 等。

然后定义监听器接口(注解式):
```@Component
public class EmailNotifier {
    @EventListener
    public void handleOrderShipped(OrderShippedEvent event) {
        Order order = orderService.getById(event.getOrderId());
        String subject = "您的订单已从淘宝发货";
        String body = buildEmailContent(order);
        emailClient.send(order.getUserEmail(), subject, body);
    }
}

钉钉通知:

public class DingTalkNotifier {
    @EventListener
    public void handleParcelArrived(ParcelArrivedEvent event) {
        String message = String.format("包裹 %s 已到达集运仓,请及时处理", event.getTrackingNo());
        dingTalkClient.sendToGroup(message);
    }
}

Webhook 给第三方系统(比如代购集运的WMS):

public class WebhookNotifier {
    @EventListener
    public void onOrderStatusChanged(OrderStatusChangedEvent event) {
        // 遍历所有已注册的webhook url
        List<String> urls = webhookRepo.findByEventType(event.getNewState().name());
        for (String url : urls) {
            restTemplate.postForEntity(url, event, Void.class);
        }
    }
}

三、异步化防止影响主流程
默认情况下 Spring 的 @EventListener 是同步的,如果钉钉接口超时,用户下单也会慢。我们改用 @Async:

@EnableAsync
public class AsyncConfig {
    @Bean(name = "notificationExecutor")
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(200);
        executor.setThreadNamePrefix("notify-");
        executor.initialize();
        return executor;
    }
}

@Component
public class DingTalkNotifier {
    @Async("notificationExecutor")
    @EventListener
    public void handleParcelArrived(ParcelArrivedEvent event) {
        // 异步发送,不阻塞主流程
    }
}

四、与taocarts的区别
taocarts 的事件系统没有提供异步选项,所有的监听器顺序执行。如果某个监听器抛出异常,后续监听器就不会执行。我在生产环境遇到过因为邮件服务器超时导致整个订单保存失败的问题。所以后来我们做了两个改进:

所有通知类监听器都用 @Async

关键业务监听器(比如库存扣减)用同步,并且放在事务提交后执行(@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT))

五、扩展:让用户自己配置 Webhook
跨境独立站的商家经常需要把自己的系统和我们代购系统对接。我们开发了一个 Webhook 管理界面,允许商家填写 URL 和订阅的事件类型(比如 order.paid, order.shipped)。

存储结构:
``CREATE TABLEwebhook_subscriptions(idint,merchant_idint,event_namevarchar(64),target_urlvarchar(255),secret` varchar(64) -- 用于签名验证
);


触发时用 HMAC-SHA256 签名:
```String payload = objectMapper.writeValueAsString(event);
String signature = HmacUtils.hmacSha256Hex(secret, payload);
httpHeaders.set("X-Signature", signature);

这套机制上线后,有三家海外物流公司通过 Webhook 接入了我们的国际集运轨迹推送,完全不需要我们改代码。

六、总结
观察者模式 + 事件总线 是代购源码必备的扩展能力。taocarts 给了我们一个很好的起点,但生产环境还需要考虑异步、重试、死信队列。我个人建议,如果你的系统监听器超过 5 个,就赶紧重构,否则后面全是坑。

相关文章
|
9天前
|
人工智能 开发工具 iOS开发
Claude Code 新手完全上手指南:安装、国产模型配置与常用命令全解
Claude Code 是一款运行在终端环境中的 AI 编程助手,能够直接在命令行中完成代码生成、项目分析、文件修改、命令执行、Git 管理等开发全流程工作。它最大的特点是**任务驱动、终端原生、轻量高效、多模型兼容**,无需图形界面、不依赖 IDE 插件,能够深度融入开发者日常工作流。
3137 8
|
12天前
|
Shell API 开发工具
Claude Code 快速上手指南(新手友好版)
AI编程工具卷疯啦!Claude Code凭借任务驱动+终端原生的特性,成了开发者的效率搭子。本文从安装、登录、切换国产模型到常用命令,手把手带新手快速上手,全程避坑,30分钟独立用起来。
3199 20
|
5天前
|
人工智能 Linux BI
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
JeecgBoot AI专题研究 一键脚本:Claude Code + JeecgBoot Skills + DeepSeek 全平台接入 一行命令装好 Claude Code + JeecgBoot Skills + DeepSeek 接入,无需翻墙使用 Claude Code,支持 Wind
2131 3
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
|
24天前
|
人工智能 JSON 供应链
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
LucianaiB分享零成本畅用JVS Claw教程(学生认证享7个月使用权),并开源GeoMind项目——将JVS改造为科研与产业地理情报可视化AI助手,支持飞书文档解析、地理编码与腾讯地图可视化,助力产业关系图谱构建。
23591 15
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
|
1天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队版、Coding Plan或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
|
11天前
|
人工智能 JSON BI
DeepSeek V4-Pro 接入 Claude Code 完全实战:体验、测试与关键避坑指南
Claude Code 作为当前主流的 AI 编程辅助工具,凭借强大的代码理解、工程执行与自动化能力深受开发者喜爱,但原生模型的使用成本相对较高。为了在保持能力的同时进一步降低开销,不少开发者开始寻找兼容度高、价格更友好的替代模型。DeepSeek V4 系列的发布带来了新的选择,该系列包含 V4-Pro 与 V4-Flash 两款模型,并提供了与 Anthropic 完全兼容的 API 接口,理论上只需简单修改配置,即可让 Claude Code 无缝切换为 DeepSeek 引擎。
2647 3
|
3天前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全+三种模式+记忆体系+实战工作流完整手册
Claude Code 是当前最流行的终端级 AI 编程助手,能够直接在命令行中完成代码生成、项目理解、文件修改、命令执行、错误修复等全流程开发工作。它不依赖图形界面、不占用额外资源,却能深度理解项目结构,自动生成规范代码,大幅提升研发效率。
772 2
|
10天前
|
人工智能 安全 开发工具
Claude Code 官方工作原理与使用指南
Claude Code 不是传统代码补全工具,而是 Anthropic 推出的终端 AI 代理,具备代理循环、双驱动架构(模型+工具)、全局项目感知、6 种权限模式等核心能力,本文基于官方文档系统解析其工作原理与高效使用技巧。
1444 0