使用Redis Pub/Sub或List作为订阅管理器,实现Webhook订阅:客户端订阅事件时将URL存入Redis Set,事件触发时遍历Set并异步POST消息,支持高并发推送,提升系统集成。
核心实现步骤
1. 初始化Redis连接池,使用go-redis库连接Redis服务器。2. 创建订阅管理:订阅事件用ZSET存储{event:webhook_url},带TTL过期。3. 事件发布:触发事件时,SPOP或LRANGE获取活跃订阅列表。4. 异步推送:用goroutine并发发送HTTP POST到每个webhook,确保幂等性通过unique_id。
配置Redis
在redis.conf中设置maxmemory 2gb,maxmemory-policy allkeys-lru。启用pubsub模式:CONFIG SET pubsub-client-memory-usage-limit 100。创建key如webhooks:event_type:SET。
实战代码示例
func SubscribeWebhook(event string, url string) { rdb.SAdd(ctx, "webhooks:"+event, url).Result() rdb.Expire(ctx, "webhooks:"+event, 24*time.Hour) } func PublishEvent(event string, payload interface{}) { urls := rdb.SMembers(ctx, "webhooks:"+event).Val() for _, url := range urls { go sendWebhook(url, payload) } }
高效推送优化
使用Redis Pipeline批量操作订阅,避免单键热点。集成Sentinel高可用,Lua脚本原子化发布:EVAL "redis.call('SMEMBERS', KEYS[1]); redis.call('DEL', KEYS[1])" 1 webhooks:event。监控:INFO keyspace获取订阅数,SLOWLOG排查延迟。
错误处理与重试
推送失败时存入Redis List retry_queue,重试机制:BLPOP + exponential backoff,最多3次后移至dead_queue。幂等:每个消息带id,webhook端查Redis EXISTS检查。
FAQ
Q: Redis Pub/Sub和SET订阅哪个更好? A: SET适合持久订阅和TTL管理,Pub/Sub适合实时广播但不持久,选择SET更可靠。
Q: 如何处理海量订阅推送性能? A: 分片KEY如webhooks:event:shard1,结合worker pool并发推送,单机支持10w+ QPS。
Q: Webhook安全怎么保障? A: 签名验证HMAC-SHA256,HTTPS强制,Redis ACL限制访问。