Kev*_*Kev 6 php email performance attachment
我今天有一张客户登记的机票报告说,mail()当我尝试发送附件时,PHP的功能在我的一个Windows 2003 Server机箱上超时.
经过调查,我能够重现他的问题.包含30-60Kb大小的小附件的消息需要15-20秒才能被该mail()功能处理.较大的附件大约360-500Kb所花费的时间超过允许的最大脚本执行时间(90秒).
我能够在两个不同的Windows 2003服务器和Windows 2008R2服务器上重现该问题.我还尝试了三个不同版本的PHP(5.2.14,5.2.17和5.3.6 - 所有32位和所有非线程安全版本,根据Microsoft的建议在Windows上运行PHP).
在所有情况下,邮件都是通过SMTP发送的(即不使用sendmail实现).我尝试了三种不同的SMTP方案:
无论如何,发送附件仍然是次优的,这意味着问题不能固定在慢速中继上.
然后我在我们的CentOS服务器上运行相同的代码,这些代码没有出现任何这些问题,该mail()函数几乎立即返回.但是,这些服务器上的PHP配置为使用sendmail.
然后我决定使用PHP源代码来查找mail()函数的实现,并发现以下代码ext/standard/mail.c:
if (!sendmail_path) {
#if (defined PHP_WIN32 || defined NETWARE)
/* handle old style win smtp sending */
if (TSendMail(INI_STR("SMTP"), &tsm_err, &tsm_errmsg, headers, subject, to, message, NULL, NULL, NULL TSRMLS_CC) == FAILURE) {
if (tsm_errmsg) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", tsm_errmsg);
efree(tsm_errmsg);
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", GetSMErrorText(tsm_err));
}
return 0;
}
return 1;
#else
return 0;
#endif
Run Code Online (Sandbox Code Playgroud)
TSendMail()在另一个源文件(win32/sendmail.c)中实现.最终发送到SMTP服务器的所有数据,似乎可以通过调用函数传入同步Post()在sendmail.c其中的样子:
static int Post(LPCSTR msg)
{
int len = strlen(msg);
int slen;
int index = 0;
while (len > 0) {
if ((slen = send(sc, msg + index, len, 0)) < 1)
return (FAILED_TO_SEND);
len -= slen;
index += slen;
}
return (SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)
该send()功能是一个winsock2功能.
我想知道缓冲区大小(根据下面的知识库文章,默认为8K)或缺乏调优是否会对更大量的数据产生一些影响.没有调用setsockopt()指定缓冲区大小或任何其他选项来优化调用send().
也许mail()使用SMTP传递的Windows上的功能不是用于发送大型电子邮件?
我有兴趣知道是否有其他人看过这段代码或经历过同样的事情.
为了清楚起见,我们现在已经为客户(SwiftMailer)提供了替代解决方案,因此这不是为了获得替代方案的建议.
我的想法是在 Windows 上使用http://glob.com.au/sendmail/和 PEAR Mail 类: http: //pear.php.net/package/Mail。这可能是解决您遇到的延迟的方法。我认为这无法绕过缓冲区,但我认为值得一试。
另外,我从未使用过它,但我听说过有关 SwiftMailer 的好消息: http: //swiftmailer.org/
| 归档时间: |
|
| 查看次数: |
977 次 |
| 最近记录: |