AWS SDK for PHP V3の非同期処理をSESで試してみる

  • 3
    Like
  • 0
    Comment
More than 1 year has passed since last update.

AWS SDK for PHP V3の非同期処理をSESで試してみる

ちょっと前ですが、AWS SDK for PHPが非同期処理に対応しました。

Concurrency in Version 3 of the AWS SDK for PHP

非同期処理を使うと並列実行しやすいとのことで、SESのメール送信APIで順次処理と非同期処理の実行時間を比較してみました。

必要環境

  • PHP >= 5.5

準備

composerからインストールします。

$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar require aws/aws-sdk-php:~3.0

メール送信:順次処理版(sync.php)

<?php

require 'vendor/autoload.php';

define('MY_LIMIT', 24);

use Aws\Ses\SesClient;

$client = SesClient::factory(array(
    'version'=> 'latest',     
    'region' => 'us-east-1',
));

$request = array();
$request['Source'] = '(送信元アドレス)';
$request['Destination']['ToAddresses'] = array('(送信先アドレス)');
$request['Message']['Subject']['Data'] = 'ses';
$request['Message']['Body']['Text']['Data'] = 'example';

for ($i = 0; $i < MY_LIMIT; $i++) {
    try {
        $result = $client->sendEmail($request);
        $messageId = $result->get('MessageId');
        echo("Email sent! Message ID: $messageId"."\n");
    } catch (Exception $e) {
        echo("The email was not sent. Error message: ");
        echo($e->getMessage()."\n");
    }
}

メール送信:非同期処理版(async.php)

6並列で実行してみました。

<?php

require 'vendor/autoload.php';

define('MY_LIMIT', 24);
define('MY_CONCURRENCY', 6);

use Aws\Ses\SesClient;
use GuzzleHttp\Promise;

$client = SesClient::factory(array(
    'version'=> 'latest',     
    'region' => 'us-east-1',
));

$request = array();
$request['Source'] = '(送信元アドレス)';
$request['Destination']['ToAddresses'] = array('(送信先アドレス)');
$request['Message']['Subject']['Data'] = 'ses';
$request['Message']['Body']['Text']['Data'] = 'example';

$promiseGenerator = function($total) use ($client, $request) {
    for ($i = 0; $i < $total; $i++) {
        yield $client->sendEmailAsync($request);
    }
};

$promise = Promise\each_limit(
    $promiseGenerator(MY_LIMIT),
    MY_CONCURRENCY,
    function ($result) {
        $messageId = $result->get('MessageId');
        echo("Email sent! Message ID: $messageId"."\n");
    },
    function (Exception $e) {
        echo("The email was not sent. Error message: ");
        echo($e->getMessage()."\n");
    }
);
$promise->wait();

比較

timeコマンドで比較しました。

$ php -v 
PHP 5.6.26 (cli) (built: Sep 15 2016 13:22:01) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
$ time php sync.php
$ time php async.php

3回ずつ実行した場合のreal値の平均値が以下となりました。

sync.php async.php
9.403 秒 2.557 秒

非同期処理で並列実行すると3倍以上速くなりました!