记录一次不能发送邮件故障处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/niedewang/article/details/80239163

服务器使用的是万网的vps,邮件服务器是阿里云邮箱。今天发现不能发送邮件。
1:编写测试代码,发送过程中,发现出现服务超时。我没有服务器管理权限,处理起来比较棘手。
这里写图片描述

2:经过百度搜索,发现阿里云服务器是禁止25端口发送邮件的。
我们使用的是万网vps,可能近期也封禁25 发送邮件端口了。目前搜索发现的一个方案是,使用80端口,马上动手试验:
这里写图片描述

将端口变更会80,默认的使用的是25

3:经过测试,代码运行不在报错,并且已经收到了邮件。
这里写图片描述
如上图所示,代码没有报超时错误

这里写图片描述
如上图所示,服务器上收到了邮件。

4:不稳定,可能和网速有关,发送邮件耗时较多,一般需要1秒左右,最高5.7秒。影响用户体验。当然彻底解决方法,是更其他邮箱之类的,但这个是后话了,也需要时间。
这里写图片描述

5:发送邮件耗时,目前选择的是使用php 自带的函数后端执行,类似实现异步的方式。
5.1 这是原来的发送邮件方式
这里写图片描述
优点是:代码容易理解,阻塞方式运行,可以提取返回值,好调试
缺点:缺点也很明显,因为是阻塞,可能应为一个发送邮件的错误,导致整个功能失败。另外,发送邮件如果很耗时的话,会影响用户体验。
举个例子,如果是用户提交了一个评论,数据库保存完毕了,但发送邮件这部分慢,让用户多等了足足5秒。
彻底解决办法:我建议是使用队列,后台执行,不要和前台耦合。
但现在系统正在运行,架构上不适合做紧急大的修改
5.2 临时方案 类似异步的方式,发送邮件后台执行,不占用响应时间。

        $email = '[email protected]';//收件人
        $subject = '这里是邮件标题';
        $body = '您好<br/>这里是邮件内容<span style="color:red">红字部分</span>';       
        echo('over' . time());
        //异步方式,快 但是获取不到结果
        register_shutdown_function(array('Email', "sendBack"),$email, $subject, $body, Email::TYPE_AGREE_NOTICE);
        fastcgi_finish_request();

register_shutdown_function ,这个函数作用是,页面的php执行完毕后,再执行发送邮件程序。不管代码流程是什么,把发送邮件级别调整到最后
fastcgi_finish_request() ,这个函数 作用是,php 执行完毕后,理解发送前段nginx服务器,用户不必等待整个php 的全部执行。

举个例子:以发布评论为例,加入 写入数据库耗时1秒,发送邮件耗时3秒
那么传统的方式,整体耗时 3 +1 = 4秒
但因为 fastcgi_finish_request执行,发送邮件的3秒后端执行,前台用户感觉不到,耗时减少了。

这样达到了一个目的,即便是发送邮件出现错误,也不会影响主体功能的运行
比如,我把端口写成错误的801

    $config = self::getConfig();
        $Mail = Yii::createComponent('application.extensions.mailer.EMailer');
        $Mail ->CharSet='utf-8';
        $Mail->Port = 801;

但如下图所示,主体代码逻辑照常运作,不会收到影响
这里写图片描述
如上图,发送邮件即便是超时,网页耗时还是很低的。

6:总结,使用上面运作后,会达到一定效果
1:一定程度上逻辑分离,发送邮件不会影响到主体流程
2:耗时减少(其实服务器上资源消耗一样,只不过在服务器上执行,用户感觉不到而已)
但也有缺陷:
1:不方便调试,一旦发送邮件出现错误,可能页面上不能反馈出来。解决方案是,增加日志
2: fastcgi_finish_request ,这个函数貌似 只影响到已fastcgi 方式运行的web服务器,nginx +php-fpm 这个方式是完美支持的。apache 可能不太兼容

猜你喜欢

转载自blog.csdn.net/niedewang/article/details/80239163