优化回调推送:参考微信/支付宝机制,限制每商户单一回调地址

- 回调重试改为微信式固定退避序列(15s/15s/30s/3m/10m/20m/30m/30m/30m/1h/3h/3h/3h/6h/6h),共 16 次尝试
- 重试次数/推送超时/退避序列可通过环境变量配置(CALLBACK_MAX_ATTEMPTS/CALLBACK_PUSH_TIMEOUT_SECONDS/CALLBACK_RETRY_SCHEDULE)
- 每个商户仅允许 1 个 active 回调订阅,创建前校验,先停用后新建
- 前端回调页提示推送策略与单地址限制
- docker-compose 透传回调相关配置
This commit is contained in:
yml2213
2026-08-03 10:57:21 +08:00
parent 7fe4a05ed7
commit cf2ee96baa
5 changed files with 131 additions and 15 deletions
+30
View File
@@ -40,6 +40,13 @@ type Config struct {
FulfillmentProcessingTimeoutMinutes int
// FulfillmentTimeoutScanIntervalSeconds 发货超时巡检间隔秒数。
FulfillmentTimeoutScanIntervalSeconds int
// CallbackMaxAttempts 回调推送总尝试次数(首次 + 重试),默认 16(微信式)。
CallbackMaxAttempts int
// CallbackPushTimeoutSeconds 单次回调推送 HTTP 超时秒数。
CallbackPushTimeoutSeconds int
// CallbackRetryScheduleSeconds 回调失败重试间隔序列(秒,逗号分隔,微信/支付宝式固定退避)。
// 为空时使用默认微信式序列。
CallbackRetryScheduleSeconds []int
}
// Load 加载配置:先尝试读取 .env,再读系统环境变量(已存在的系统环境变量优先级更高)
@@ -66,9 +73,32 @@ func Load() *Config {
DeliveryLinkTTLMinutes: getEnvInt("DELIVERY_LINK_TTL_MINUTES", 120),
FulfillmentProcessingTimeoutMinutes: getEnvInt("FULFILLMENT_PROCESSING_TIMEOUT_MINUTES", 30),
FulfillmentTimeoutScanIntervalSeconds: getEnvInt("FULFILLMENT_TIMEOUT_SCAN_INTERVAL_SECONDS", 60),
CallbackMaxAttempts: getEnvInt("CALLBACK_MAX_ATTEMPTS", 16),
CallbackPushTimeoutSeconds: getEnvInt("CALLBACK_PUSH_TIMEOUT_SECONDS", 15),
CallbackRetryScheduleSeconds: getEnvIntList("CALLBACK_RETRY_SCHEDULE", nil),
}
}
// getEnvIntList 解析逗号分隔的整数列表(如 "15,15,30,180");空串返回 nil。
func getEnvIntList(key string, def []int) []int {
v := os.Getenv(key)
if v == "" {
return def
}
var out []int
for _, part := range strings.Split(v, ",") {
n, err := strconv.Atoi(strings.TrimSpace(part))
if err != nil || n < 1 {
continue
}
out = append(out, n)
}
if len(out) == 0 {
return def
}
return out
}
func getEnvBool(key string, def bool) bool {
v := os.Getenv(key)
if v == "" {