Magento 1.9.1 Cron执行邮件发送时TLS连接失败求助
问题排查与解决方案:Magento 1.9 Cron邮件TLS连接失败
从你的描述和错误日志来看,核心问题是Cron任务触发邮件发送时无法通过TLS连接SMTP服务器,但SMTP扩展的手动测试功能正常——这说明问题大概率出在Cron执行环境与Web请求环境的差异,或者代码调用逻辑上。下面分点给出排查方向和解决办法:
1. 检查Cron执行环境的PHP配置差异
Web请求和Cron任务可能使用不同的PHP配置文件,这是最常见的诱因:
- 首先确认Cron使用的PHP版本和配置:
执行命令查看Cron默认PHP路径:
然后检查该PHP环境是否启用了openssl扩展(TLS连接依赖它):which php/path/to/your/php -i | grep openssl - 如果输出中没有
OpenSSL support => enabled,说明Cron用的PHP没启用openssl。修改对应PHP的php.ini文件,找到extension=openssl.so(Linux)或extension=php_openssl.dll(Windows),去掉前面的注释符号,保存后确保Cron进程能加载到新配置。
2. 改用SMTPPro扩展的邮件模型发送
你的代码使用了Mage::getModel('core/email'),虽然SMTPPro会替换核心邮件模型,但Cron环境下的模型重写可能存在兼容性问题。直接调用SMTPPro的专属模型更可靠,同时添加异常捕获便于排查:
public function sendExpiryNotification() { try { $mail = Mage::getModel('smtppro/email') ->setToEmail('mytest@example.com') ->setBody('Body of the Automated Cron Email Goes Here') ->setSubject('Subject: Cron Task '.date("Y-m-d H:i:s")) ->setFromEmail('sender@yourdomain.com') ->setFromName('Store name') ->setType('html'); $mail->send(); Mage::log('Cron email sent successfully', null, 'cron_email_success.log'); } catch (Exception $e) { Mage::log('Cron email failed: ' . $e->getMessage() . "\n" . $e->getTraceAsString(), null, 'cron_email_error.log'); } }
3. 解决TLS版本兼容性问题
Magento 1.9内置的Zend_Mail版本较老,可能不支持TLS 1.2/1.3,而你的SMTP服务器可能只允许高版本TLS,导致握手失败。可以强制指定TLS版本:
public function sendExpiryNotification() { try { $mail = Mage::getModel('core/email') ->setToEmail('mytest@example.com') ->setBody('Body of the Automated Cron Email Goes Here') ->setSubject('Subject: Cron Task '.date("Y-m-d H:i:s")) ->setFromEmail('sender@yourdomain.com') ->setFromName('Store name') ->setType('html'); // 手动配置SMTP传输,强制使用TLS 1.2 $config = array( 'ssl' => 'tls', 'port' => 587, 'auth' => 'plain', 'username' => Mage::getStoreConfig('system/smtp/username'), 'password' => Mage::getStoreConfig('system/smtp/password'), 'ssloptions' => array( 'ssl_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT ) ); $transport = new Zend_Mail_Transport_Smtp('mail.mydomain.com', $config); $mail->send($transport); Mage::log('Cron email sent successfully', null, 'cron_email_success.log'); } catch (Exception $e) { Mage::log('Cron email failed: ' . $e->getMessage(), null, 'cron_email_error.log'); } }
4. 排查服务器防火墙/SELinux限制
Cron进程的出站连接可能被防火墙或SELinux拦截:
- 防火墙检查:执行
iptables -L -n | grep 587,确认是否允许TCP 587端口的出站流量。如果没有,添加规则:iptables -A OUTPUT -p tcp --dport 587 -j ACCEPT service iptables save - SELinux检查:执行
sestatus,如果状态是Enforcing,检查是否有阻止SMTP连接的审计日志:
如果发现相关拒绝记录,执行以下命令允许Cron进程联网:grep smtp /var/log/audit/audit.logsetsebool -P cron_can_network_connect on
5. 修复HELO主机名验证问题
从错误栈能看到Zend_Mail_Protocol_Smtp->helo('localhost'),SMTP服务器可能拒绝localhost作为HELO主机名,导致连接中断:
- 打开Aschroder SMTPPro的配置页面,找到HELO主机名选项,设置为你的服务器域名(比如
server2.mywebsolutions.co.in); - 或者在代码中手动指定HELO:
$transport = Mage::getModel('smtppro/transport')->getZendTransport(); $transport->getProtocol()->helo('server2.mywebsolutions.co.in'); $mail->send($transport);
建议先从第1、2点入手排查,这两个是最容易解决且常见的原因。
内容的提问来源于stack exchange,提问作者Joshi
相关产品推荐
相关产品推荐

