阿里云ECS服务器无法发送邮件问题解决方案

这篇文章分享一下自己把项目部署在阿里云ECS上之后,登录邮件提醒时的邮件发送失败问题,无法连接发送邮箱的服务器。

博主使用的springboot提供的发送邮件服务,如下所示,为了实现异步的效果,新开了一个线程来发送邮件。

package cn.edu.sgu.www.mhxysy.service.system.impl;import cn.edu.sgu.www.mhxysy.property.EmailProperties;
import cn.edu.sgu.www.mhxysy.property.SystemSettingsProperties;
import cn.edu.sgu.www.mhxysy.consts.RedisKeyPrefixConst;
import cn.edu.sgu.www.mhxysy.dto.system.UserLoginDTO;
import cn.edu.sgu.www.mhxysy.dto.system.UserUpdateDTO;
import cn.edu.sgu.www.mhxysy.entity.system.User;
import cn.edu.sgu.www.mhxysy.entity.system.UserLoginLog;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import cn.edu.sgu.www.mhxysy.feign.FeignService;
import cn.edu.sgu.www.mhxysy.redis.RedisRepository;
import cn.edu.sgu.www.mhxysy.redis.StringRedisUtils;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.service.system.UserService;
import cn.edu.sgu.www.mhxysy.util.IpUtils;
import cn.edu.sgu.www.mhxysy.util.StringUtils;
import cn.edu.sgu.www.mhxysy.util.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;/*** @author heyunlin* @version 1.0*/
@Slf4j
@Service
public class UserServiceImpl implements UserService {private final FeignService feignService;private final JavaMailSender javaMailSender;private final EmailProperties emailProperties;private final RedisRepository redisRepository;private final StringRedisUtils stringRedisUtils;private final SystemSettingsProperties systemSettingsProperties;@Autowiredpublic UserServiceImpl(FeignService feignService,JavaMailSender javaMailSender,EmailProperties emailProperties,RedisRepository redisRepository,StringRedisUtils stringRedisUtils,SystemSettingsProperties systemSettingsProperties) {this.feignService = feignService;this.javaMailSender = javaMailSender;this.emailProperties = emailProperties;this.redisRepository = redisRepository;this.stringRedisUtils = stringRedisUtils;this.systemSettingsProperties = systemSettingsProperties;}@Overridepublic void logout() {// 删除角色的权限redisRepository.delete(UserUtils.getLoginUsername());// 注销UserUtils.getSubject().logout();}@Overridepublic void login(UserLoginDTO loginDTO) {// 一、验证码判断// 得到用户输入的验证码String code = loginDTO.getCode();// 获取正确的验证码String uuid = loginDTO.getUuid();String key = RedisKeyPrefixConst.PREFIX_CAPTCHA + uuid;String realCode = stringRedisUtils.get(key);// 得到的验证码为空,则获取验证码到登录之间的时间已经过了3分钟,验证码过期已经被删除if (realCode == null) {throw new GlobalException(ResponseCode.BAD_REQUEST, "验证码已失效,请刷新页面重新获取~");}// 验证码校验if (!code.equalsIgnoreCase(realCode)) {throw new GlobalException(ResponseCode.BAD_REQUEST, "验证码错误~");}// 二、登录流程// 得到用户名String username = loginDTO.getUsername();log.debug("用户{}正在登录...", username);// 查询用户信息,如果用户被锁定,提前退出User user = feignService.selectByUsername(username);if (user != null) {if (user.getEnable()) {// 1、shiro登录认证UsernamePasswordToken token = new UsernamePasswordToken(username, loginDTO.getPassword());Subject subject = UserUtils.getSubject();subject.login(token);// 设置session失效时间:永不超时subject.getSession().setTimeout(-1001);// 2、修改管理员上一次登录时间User usr = new User();usr.setId(user.getId());usr.setLastLoginTime(LocalDateTime.now());feignService.updateById(usr);// 3、邮件通知if (emailProperties.isEnable()) {new Thread(() -> {// 定义日期格式DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");MimeMessage message = javaMailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message);try {String text = "您的账号" + username + "在广州登录了。" +"[" + LocalDateTime.now().format(formatter) + "]";helper.setFrom(emailProperties.getFrom());helper.setTo(emailProperties.getTo());helper.setText(text);javaMailSender.send(message);} catch (MessagingException e) {e.printStackTrace();}}).start();}// 4、如果开启了系统日志,添加管理员登录历史if (systemSettingsProperties.isLoginLog()) {UserLoginLog loginLog = new UserLoginLog();loginLog.setId(StringUtils.uuid());loginLog.setUserId(user.getId());loginLog.setLoginTime(LocalDateTime.now());loginLog.setLoginIp(IpUtils.getLocalHostAddress());loginLog.setLoginHostName(IpUtils.getLocalHostName());feignService.saveLoginLog(loginLog);}// 5、从redis中删除用户权限redisRepository.delete(username);// 6、查询用户的权限信息,并保存到redisredisRepository.save(username);} else {throw new GlobalException(ResponseCode.FORBIDDEN, "账号已被锁定,禁止登录!");}} else {throw new GlobalException(ResponseCode.NOT_FOUND, "用户名不存在~");}}@Overridepublic void updatePass(UserUpdateDTO userUpdateDTO) {feignService.updatePass(userUpdateDTO);}}

过了一段时间之后,后台打印出了连接邮箱服务器超时的日志。 

Exception in thread "Thread-25" org.springframework.mail.MailSendException: Mail server connection failed; nested exception is com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.163.com, 25; timeout -1;nested exception is:java.net.ConnectException: Connection timed out (Connection timed out). Failed messages: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.163.com, 25; timeout -1;nested exception is:java.net.ConnectException: Connection timed out (Connection timed out); message exception details (1) are:Failed message 1:com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.163.com, 25; timeout -1;nested exception is:java.net.ConnectException: Connection timed out (Connection timed out)at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2210)at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:722)at javax.mail.Service.connect(Service.java:342)at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:518)at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:437)at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:361)at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:356)at cn.edu.sgu.www.mhxysy.service.system.impl.UserServiceImpl.lambda$login$0(UserServiceImpl.java:135)at java.lang.Thread.run(Thread.java:745)Caused by: java.net.ConnectException: Connection timed out (Connection 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:589)at java.net.Socket.connect(Socket.java:538)at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:335)at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:214)at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2160)... 8 more

