事件推送概述
本页面介绍MISEB系统的事件推送机制。
什么是事件推送
事件推送是MISEB系统内置的事件驱动架构,当系统中发生关键业务事件时,会通过Redis(或Kafka)发布事件消息,并自动调用配置好的Magic API脚本进行处理。
核心优势
- 零代码扩展:通过Magic API配置事件处理逻辑,无需修改系统源码
- 灵活对接:可对接ERP、WMS、CRM等外部系统
- 完整日志:事件处理结果自动记录到Elasticsearch
工作原理
┌─────────────────────────────────────────────────────────────────────────┐
│ MISEB系统内部 │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ 业务操作 │ │ Redis │ │ MagicEventProcessor │ │
│ │ 订单/支付 │ ──→ │ Channel │ ──→ │ 事件处理器 │ │
│ │ 商品/用户 │ │ magic-api: │ │ │ │
│ └─────────────┘ │ event │ └───────────┬─────────────┘ │
│ └─────────────┘ │ │
│ ▼ │
│ ┌─────────────────────────┐ │
│ │ Magic API │ │
│ │ 事件处理脚本 │ │
│ └───────────┬─────────────┘ │
│ │ │
└─────────────────────────────────────────────────────┼───────────────────┘
│
┌─────────────────────────────┼─────────────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ ERP系统 │ │ WMS系统 │ │ CRM系统 │
│ 订单同步 │ │ 库存同步 │ │ 用户同步 │
└──────────────┘ └──────────────┘ └──────────────┘处理流程
- 事件产生:用户下单、支付、发货等操作触发事件
- 事件发布:系统调用
EventPublisher.publish()发布事件到Redis Channel - 事件监听:
MagicRedisEventListener监听并接收事件消息 - 处理器匹配:
MagicEventProcessor查询配置的事件处理器 - 执行脚本:调用对应的Magic API脚本处理事件
- 日志记录:处理结果记录到Elasticsearch
事件数据结构
MisebEvent
java
public class MisebEvent {
private String eventKey; // 事件标识,如 ORDER_PAY_SUCCESS
private Object payload; // 业务数据,通常是订单号或业务对象
private Long timestamp; // 事件发生时间戳
}示例数据
json
{
"eventKey": "ORDER_PAY_SUCCESS",
"payload": "202401010001",
"timestamp": 1704067200000
}适用场景
数据同步
- 订单支付成功后同步到ERP系统
- 库存变更同步到WMS系统
- 用户注册同步到CRM系统
业务扩展
- 订单完成后发放积分
- 支付成功后发送通知
- 用户注册后发放优惠券
监控告警
- 大额订单告警
- 异常退款告警
- 拼团失败通知
配置事件处理器
进入配置页面
菜单路径:系统设置 → 事件处理器
配置项说明
| 配置项 | 说明 |
|---|---|
| 事件标识 | 要监听的事件类型,如 ORDER_PAY_SUCCESS |
| 处理器名称 | 处理器的描述名称 |
| Magic API | 选择要执行的Magic API接口 |
| 执行方式 | 同步执行 / 异步执行 |
| 状态 | 启用 / 禁用 |
配置示例
事件标识: ORDER_PAY_SUCCESS
处理器名称: 订单支付成功-同步ERP
Magic API: /custom/erp/order-sync
执行方式: 异步
状态: 启用Magic API接收事件
在Magic API脚本中,可以通过以下方式获取事件数据:
javascript
// 获取事件对象
var event = payload.event; // MisebEvent对象
var eventKey = event.eventKey; // 事件标识
var data = event.payload; // 业务数据(如订单号)
var timestamp = event.timestamp; // 事件时间戳
// 也可以直接获取payload
var orderNo = payload.payload; // 如果payload是订单号
log.info("收到事件: eventKey={}, data={}", eventKey, data);完整处理示例
javascript
// 接口路径: /custom/erp/order-sync
// 用于处理 ORDER_PAY_SUCCESS 事件
// 1. 获取事件数据
var event = payload.event;
var orderNo = event.payload;
log.info("处理订单支付成功事件: orderNo={}", orderNo);
// 2. 查询订单详情
var order = db.selectOne(`
SELECT o.*, u.phone, u.nickname
FROM eb_store_order o
LEFT JOIN eb_user u ON o.uid = u.uid
WHERE o.order_id = ?
`, orderNo);
if (!order) {
log.error("订单不存在: {}", orderNo);
return { success: false, message: "订单不存在" };
}
// 3. 转换为ERP格式
var erpOrder = {
sourceOrderNo: order.order_id,
sourceSystem: "MISEB",
customerId: "MISEB_" + order.uid,
payAmount: order.pay_price / 100,
payType: order.pay_type,
payTime: order.pay_time
};
// 4. 调用ERP接口
var result = http.post(env.get('ERP_API_URL') + '/order/create', {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + env.get('ERP_API_KEY')
},
body: erpOrder,
timeout: 10000
});
// 5. 处理结果
if (result.code == 0 || result.code == 200) {
log.info("订单同步ERP成功: orderNo={}, erpOrderId={}", orderNo, result.data?.orderId);
return { success: true, erpOrderId: result.data?.orderId };
} else {
log.error("订单同步ERP失败: orderNo={}, error={}", orderNo, result.message);
return { success: false, message: result.message };
}事件日志查询
查看日志
菜单路径:系统监控 → 事件日志
日志字段
| 字段 | 说明 |
|---|---|
| 事件标识 | 事件类型 |
| 消息内容 | 事件的完整JSON数据 |
| 处理器名称 | 执行的处理器 |
| 执行状态 | SUCCESS / FAIL |
| 错误信息 | 失败时的错误详情 |
| 耗时 | 处理耗时(毫秒) |
| 创建时间 | 事件发生时间 |
事件模式配置
MISEB支持两种事件传输模式:
Redis模式(默认)
yaml
# application.yml
miseb:
event:
mode: redis- Redis Channel:
magic-api:event - 适用于单机或小规模集群
Kafka模式
yaml
# application.yml
miseb:
event:
mode: kafka- Kafka Topic:
miseb_global_event - 适用于大规模分布式系统
最佳实践
1. 异步处理耗时操作
对于调用外部API等耗时操作,建议使用异步执行:
执行方式: 异步2. 错误处理
在Magic API中做好异常处理:
javascript
try {
// 业务处理
var result = callExternalAPI(data);
return { success: true, data: result };
} catch (e) {
log.error("处理失败: {}", e.message);
// 抛出异常会记录到日志
throw e;
}3. 幂等设计
部分事件可能重复触发,建议做幂等处理:
javascript
// 检查是否已处理
var exists = db.selectInt(`
SELECT COUNT(*) FROM sync_log
WHERE order_no = ? AND event_key = ?
`, orderNo, eventKey);
if (exists > 0) {
log.info("事件已处理,跳过: orderNo={}", orderNo);
return { success: true, message: "已处理" };
}
// 处理业务...
// 记录处理日志
db.insert(`
INSERT INTO sync_log (order_no, event_key, created_at)
VALUES (?, ?, NOW())
`, orderNo, eventKey);4. 监控告警
定期检查事件处理失败率:
javascript
// 定时任务脚本:检查失败事件
var failCount = db.selectInt(`
SELECT COUNT(*) FROM event_process_log
WHERE status = 'FAIL'
AND create_time > DATE_SUB(NOW(), INTERVAL 1 HOUR)
`);
if (failCount > 10) {
// 发送告警通知
sendAlert("事件处理失败率过高: " + failCount + " 条失败");
}下一步
- 事件类型列表 - 查看所有事件类型
- 订单事件 - 订单相关事件详情
- 事件+Magic-API - 完整实战示例
