最近搞了个django项目,其中用到了django的发邮件方法,本地调试没有问题,但是部署到腾讯云服务器后一直报错超时:Connection unexpectedly closed 研究了半天终于找到了解决办法!
先上一下流程代码吧:
def test1_view(request):
t = Thread(target=test2, args=('test1',))
t.start()
return JsonResponse({'msg': 'test1进入啦!'})
def test2(a):
msg = a
t1 = Thread(target=send_Email, args=(msg,))
t1.start()
def send_Email(msg):
subject = '[test]'
message = msg
from_email = settings.DEFAULT_FROM_EMAIL
receivers = ['test@163.com']
try:
send_mail(subject, message, from_email, receivers, fail_silently=False)
except Exception as e:
print(str(e))
finally:
pass
流程很简单:接收到前端请求后 test1_view 处理对应请求,并新起线程执行test2,而在test2执行一系列操作完成后新起线程执行发送邮件通知。
简单的代码调试起来却遇到了发送邮件失败的问题。
首先,发送邮件失败大体就是进行下面几点检查:
1、检查django setting.py邮件配置
经检查 我的django email 发送配置是没有问题的,用的也是465端口,大体配置如下:
# 发送邮箱
EMAIL_HOST = "smtp.163.com" # 服务器
EMAIL_PORT = 465 # 一般情况下都为25, 服务器为 465
EMAIL_HOST_USER = "xxx@163.com" # 账号
EMAIL_HOST_PASSWORD = "xxx" # 密码(这里是你的授权码)
EMAIL_USE_SSL = True
EMAIL_FROM = "xxx@163.com" # 邮箱来自
我在本地 Windows 环境上进行调试,邮件可以正常发出,完全没有问题。
2、于是,我把代码部署到了服务器上。
最开始在服务器上就是简单的运行,通过 python manage.py runserver 运行。此时,代码也是没有问题的,邮件正常发送。
有的同学可能在这边会发送失败,你需要登录云服务管理后台看看服务器的安全组配置,是不是对应的端口没有放开。
3、最后,我用nginx uwsgi 部署django 应用
结果!问题出现了。邮件一直发送失败,主要会有两种异常:
EOF occurred in violation of protocol (_ssl.c:645)
Connection unexpectedly closed
于是开始寻找解决办法,最开始我以为是配置问题和端口问题,于是又把上面的步骤1、2检查了一遍,事实证明完全没问题。
最后,两份相同的代码,在相同的环境下,放通相同的端口下为什么会发送失败呢?我开始想到了是 nginx和 uwsgi的问题。
终于,发现了uwsgi有这么一条配置:
--enable-threads
这条配置允许用内嵌的语言启动线程(即允许在app程序中产生子线程)。
于是再uwsgi配置中添加,完美解决。
#允许用内嵌的语言启动线程。这将允许你在app程序中产生一个子线程
enable-threads = true