1.概述
以下是qmail的数据流简图
qmail-smtpd --- >>qmail-queue --->> qmail-send <<--- qmail-rspawn <<--- qmail-remote
/ |
qmail-inject _/ qmail-clean \_ qmail-lspawn <<--- qmail-local
qmail中,每一条消息都发送到中央队列等待发送,由qmail-queue进程控制。它在以下情况被调用:
1、当产生本地消息时,qmail-inject进程调用qmail-queue。
2、qmail-smtpd准备SMTP协议下的投递邮件任务时调用它。
3、向前(forwarded)发送邮件时,qmail-local调用它。
4、退回邮件时,qmail-send调用它。
每封邮件接着由qmail-lspawn 和qmail-rspawn协助qmail-sned进程完成投递,最后由qmail-clean清除邮件队列。这四个进程是系统由始至终都在运行的,十分重要。
qmail的队列被设计成很强的鲁棒性,并假定基础的文件系统也是强健的。所有的cleanups清除队列操作都由qmail-send独立控制,无须人为干预。详细请看第六部分。
2. 队列结构
队列里的每条消息都由唯一的号码标识,假定某条消息是的标识码是457。队列被组织成几个目录,每个目录都可能包含和这条消息相关的文件:
mess/457: 消息正文
todo/457: 信封: 消息的来源地址和目的地址。实际是指向intd/457的链接。
intd/457: 信封,由qmail-queue生成。
info/457: 信封上的发送者地址,预处理后生成。
local/457: 本地接受地址,预处理后生成。
remote/457: 远程接受地址,预处理后生成。
bounce/457: 传输错误信息。
以下是一条消息所有可能的状态。“+”号表示该目录下文件存在,“-”表示该目录下文件不存在,“?”表示未知。
S1. -mess -intd -todo -info -local -remote -bounce
S2. +mess -intd -todo -info -local -remote -bounce
S3. +mess +intd -todo -info -local -remote -bounce
S4. +mess ?intd +todo ?info ?local ?remote -bounce (queued,表示已经进入队列)
S5. +mess -intd -todo +info ?local ?remote ?bounce (preprocessed,表示已通过预处理)
重点:如果消息457存在,那么它也对应一个inode结点号457。
3. 消息如何进入队列?
添加一条消息到队列里,qmail-queue首先创建一个单独的目录,命名为 pid/。然后在这个目录下为这条消息创建一个独立文件。文件系统为这个文件分配唯一的标识,暂时记做457。qmail-queue监视这个文件标识,并保证这条消息进入状态S1。
qmail-queue接着把pid/ 更名为mess/457,进入状态S2。然后写一些相关的信息到mess/457目录下,创建目录intd/457,进入状态S3,并在intd/457下写入相关的信封信息。
最后,qmail-queue创建一个指向 intd/457 的链接 :todo/457 ,进入状态S4。到此为止,这条消息已经被处理到队列中,等待qmail-send的处理。
qmail-queue在处理任何文件之前,会启动一个24小时的超时记时器。一旦等待处理超过24小时,qmail-queue将中止当前进程。
4. 队列中的消息如何预处理
一旦消息进入等待队列,qmail-send必须判断哪些是要投递给本地接收者,哪些是要投递给远程接收者。它也有可能重写某些接受者地址。
当qmail-send检测到 todo/457 目录,得知消息457处于状态S4。于是,它先删除已经存在的(假如)info/457, local/457 和 remote/457目录。然后读取整个todo/457目录,生成 info/457 、 local/457 或者 remote/457 目录。完成这些操作后,删除 intd/457目录。这时,该条消息仍然处于S4状态。最后,qmail-send删除 todo/457 目录,进入S5状态。到此为止,这条消息已成功的完成预处理。
5. 预处理后,消息如何被投递。
处在S5状态的消息将被做如下处理。每个 local/457 和 remote/457 目录下的邮件地址将被标记NOT DONE 或 DONE:
DONE: 表示该消息已经被成功投递,或者是投递时遇到了永久性错误。这时,qmail-send将会停止对该消息所示的地址继续进行投递任务。
NOT DONE:如果已经有投递任务在尝试,该标记表示投递人物遇到暂时性错误。这种情况下,qmail-send会随后继续尝试投递。
qmail-send 会在空闲的时间尝试给标记了NOT DONE 的地址发送邮件。如果邮件被成功处理,qmail-send将在该地址标记DONE。如果遇到永久性错误,它首先发送一条错误通知到bounce/457目录(如果该目录不存在,就自动创建),然后将邮件地址标记为DONE。
注意:bounce/457被设计成不强健的。
qmail-send会在任意的时刻处理 bounce/457目录 ,可能如下:
1)从 bounce/457 和 mess/457目录创建一条新的bounce消息
2)删除bounce/457目录。
当local/457中所有的邮件地址都被标记DONE后,qmail-send将删除local/457。同样的,remote/457也做此处理。随后,qmail-send删除队列里的邮件:
第一步、如果 bounce/457存在,qmail-send按照上述的方法处理。
第二步、如果 bounce/457已删除,qmail-send删除 info/457目录,进入状态S2;然后删除 mess/457 ,进入状态S1。
6. Cleanups清除操作。
如果在qmail-queue处理邮件队列时,或者qmail-send正删除邮件时,系统因故障崩溃,当时处理的邮件就会处在S2或者S3状态。
如果qmail-send检查到有邮件处在S2或者S3状态(不是正在删除的邮件),而mess/457的创建时间已经过了36小时,它就相续删除 intd/457 (如果存在)和 mess/457。此时,正在处理该邮件的qmail-queue将被挂起。
同样的,如果qmail-send发现 pid/ 目录下的文件创建时间超过36小时,也将删除该目录。
如果在qmail-send投递邮件时发生系统崩溃故障,Cleanups则无须运行。最遭情况下,邮件可能会被投递两次。其实,在分布式邮件系统上,目前并没有一种有效的方法来降低邮件重复投递的可能。不妨试想一下,如果在接受方的邮件服务器响应之前,投递邮件的SMTP链接发生断路错误,该怎么办?显然,用户必须考虑到这种最坏情况,并再次发送邮件。同样的,如果在qmail-send进程为邮件做DONE标记之前,计算机崩溃了。那么,重启后的新进程必须再次发送该邮件。通常的方法是,利用日志文件。反正,删除重复邮件是接受方的事情,无须顾虑。
7. 更多
目前,info/457的存在有两种作用:
1、它记录了邮件信封中,发送人的信息。
2、守护进程通过它的修改时间来判断该邮件在队列中是否超时。
将来,随着系统改进, info/457 可能会存储更多的信息。任何改变都是向后兼容的,并将由版本号标识。
当qiaml-queue成功的将一条邮件加入到队列中时,它将启动一个由qmail-send设定的触发器。该触发器的工作机制是:命名管道锁触发-- lock/trigger 。在扫描 todo/ 之前,qmail-send 打开 lock/trigger下的管道O_NDELAY 设定可读。qiaml-queue通过向O_NDELAY写一个字节来触发qmail-send。这使得 locks/trigger 可读并唤醒qmail-send进程。在再次扫描 todo/ 之前,qmail-send 先关闭lock/trigger再打开它。
自由广告区 |
分类导航 |
邮件新闻资讯: IT业界 | 邮件服务器 | 邮件趣闻 | 移动电邮 电子邮箱 | 反垃圾邮件|邮件客户端|网络安全 行业数据 | 邮件人物 | 网站公告 | 行业法规 网络技术: 邮件原理 | 网络协议 | 网络管理 | 传输介质 线路接入 | 路由接口 | 邮件存储 | 华为3Com CISCO技术 | 网络与服务器硬件 操作系统: Windows 9X | Linux&Uinx | Windows NT Windows Vista | FreeBSD | 其它操作系统 邮件服务器: 程序与开发 | Exchange | Qmail | Postfix Sendmail | MDaemon | Domino | Foxmail KerioMail | JavaMail | Winwebmail |James Merak&VisNetic | CMailServer | WinMail 金笛邮件系统 | 其它 | 反垃圾邮件: 综述| 客户端反垃圾邮件|服务器端反垃圾邮件 邮件客户端软件: Outlook | Foxmail | DreamMail| KooMail The bat | 雷鸟 | Eudora |Becky! |Pegasus IncrediMail |其它 电子邮箱: 个人邮箱 | 企业邮箱 |Gmail 移动电子邮件:服务器 | 客户端 | 技术前沿 邮件网络安全: 软件漏洞 | 安全知识 | 病毒公告 |防火墙 攻防技术 | 病毒查杀| ISA | 数字签名 邮件营销: Email营销 | 网络营销 | 营销技巧 |营销案例 邮件人才:招聘 | 职场 | 培训 | 指南 | 职场 解决方案: 邮件系统|反垃圾邮件 |安全 |移动电邮 |招标 产品评测: 邮件系统 |反垃圾邮件 |邮箱 |安全 |客户端 |