Go语言使用robfig/cron定时发推送每次收到2条通知如何解决
触发两次推送的常见原因
1. 多实例重复执行
你将定时任务耦合在REST API服务中,如果AWS部署时为了高可用开了多个服务实例(比如ECS多副本、K8s多Pod),每个实例都会独立启动一个cron进程,定时时间到了之后两个实例会同时执行推送逻辑,自然会发出两条推送,这是这类问题最常见的诱因。
2. SNS消息配置问题
查看你NotifyTopic里的消息构造逻辑:
msg.APNS = string(b) msg.APNSSandbox = string(b)
你同时给APNS生产和沙箱两个字段赋值了相同的推送内容,如果你的SNS主题同时绑定了APNS生产和沙箱应用,同一个测试设备如果同时在两个环境注册过端,就会收到两条推送。
3. 数据查询重复
你的SQL查询用了join hive,如果hive表中同一个hive_id存在重复的有效数据,或者post表有重复记录,会导致查询出来的posts数组里存在重复的hive_id,循环推送时就会给同一个主题发两次通知。
4. 本地开发多进程残留
如果是本地测试时出现该问题,大概率是热重载工具(比如air)没有完全杀死旧进程,新旧两个进程同时运行,各执行了一次定时任务。
对应解决方案
针对多实例问题
- 方案一:将定时任务从API服务中拆分出来,单独作为一个单实例的定时任务服务部署,避免多副本重复执行。
- 方案二:增加分布式锁,定时任务触发时先抢分布式锁(比如用Redis实现),只有抢到锁的实例才执行后续推送逻辑,没抢到的直接跳过本次执行。
针对SNS配置问题
根据当前运行环境动态赋值字段,生产环境仅填充APNS,非生产环境仅填充APNSSandbox,不要同时赋值两个字段:
if cfg.Env == config.Production { msg.APNS = string(b) } else { msg.APNSSandbox = string(b) }
针对查询重复问题
在定时任务的查询逻辑后加日志打印posts数组的长度和每个元素的hive_id,确认是否有重复数据,如果有则优化SQL,增加distinct或者调整查询条件去重。
针对本地多进程问题
测试前先检查并杀死所有运行中的API服务进程,再重新启动服务即可。
内容的提问来源于stack exchange,提问作者Mia Mia
相关产品推荐
相关产品推荐

