You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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路径:
    which php
    
    然后检查该PHP环境是否启用了openssl扩展(TLS连接依赖它):
    /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连接的审计日志:
    grep smtp /var/log/audit/audit.log
    
    如果发现相关拒绝记录,执行以下命令允许Cron进程联网:
    setsebool -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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:07:25