- Affected version
- 2.2.9
In order to test the performance impact of DKIM signing I wrote a little test script:
I ran this script in a local VM (located in Europe) via CLI with three different setups:
With setup 1) it took around 800ms to generate the emails.
With setup 2) it took around 1s to generate the emails which seems plausible and quite acceptable (for a pretty limited VM).
With setup 3) however the process took well over 190 seconds to complete.
The root cause for this massive slowdown seems to be
in
This effecively reads the key for every single mail being send, in case of
Moving signer initialization to the container and changing above code to smth. like
reduced the runtime for setup 3) to an acceptable value of about 2.7 seconds.
PHP:
$dir = __DIR__;
require($dir . '/src/XF.php');
XF::start($dir);
$app = \XF::setupApp('XF\Pub\App');
$options = $app->options();
$mailer = $app->mailer();
$transport = $mailer->getDefaultTransport();
$start = microtime(true);
for ($i = 0; $i < 200; $i++)
{
$mail = $mailer->newMail();
$mail->setTo('webmaster@local.host');
$mail->setContent(
\XF::phrase('outbound_email_test_subject', ['board' => $options->boardTitle])->render('raw'),
\XF::phrase('outbound_email_test_body', ['username' => \XF::visitor()->username, 'board' => $options->boardTitle])
);
$mail->send($transport, false);
}
$end = microtime(true);
echo("Sending mails took " . ($end-$start) . "\n");
I ran this script in a local VM (located in Europe) via CLI with three different setups:
- DKIM signing disabled
- DKIM signing enabled, all storage local
- DKIM signing enabled,
internal-data
configured to use an Amazon S3 Bucket in US-West
PHP:
$config['enableMail'] = false;
With setup 1) it took around 800ms to generate the emails.
With setup 2) it took around 1s to generate the emails which seems plausible and quite acceptable (for a pretty limited VM).
With setup 3) however the process took well over 190 seconds to complete.
The root cause for this massive slowdown seems to be
PHP:
$dkimOptions = \XF::options()->emailDkim;
if ($dkimOptions['enabled']
&& extension_loaded('openssl')
&& $dkimOptions['domain'] == substr(strrchr($this->getFromAddress(), '@'), 1)
)
{
$keyFile = null;
try
{
$path = 'internal-data://keys/' . $dkimOptions['privateKey'];
$keyFile = \XF::fs()->read($path);
}
catch (\Exception $e)
{
\XF::logError("Email DKIM: Key not found at $path");
}
if ($keyFile)
{
$message->attachSigner(new \Swift_Signers_DKIMSigner($keyFile, $dkimOptions['domain'], 'xenforo'));
}
}
in
XF\Mail\Mail::send
.This effecively reads the key for every single mail being send, in case of
internal-datsa
using a remote storage (like S3) this is getting really slow as the file has to be dowoleded over and over again.Moving signer initialization to the container and changing above code to smth. like
PHP:
$dkimOptions = \XF::options()->emailDkim;
if (
$dkimOptions['enabled']
&& $dkimOptions['domain'] == substr(strrchr($this->getFromAddress(), '@'), 1)
)
{
$dkimSigner = \XF::app()->get('mailer.dkimsigner');
if ($dkimSigner)
{
$message->attachSigner($dkimSigner);
}
}
Last edited: