洛基的城堡

Python学习手记

python SMTP邮件发送中的坑

邮件大小

问题:error[(552, '5.3.4 Message size exceeds fixed limit' 当邮件的正文或者附件超过一定大小限制时会返回这个错误。
解决方法:对邮件进行切分,一封邮件最多已发送1000条信息

邮件发送速度

问题:如果邮件发送速度过快,那么邮件服务器会认为你是一个垃圾邮件的制造者,会主动断掉与你的连接。
处理方法:每发送完一封邮件后sleep 0.2s

异常处理

问题:C/C++中我们使用返回值判断函数是否正确返回,在python/java中使用异常进行错误处理。

python中即使没有明确指出这个函数会抛出异常,这个函数还是有可能会抛出异常(比如它调用了其他会抛出异常的函数)

SMTP.quit()函数有可能会抛出异常,但是在python的api接口中并没有显示的说明。
quit()函数不会主动抛出异常,但是quit()调用其他会抛出异常的函数。

处理方法
为了避免再次出现问题,仅在sendmail的外围catch所有的异常,这样即使出现问题,也仅仅是抛弃出现问题的邮件,不影响其他邮件的发送。

try:

    server.sendmail(...)

except SMTPException as err:

    logging.warning(...)

except Exception as err:

    logging.warning(...)


STMP类默认的超时

问题:SMTP的默认超时是socket._GLOBAL_DEFAULT_TIMEOUT,socket类对于_GLOBAL_DEFAULT_TIMEOUT的处理方式是不设置超时。

如果网络出现异常,或者smtplib和服务器的代码中存在bug,就有可能SMTP一直hang住,在使用的时候务必要记得设置超时。

处理方法:我们使用的过程设置是20s

server = STMP(host, timeout=20)

<pre lang="python">

smtplib.py

class SMTP:

    def __init__(self, host='', port=0, local_hostname=None,

                 timeout=socket._GLOBAL_DEFAULT_TIMEOUT):

 

socket.py

_GLOBAL_DEFAULT_TIMEOUT = object()

def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT):

    sock = socket(af, socktype, proto)

    if timeout is not _GLOBAL_DEFAULT_TIMEOUT:

            sock.settimeout(timeout)

    sock.connect(sa)


邮件地址格式

问题:正则表达式 '[\w.]+@[\w.]+' 匹配liming@126.?.com
处理方法:'^[\w.]+@[\w.]+$'

但是有的邮箱系统允许使用-作为邮箱名,比如li-ming@126.com
处理方法:'^[\w.-]+@[\w.-]+$'

临时文件

问题:线上发现一个很奇怪的问题,程序生成的文件只有work用户有rw权限,其他用户没有任何权限,这样导致出了问题之后rd不能进行排查。
原因: 发现mktemp 生成的临时文件只有owner有rw权限,其他用户没有权限。
处理方法:chmod a+r tempfile

发送过程中异常退出

问题:如果发送过程中异常退出,需要进行手工恢复:已经发送的用户不在发送,未发送的用户进行补发
处理方法<后续>:将已发送用户记录到milestone里,如果任务失败,无需手动恢复数据,只要重跑任务即可

调度脚本

问题:调度脚本的日志太少,由于使用shell编写日志打印不规范,不易维护
处理方法<后续>:



转载自:https://blog.xiaoheshang.info/?p=697

评论

© 洛基的城堡 | Powered by LOFTER