SMTP服务器批量发送邮件无响应且未抛异常问题咨询
批量SMTP邮件发送卡住的问题排查与解决
我之前在做批量邮件推送的时候也碰到过一模一样的问题!结合你描述的场景——服务器没宕机但程序突然卡住,既不返回结果也不抛异常,核心原因几乎可以确定是缺少超时配置导致的连接/读写阻塞,下面给你拆解问题和解决方案:
问题根源分析
- JavaMail默认是没有设置任何超时限制的!当SMTP服务器在处理大量批量请求时,很可能因为队列积压、临时资源不足等情况,对部分请求的响应变慢甚至暂时挂起。你的程序因为没有超时机制,会一直无限期等待服务器的响应,就出现了这种“卡住不动”的状态。
- 你提到服务器已经持续处理请求超过5分钟,但中途某个阶段卡住,大概率是某一封邮件的连接建立或数据传输环节出现了无响应的情况,没有超时的话程序就会一直停在那里。
立即生效的解决方案:添加超时配置
给你的JavaMail Session加上这两个关键属性即可,单位都是毫秒:
Properties mailProps = new Properties(); mailProps.put("mail.smtp.host", "你的SMTP服务器地址"); mailProps.put("mail.smtp.port", "你的SMTP端口"); // 连接超时:设置为30秒,超过这个时间没建立连接就抛出异常 mailProps.put("mail.smtp.connectiontimeout", "30000"); // 读写超时:设置为60秒,发送/接收数据时超过这个时间没响应就抛出异常 mailProps.put("mail.smtp.timeout", "60000"); // 如果你的SMTP用的是SSL加密(比如端口465),要改用对应的SSL属性: // mailProps.put("mail.smtps.connectiontimeout", "30000"); // mailProps.put("mail.smtps.timeout", "60000"); // 创建Session时传入配置 Session session = Session.getInstance(mailProps, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("你的邮箱账号", "你的授权码/密码"); } });
加上这两个配置后,一旦遇到服务器无响应的情况,程序会在超时时间到后抛出SocketTimeoutException,你可以捕获这个异常并做相应的处理(比如重试、记录异常日志),不会再出现无限卡住的情况。
批量邮件发送的额外优化建议
- 添加单邮件重试机制:即使设置了超时,偶尔还是会遇到超时或临时失败的情况,针对单个邮件发送失败的场景,做1-2次重试(注意不要无限重试,避免给服务器造成额外压力)。
- 控制并发连接数:SMTP服务器通常有并发连接限制,一次性发起太多并发请求容易导致服务器响应变慢甚至拒绝连接。可以用线程池控制并发数,比如
ExecutorService executor = Executors.newFixedThreadPool(5);(具体线程数根据你的SMTP服务器配置调整)。 - 完善日志监控:在每一封邮件发送前后记录详细日志,包括收件人、发送时间、最终结果,这样如果再出现问题,能快速定位到具体是哪一封邮件出了问题,方便后续排查。
内容的提问来源于stack exchange,提问作者user6591323
相关产品推荐
相关产品推荐

