# 数据质量告警结果发送邮件功能(内网 SMTP)无法送达问题排查指南
# 核心问题表象
数据质量告警已成功生成,但指定收件人始终未收到邮件。
# 排查目标
快速定位邮件未送达原因,并恢复告警通知能力。
# 排查思路与操作步骤
# 第一步:测试内网同域名邮箱互发(排除外域投递限制)
# 目的
确认 SMTP 服务是否正常运行,同时排除内网 SMTP 服务禁止跨域投递的可能性,缩小问题排查范围。
# 操作
将告警邮件的收件人临时修改为与发件人相同域名的内网邮箱(例如发件人为 a@company.com,则收件人改为 b@company.com),重新触发数据质量告警,观察收件人邮箱是否能收到邮件。
# 结论
✅ 能收到:说明 SMTP 服务运行正常,未送达问题大概率是 SMTP 服务禁止跨域发送,或目标外部域名邮箱存在拦截策略。
❌ 仍收不到:说明 SMTP 服务本身、网络连通性或基础配置存在问题,进入第二步排查。
# 第二步:检查收件人端状态(垃圾箱、白名单、账号异常)
# 目的
排除邮件被收件人邮箱过滤、拦截,或收件人账号自身异常导致的未送达问题,避免遗漏客户端层面的常见原因。
# 操作
让收件人登录其内网邮箱 Web 端,重点检查垃圾邮件/垃圾箱文件夹,确认告警邮件是否被误判为垃圾邮件;
指导收件人将告警发件人邮箱(即配置文件中 spring.mail.username 的配置值)加入邮箱联系人或白名单,避免后续邮件被拦截;
确认收件人账号状态正常,检查账号是否被禁用、邮箱容量是否已满、是否存在退信记录等异常情况。
# 结论
✅ 找到邮件/配置后正常接收:问题已解决,后续需确保发件人始终在收件人白名单中,避免再次被拦截。
❌ 未找到邮件且账号正常:说明问题不在收件人端,需排查服务器端、网络或 SMTP 配置,进入第三步排查。
❌ 账号异常(禁用/满容/退信):需收件人联系邮箱管理员恢复账号状态,修复后重新测试邮件送达情况。
备注:部分内网邮件系统会将程序自动发送的邮件判定为垃圾邮件,优先检查垃圾箱是关键操作。
# 第三步:验证 executor 所在服务器与 SMTP 服务器的网络连通性
# 目的
确认 executor 所在服务器与内网 SMTP 服务器之间网络连通正常,排除防火墙拦截、网段隔离、端口未开放等网络层面问题。
# 操作
前提:先确认操作所用的 SMTP IP 和端口,与 application.properties 配置文件中一致(例如 192.168.0.10:25)。
测试 IP 层连通性:在 executor 所在服务器执行 bash 命令
ping 192.168.0.10,观察是否能正常 ping 通;测试 SMTP 端口(25)可达性:在 executor 所在服务器执行 bash 命令
telnet 192.168.0.10 25或nc -zv 192.168.0.10 25,观察端口是否可达。
容器化部署补充:若 executor 运行在 Docker/K8s 中,需额外确认容器网络无 NetworkPolicy 限制,桥接模式正常,确保容器能访问外部 25 端口。
# 结论
✅ IP 能 ping 通且端口可达:网络连通性正常,进入第四步排查 SMTP 配置问题。
❌ IP 无法 ping 通:联系运维确认两台服务器是否在同一内网网段,是否存在防火墙隔离,协调运维打通网段连通性。
❌ 端口拒绝连接/超时:联系运维开放 executor 服务器 IP 到 SMTP 服务器 25 端口的访问权限,容器化部署需同步检查容器网络策略。
# 第四步:核对并修正内网 SMTP 标准配置
# 目的
排查 SMTP 配置参数错误、缺失或不规范导致的邮件发送失败,确保配置符合内网 25 端口非加密 SMTP 服务的要求。
# 操作
找到配置文件:定位到 executor 组件的 application.properties 配置文件;
对照标准配置模板,逐一核对核心配置参数,重点检查易出错项;
修正错误配置后,重启 executor 服务,使配置生效,重启后重新触发告警,测试邮件是否送达。
标准配置模板(适用于 25 端口非加密内网 SMTP):
# 内网SMTP服务器核心配置(请替换为实际值)
spring.mail.host=192.168.0.10
spring.mail.port=25
spring.mail.username=xxx.xxzx.xxx@xxx.com
spring.mail.password=xxxxxx
spring.mail.protocol=smtp
# 必须开启认证
spring.mail.properties.mail.smtp.auth=true
# 信任内网自签名证书(避免SSL校验失败)
spring.mail.properties.mail.smtp.ssl.trust=*
# 可选:设置超时防止阻塞
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
关键检查点:host 使用 IP 而非域名(避免内网 DNS 解析失败);username 必须是完整邮箱地址;不要配置 mail.smtp.ssl.enable=true 或 protocol=smtps(25 端口不加密)。
# 结论
✅ 配置修正后邮件送达:问题已解决,后续修改配置后需牢记重启 executor 服务。
❌ 配置无误但仍未送达:说明问题可能是账号权限或 SMTP 服务端异常,进入第五步进一步验证。
# 第五步:使用独立 Java 测试程序验证端到端投递有效性
# 目的
通过独立测试程序,绕开 executor 组件的业务逻辑,精准区分问题是配置错误、账号权限异常,还是 SMTP 服务端本身故障。
# 操作
准备测试代码:在 executor 所在服务器创建 SmtpTest.java 文件,复制以下代码,替换注释中 4 个核心参数(与 application.properties 配置完全一致);
编译并运行:在服务器执行 bash 命令
javac SmtpTest.java编译代码,再执行java SmtpTest运行测试程序;观察运行日志和收件人邮箱,记录测试结果。
测试代码:
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
public class SmtpTest {
public static void main(String[] args) {
// ########## 请修改以下4项,与 application.properties 完全一致 ##########
String smtpHost = "192.168.0.10";
int smtpPort = 25;
String username = "xxx.xxzx.xxx@xxx.com";
String password = "xxxxxx";
String receiveMail = "test@xxx.com"; // 建议先用同域名邮箱测试
// #################################################################
Properties props = new Properties();
// 注意:以下配置需同步落到 executor 组件的 application.properties 配置文件中,确保与测试代码一致
props.setProperty("mail.smtp.host", smtpHost);
props.setProperty("mail.smtp.port", String.valueOf(smtpPort));
props.setProperty("mail.smtp.auth", "true");
props.setProperty("mail.smtp.ssl.trust", "*");
props.setProperty("mail.transport.protocol", "smtp");
try {
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
session.setDebug(true); // 输出详细交互日志
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(receiveMail));
message.setSubject("[测试] 数据质量告警邮件通道验证");
message.setText("此邮件用于验证内网SMTP配置是否有效。");
Transport.send(message);
System.out.println("✅ 邮件发送成功!配置、账号、网络均正常。");
} catch (AuthenticationFailedException e) {
System.err.println("❌ 认证失败:账号密码错误 或 未开通SMTP权限");
e.printStackTrace();
} catch (Exception e) {
System.err.println("❌ 发送失败(非认证问题):网络、协议或服务异常");
e.printStackTrace();
}
}
}
# 结论
| 测试结果 | 结论(含义) | 后续操作 |
|---|---|---|
| ✅ 成功收到邮件 | ✅ 邮件发送成功,说明 Java 示例代码中的 SMTP 相关配置完全正确;此时只需将该 Java 示例代码中填写的 smtpHost、smtpPort、username、password 四项核心配置,逐一落到 executor 组件的 application.properties 配置文件中,确保配置文件与测试代码中的配置完全一致即可。 | 检查 executor 是否加载了正确配置,或是否存在代码逻辑覆盖发件人 |
| ❌ 认证失败 | 账号密码错误,或该账号未开通 SMTP 发送权限 | 联系邮箱管理员确认账号权限,或通过 Web 端登录验证密码 |
| ❌ 连接拒绝/超时 | 网络仍未连通,或 SMTP 服务端宕机 | 返回第三步重新排查网络,或联系运维确认 SMTP 服务状态 |
| ❌ SSL/TLS 错误 | 配置中错误启用了加密,与 25 端口非加密要求冲突 | 删除 ssl.enable=true 相关配置,确保 25 端口使用纯 SMTP 协议 |
# 附:常见误区提醒
❌ 不要混淆 Web 登录密码 与 SMTP 专用密码(如有),两者不一致会导致认证失败;
❌ 不要在 25 端口配置 smtps 或强制 SSL,25 端口为非加密端口,加密配置会导致连接失败;
❌ 修改 application.properties 后未重启 executor 服务,导致配置不生效;
✅ 发件人地址必须与 spring.mail.username 完全一致,否则会被 SMTP 服务或收件人邮箱拒收。
← 常见问题解答 数据资产与元数据集成相关问题 →