原因是:Couldn't connect to host, port: smtp.163.com, 25

但是通过终端连接smtp.163.com是成功的

ping smtp.163.com

但是尝试访问25端口,却无响应

telnet smtp.163.com 25

 

于是在网上查找了一些解决方案,最后采用了通过ssl连接的方式,在原来的邮件设置中加入以下设置

spring:mail:port: 25host: smtp.163.comdefault-encoding: UTF-8username: xxxxx@163.compassword: xxxxxxxxxxxxx# 以下是新增的设置properties:mail:debug: truesmtp:auth: truessl:trust: smtp.163.comstarttls:enable: truerequired: truesocketFactory:port: 465class: javax.net.ssl.SSLSocketFactory

最后重启服务,登陆的时候成功发出了邮件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/92166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 SpringBoot 2.7.x 使用最新的 Elasticsearch Java API Client 之 ElasticsearchClient

1. 从 RestHighLevelClient 到 ElasticsearchClient 从 Java Rest Client 7.15.0 版本开始,Elasticsearch 官方决定将 RestHighLevelClient 标记为废弃的,并推荐使用新的 Java API Client,即 ElasticsearchClient. 为什么要将 RestHighLevelC…

SuffixArray练习题

SuffixArray练习题 🍉题目 import java.util.Arrays;class SuffixArray {//LCP:Longest common prefix/*字符串后缀,指从字符串某个* 位置开始到字符串末尾的字串,原串和空串也是后缀* Create the LCP array from the suffix array* 从后缀数组创建LCP数组* @param s the…

Windows的批处理——获取系统时间、生成当天日期日志

Windows批处理基础https://coffeemilk.blog.csdn.net/article/details/132118351 一、Windows批处理的日期时间 在我们进行软件开发的过程中,有时候会使用到一些批处理命令,其中就涉及到获取系统日期、时间来进行一些逻辑的判断处理;那么我们…

Tomcat启动后的日志输出为乱码

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

[Linux] 4.常用初级指令

pwd:显示当前文件路径 ls:列出当前文件夹下有哪些文件 mkdir空格文件名:创建一个新的文件夹 cd空格文件夹名:进入文件夹 cd..:退到上一层文件夹 ls -a:把所有文件夹列出来 .代表当前文件夹 ..代表上层文件夹 用…

朴素贝叶斯分类(下):数据挖掘十大算法之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。 🐴欢迎小伙伴们点赞👍🏻、收藏⭐️、…

探索ClickHouse——连接Kafka和Clickhouse

安装Kafka 新增用户 sudo adduser kafka sudo adduser kafka sudo su -l kafka安装JDK sudo apt-get install openjdk-8-jre下载解压kafka 可以从https://downloads.apache.org/kafka/下找到希望安装的版本。需要注意的是,不要下载路径包含src的包,否…

最新ChatGPT网站系统源码+支持GPT4.0+支持AI绘画Midjourney绘画+支持国内全AI模型

一、SparkAI创作系统 SparkAi系统是基于很火的GPT提问进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT系统?小编这里写一个详细图文教程吧&a…

AWS】在EC2上创建root用户,并使用root用户登录

最近有项目需要使用AWS的EC2服务器; 在创建服务器实例之后发现,没有root用户,仔细阅读AWS EC2文档,发现默认是ec2-user用户; 那我们需要创建一个root用户 1.创建 root 用户 注意:必须要要在ec2-user用户下…

CCF CSP认证 历年题目自练Day18

CCF CSP认证 历年题目自练Day18 题目一 试题编号: 201809-1 试题名称: 卖菜 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述   在一条街上有n个卖菜的商店,按1至n的顺序排成一排,这…

Apollo自动驾驶系统概述(文末参与活动赠送百度周边)

前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 「推荐专栏」: ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄,vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

大喜国庆,聊聊我正式进入职场的这三个月...

个人简介 👀个人主页: 前端杂货铺 🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…

【python学习第11节:numpy】

文章目录 一,numpy(上)1.1基础概念1.2数组的属性1.3数组创建1.4 类型转换1.5ndarry基础运算(上)矢量化运算1.6拷贝和视图1.6.1完全不复制1.6.2视图或浅拷贝1.6.3深拷贝 1.7索引,切片和迭代1.7.1一维数组1.7…

浅谈一致性哈希Consistent Hashing

目录 1.一致性哈希定义2.工作原理3.应用场景4.使用一致性哈希的软件5.一致性哈希的开源实现6. 一致性哈希的不足 本文主要介绍一致性哈希的定义、原理,以及应用场景等内容。 1.一致性哈希定义 一致性哈希(Consistent Hashing)是一种特殊的哈…

React查询、搜索类功能的实现

React查询、搜索类功能的实现 查询之类的如果是通过向列表接口中发送对应参数来查询的,那么在默认输出时,在useEffect钩子中的请求中可以先为需要查询的请求参数设初始的state,也就是null或者未定义,这样的话初始请求的还是整个列…

日撸代码300行:第73天(固定激活函数的BP神经网络,训练与测试过程理解)

进一步梳理理解了一下正向和反向传播。Forward 是利用当前网络对一条数据进行预测的过程,BackPropagation 是根据误差进行网络权重调节的过程。 完整的代码在72天,这里只粘贴Forward和BackPropagation两个方法。 /*** *********************************…

编写结构化程序 - Go语言从入门到实战

编写结构化程序for、if、switch - Go语言从入门到实战 for 循环 与其他主要编程语⾔的差异: Go 语⾔仅⽀持循环关键字 for,而且代码更简洁性和灵活性。 一般的 for 循环结构如下: for 初始化; 条件; 后续操作 { // 循环体 }Go语言在循环…

基础数据结构之——【顺序表】(上)

从今天开始更新数据结构的相关内容。(我更新博文的顺序一般是按照我当前的学习进度来安排,学到什么就更新什么(简单来说就是我的学习笔记),所以不会对一个专栏一下子更新到底,哈哈哈哈哈哈哈!&a…

八个不可不知的SQL高级方法

结构化查询语言(SQL)是一种广泛使用的工具,用于管理和操作数据库。基本的SQL查询简单易学,但掌握高级SQL技术可以将您的数据分析和管理能力提升到新的高度。 高级SQL技术是指一系列功能和函数,使您能够对数据执行复杂…

【day10.01】使用select实现服务器并发

用select实现服务器并发&#xff1a; linuxlinux:~/study/1001$ cat server.c #include <myhead.h>#define ERR_MSG(msg) do{\printf("%d\n",__LINE__);\perror(msg);\ }while(0)#define PORT 8880#define IP "192.168.31.38"int main(int argc, c…