SQSのメッセージを取得する部分と、メッセージを削除する部分をAWSのSDK経由で行います。
PHPでLaravelを使っている場合、一般的なJobをQueueする処理などは、LaravelのQueueの機能を使えば実装出来ますが、
メールのBounceなど、Laravelの機能とは別のサービス経由で発生したメッセージを処理する場合は、Laravelの機能を使わずにSQSからのメッセージ取得、削除を書くこともあると思います。
以下にSQSからのメッセージ一覧の取得とメッセージの削除を載せます。
SqsClient.php
<?php
declare(strict_types=1);
namespace Infra\ApiClient\Aws\SQS;
use Aws\Credentials\Credentials;
use Aws\Sqs\SqsClient;
class SqsClient {
private $sqsClient;
private $apiPath;
public function __construct()
{
$prefix = "";
$queue = "";
$this->apiPath = $prefix . '/' . $queue;
$key = ""; // AWSのプログラマチックユーザーのアクセスキー
$secret = ""; // AWSのプログラマチックユーザーのシークレット
$region = "";
$this->sqsClient = new SqsClient([
'credentials' => new Credentials($key, $secret),
'region' => $region,
'version' => '2012-11-05', // 最新バージョン
]);
}
public function getList(): array
{
$request = [
'AttributeNames' => ['All'],
'MessageAttributeNames' => ['All'],
'MaxNumberOfMessages' => 10, // 一回のリクエストで取得するMessage数、最大10なので最大値
'QueueUrl' => $this->apiPath,
'WaitTimeSeconds' => 3, // Messageを取得するまで待つ時間
'VisibilityTimeout' => 30, // 取得したMessageの可視性タイムアウト
];
$response = $this->sqsClient->receiveMessage($request);
$items = $response->get('Messages');
return $items;
}
public function delete($item) : void
{
$this->sqsClient->deleteMessage([
'QueueUrl' => $this->apiPath,
'ReceiptHandle' => $item['ReceiptHandle'],
]);
}
補足
1回の取得で最大10件のメッセージしか取得することが出来ません。大量にメッセージを処理したい場合は並列に実行出来ます。その際に複数のクライアントで実行されてしまうということはありません。SQSには可視性タイムアウトという取得したら一定時間他のクライアントから見えなくなる機能がついているからです。
メッセージの削除にはReceiptHandle
というメッセージの識別子が必要になります。メッセージを取得したクライアントしかメッセージを削除出来ないようにする配慮ですね。