Java中如何实现网络连接恢复后自动发送通知邮件
离线场景告警邮件发送的落地实现方案
首先推荐你采用第一种思路为核心实现,相比另外两种方案容错性更高、资源消耗更低:
- 死循环检测会无意义占用CPU资源,即便加了休眠间隔,也会阻塞单线程下的其他业务逻辑,可用性极差
- 独立常驻线程检测连通性,除了长期占用线程资源外,还存在时序漏洞:可能检测时网络正常,真正执行发送的瞬间网络又断开,最终还是要处理发送失败的兜底逻辑
具体实现步骤
1. 实现邮件暂存机制
根据你的业务容忍度选择存储介质:
- 允许程序重启后丢失未发送邮件:直接用内存队列暂存即可
- 需要保证未发送邮件不丢失:用本地SQLite数据库、本地json文件存储
暂存的邮件需要包含以下字段:收件人列表、邮件主题、邮件正文、附件路径(如果有)、首次生成时间、已重试次数
同时要配置最大重试规则:比如最多重试7天,每天最多重试3次,超过阈值的邮件直接标记为发送失败,不再重试避免无效资源占用。
2. 封装邮件发送逻辑
把邮件发送逻辑单独封装,内置失败分支处理:
- 发送成功:直接返回成功状态
- 发送失败且错误为网络连接超时、DNS解析失败、Socket连接异常等网络相关报错:将邮件写入暂存池
- 发送失败且错误为收件人地址无效、SMTP鉴权失败等业务类报错:直接标记为发送失败,不需要进入重试队列
3. 实现轻量重试触发逻辑
不需要单独做网络连通性检测,直接用两种触发逻辑配合完成重试:
- 事件触发:和你现有的下载任务逻辑绑定,每次执行文件下载操作前(这个时候本身已经要发起网络请求,天然能验证网络是否连通),就拉取所有暂存的待发送邮件执行发送,发送成功的就从暂存池删除
- 定时兜底:如果你的下载任务间隔可能超过1小时,可以额外加一个定时任务,每30分钟触发一次暂存邮件重试,覆盖长时间没有下载任务的场景
简易伪代码参考(Python)
# 自定义网络相关异常类 NETWORK_ERRORS = (ConnectTimeout, DNSResolveError, SocketError) def send_alert_mail(receiver: str, subject: str, content: str) -> bool: try: # 实际SMTP发送逻辑 smtp_client.sendmail(from_addr, receiver, f"Subject: {subject}\n\n{content}") return True except NETWORK_ERRORS as e: # 网络异常,存入暂存队列 save_pending_mail(receiver, subject, content) return False except (InvalidAddressError, SMTPAuthenticationError) as e: # 业务异常,直接记录日志返回失败 logger.error(f"邮件发送业务错误: {str(e)}") return False # 下载任务前置钩子,每次下载前调用 def pre_download_hook(): pending_mails = query_all_pending_mails() for mail in pending_mails: if send_alert_mail(mail.receiver, mail.subject, mail.content): delete_pending_mail(mail.id)
提示:如果你的项目已经接入了本地消息队列,也可以直接把待发送邮件丢进消息队列,配置失败自动重试规则即可,不用自己实现暂存和重试逻辑。
内容的提问来源于stack exchange,提问作者Abdurrahman Anas
相关产品推荐
相关产品推荐

