Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3061531
  • 博文数量: 535
  • 博客积分: 15788
  • 博客等级: 上将
  • 技术积分: 6507
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-07 09:11
文章分类

全部博文(535)

文章存档

2016年(1)

2015年(1)

2014年(10)

2013年(26)

2012年(43)

2011年(86)

2010年(76)

2009年(136)

2008年(97)

2007年(59)

分类: LINUX

2008-09-12 13:41:26

问题:qmail-send 占用cpu 100%,后台不再输出日志,重起qmail,qmail-send立刻占用cpu100%,没有任何日志输出。
执行qmail-qstat查看qmail状态
messages in queue: 287425
messages in queue but not yet preprocessed(预处理完成): 124573
没有变化。

相关知识:
qmail-send
当一个邮件被放入邮件队列之后,qmail-send就开始对该邮件进行处理,。它会检查邮件队列中的每一个邮件的状态,对于没有投递过的和投递暂时失败的邮件,qmail-send会将目标地址是本地主机的传递给qmail-lspawn,目标地址是远端主机的传递给qmail-rspawn,对于投递永久失败的邮件,qmail-send将会把该邮件传递给qmail-clear,让这个程序永久删除这个邮件。qmail-send是一个常驻内存进程程序,如果qmail-send中止,qmail的其他进程将会自动中止。


qmail对邮件的处理过程,由前端smtpd收下邮件,通过临时进程qmail-queue将邮件入队。qmail-queue首先在pid目录下创建一个inode,以这个inode的序列号作为该mail message的id,随后将该inode硬连接到mess目录下,写入邮件的内容,并在intd目录下创建一个同名的文件,写入MAIL FROM和RCPT TO等信息后又将该文件link到todo目录下。至此,整个邮件的入队过程完成。 qmail-send不断扫描todo目录,如果有新邮件,它将todo文件中的MAIL FROM写入到info目录下的同名文中,RCPT TO分别写入到local和remote目录下,删除todo下的文件随后将该id加入到remote或者local的内存队列中.(预处理完成)。qmail在内存中有四条队列,分别为前面所说的两条,和一条标示已经完成一份邮件处理的队列以及一条文件系统发生错误时才会被使用到的队列. job对应一个local或者remote下保存rcpt to的文件,rcpt to的地址以T作为开头,当往该用户成功投递后qmail就将T改为D标示投递成功或者永久性失败.
qmail-send不断从remote或者local的内存队列中取下一个id,给它分配一个对应的job,并从相应的info, local或者remote目录下取到MAIL FROM和RCPT TO并将它写到管道的buffer中,最后才被写入管道. 管道是qmail-send用来与两个长驻进程rspawn和lspawn通信的方式.rspawn或者lspawn收到来自qmail-send的投递信息后创建一个新的进程去投递,rspawn或者lspawn通过wait这个进程结束时的exit code来确定投递的成功与否.然后再通过管道将结果返回给qmail-send. qmail-send检查投递的结果,如果成功就如上面所说的将rcpt标示为D,否则确定是要重试还是多次尝试失败放弃。当一个job中所有的RCPT TO都被处理完后,qmail-send将相应的local或者remote目录下的文件删除,当一个msgid对应的local或者remote下的 rcpt to全被处理完时(即这几个文件已经不存在了),则该id会被加入到完成队列中去. qmail-send也会不断检测这个完成队列,取下一个id,通过检测bounce目录下是否有对应的文件来决定是否需要bounce,并删除info目录下的对应文件最后提交给qmail-clean将mess目录下的文件删除。
这些应该就是一封邮件在qmail中处理的大致过程,当然qmail-send 并不像我所说的那样线性地执行下来的,它是通过一个循环不断地执行前面所说的那五个函数来实现

分析:
根据上面的内容,可以判断,qmail-send进程在与qmail-rspawn进程通信或者在处理todo目录时出现了问题。(因为我的是外发邮件系统,不涉及local的邮件,所以不考虑qmail-lspawn)

分两步解决:
1.移出todo目录判断是否是在处理/var/qmail/queue/todo目录时出现了问题.
我的问题就是这个,停止qmail服务,移出todo目录,新建todo目录,设置权限,启动qmail,qmail正常运行了。待队列发送完后,再移回todo目录内的文件(也可以考虑分批移动)
2.如果不是上面的问题,那可能是在与qmail-rspawn进程通信时出现了问题,同理移动remote目录,看是否起作用。

注意:
队列应该在36小时之内发送完成,否则会出现类似这样的错误,造成邮件丢失
Sep 14 03:57:00 card4 qmail: 1221335820.985014 warning: unable to stat mess/19/3089494
原因:
qmail-queue首先在pid目录下创建一个inode(暂记为123)(S1),以这个inode的序列号作为该mail message的id,随后将该inode硬连接到mess目录下(S2),写入邮件的内容,并在intd目录下创建一个同名的文件,写入MAIL FROM和RCPT TO等信息(S3)后又将该文件link到todo目录下。至此,整个邮件的入队过程完成(S4)等待qmail-send的处理。 qmail-send不断扫描todo目录,如果有新邮件,它将todo文件中的MAIL FROM写入到info目录下的同名文中,RCPT TO分别写入到local和remote目录下,删除todo下的文件随后将该id加入到remote或者local的内存队列中(S5).(预处理完成)
qmail-queue在处理任何文件之前,会启动一个24小时的超时记时器。一旦等待处理超过24小时,qmail-queue将中止当前进程。
如果在qmail-queue处理邮件队列时,或者qmail-send正删除邮件时,系统因故障崩溃,当时处理的邮件就会处在S2或者S3状态。
如果qmail-send检查到有邮件处在S2或者S3状态(不是正在删除的邮件),而mess/123的创建时间已经过了36小时,它就相续删除 intd/123 (如果存在)和 mess/123。此时,正在处理该邮件的qmail-queue将被挂起。
同样的,如果qmail-send发现 pid/ 目录下的文件创建时间超过36小时,也将删除该目录。
阅读(2081) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~