Springboot框架开发的程序,部署在本地Centos7虚拟机上。 使用了spring-boot-starter-mail包进行发送邮件。但稳定性不高,偶尔成功偶尔失败。无法解决的失败原因如下:

2021-10-13 00:00:09.055 febs [asyncTaskExecutor-5] ERROR o.s.a.i.SimpleAsyncUncaughtExceptionHandler - Unexpected exception occurred invoking async method: public void cc.mrbird.febs.common.service.impl.MailServiceImpl.sendMail(java.util.List,java.lang.String,java.lang.String)
org.springframework.mail.MailSendException: Mail server connection failed; nested exception is com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.qiye.aliyun.com, 25; timeout 5000;
  nested exception is:
	java.net.SocketTimeoutException: connect timed out. Failed messages: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.qiye.aliyun.com, 25; timeout 5000;
  nested exception is:
	java.net.SocketTimeoutException: connect timed out
	at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:447)
	at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:322)
	at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:311)
	at cc.mrbird.febs.common.service.impl.MailServiceImpl.sendMail(MailServiceImpl.java:43)
	at cc.mrbird.febs.common.service.impl.MailServiceImpl.sendMail(MailServiceImpl.java:74)
	at sun.reflect.GeneratedMethodAccessor781.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.qiye.aliyun.com, 25; timeout 5000
	at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2209)
	at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:740)
	at javax.mail.Service.connect(Service.java:366)
	at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:517)
	at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:436)
	... 15 common frames omitted
Caused by: java.net.SocketTimeoutException: connect timed out
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:607)
	at com.sun.mail.util.WriteTimeoutSocket.connect(WriteTimeoutSocket.java:115)
	at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:357)
	at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
	at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175)
	... 19 common frames omitted

相关的springboot的application.yml配置如下:

spring:
  mail:
    host: smtp.qiye.aliyun.com
    protocol: smtp
    default-encoding: UTF-8
    username: ****@***.com
    password: ******
    properties:
      mail:
        smtp:
          socketFactory:
            class: javax.net.ssl.SSLSocketFactory
            port: 465
          auth: true
          connectiontimeout: 5000
          timeout: 3000
          writetimeout: 5000

发送邮件相关的java代码如下:

@Service @Slf4j public class MailServiceImpl implements MailService { @Autowired private JavaMailSender mailSender; @Value("${spring.mail.username}") private String from; @Value("${webHost}") private String webHost; public void sendMail(String[] toList, String subject, String text) { text += "\n系统地址:" + webHost; SimpleMailMessage message = new SimpleMailMessage(); message.setFrom(from); message.setTo(toList); message.setSubject(subject); message.setText(text); String errorMessage = String.format("发送邮件失败,目标地址:%s,主题:%s,内容:%s", String.join("、",toList),subject,text); mailSender.send(message); } catch (MailSendException se) { Exception[] messageExceptions = se.getMessageExceptions(); SendFailedException sendFail; if (!(messageExceptions[0] instanceof SendFailedException)) { throw new FebsRuntimeException(errorMessage, se); sendFail = (SendFailedException) messageExceptions[0]; log.error("send mail error,the invalid mail address:{}", sendFail.getInvalidAddresses()); Address[] address = sendFail.getValidUnsentAddresses(); if (null == address || 0 == address.length) { throw new FebsRuntimeException(errorMessage, se); String[] validMails = new String[address.length]; for(int j=0;j<address.length;j++){ validMails[j] = String.valueOf(address[j]); message.setTo(validMails); mailSender.send(message); } catch (Exception e) { log.error(errorMessage,e); @Override @Async public void sendMail(List<String> toList, String subject, String text) { if (CollectionUtils.isEmpty(toList)) { return; String[] toArray = toList.toArray(new String[] {}); sendMail(toArray,subject,text);

由于有成功发送的情况,所以应该不存在因配置错误而导致的连接不上或者端口被ban的情况。 经排查,在虚拟机上反复执行:telnet smtp.qiye.aliyun.com 25指令,不定期的出现Connection timed out。请问是否存在网络波动以外的原因?以及如果真是因为网络波动所导致,是否只有增加重试机制这唯一的方案?

企业邮箱发送邮件时,若出现投递失败产生退信,内容提示包含如下: the mta server of * reply:550 failed to meet SPF requirements 或者 the mta server of 163.com — 163mx01.mxmail.netease.com(220.181.14.141) reply:550 MI:SPF mx14,QMCowECpA0qTiftVaeB3Cg—.872S2 1442548128 http://mail.163.com/help 302305