08/09/2018 - PHP, SYMFONY
Bu örneğimizde Amazon Simple Queue Service (AWS SQS) kullanarak bir tane dead-letter queue, bir tanede standard queue yaratıp bunları birbirleriyle bağdaştıracağız. Bu işlemin yapılış nedeni, eğer standard queue içindeki bir mesaj belirli sayıdaki işleme denemelerine rağmen işlenemezse, bu mesaj dead-letter queue içine taşınır ve orada bekletilir.
Aşağıdaki anahtarların sahibi olan AWS IAM kullanıcısının "AmazonSSQSFullAccess" hakkına sahip olduğundan emin olun.
parameters:
application_name: 'APP'
aws_sdk.config.default:
version: 'latest'
region: 'eu-west-1'
aws_sdk.credentials.default:
credentials:
key: 'AWS_KEY'
secret: 'AWS_SECRET'
services:
Aws\Sdk: ~
App\Util\AwsSqsUtil:
arguments:
$applicationName: '%application_name%'
$env: '%kernel.environment%'
calls:
- [createClient, ['%aws_sdk.config.default%', '%aws_sdk.credentials.default%']]
declare(strict_types=1);
namespace App\Util;
use Aws\Result;
use Aws\Sdk;
use Aws\Sqs\SqsClient;
class AwsSqsUtil implements AwsSqsUtilInterface
{
private $sdk;
/** @var SqsClient */
private $client;
private $applicationName;
private $env;
public function __construct(Sdk $sdk, string $applicationName, string $env)
{
$this->sdk = $sdk;
$this->applicationName = $applicationName;
$this->env = $env;
}
public function createClient(iterable $config, iterable $credentials): void
{
$this->client = $this->sdk->createSqs($config+$credentials);
}
/**
* @link https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sqs-2012-11-05.html#createqueue
*/
public function createQueue(string $name, bool $isDeadLetter, string $deadLetterArn = null): ?string
{
$attributes = ['VisibilityTimeout' => 60];
if ($deadLetterArn) {
$attributes['RedrivePolicy'] = sprintf(
'{"deadLetterTargetArn":"%s","maxReceiveCount":"5"}',
$deadLetterArn
);
}
/** @var Result $result */
$result = $this->client->createQueue([
'QueueName' => $this->createQueueName($name, $isDeadLetter),
'Attributes' => $attributes,
]);
return $result->get('QueueUrl');
}
/**
* @link https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sqs-2012-11-05.html#getqueueattributes
*/
public function getQueueArn(string $url): string
{
/** @var Result $result */
$result = $this->client->getQueueAttributes([
'QueueUrl' => $url,
'AttributeNames' => ['QueueArn']
]);
return $result->get('Attributes')['QueueArn'];
}
private function createQueueName(string $name, bool $isDeadLetter): string
{
return sprintf(
'%s_%s_%s%s',
strtoupper($this->applicationName),
strtoupper($this->env),
$name,
$isDeadLetter ? '_DL' : null
);
}
}
VisibilityTimeout => 60
mesajı 60 saniye boyunca "in flight" modunda tutar ve daha sonra "available" moduna alır (her ne sebepten dolayı işlenememiş ve silinememiş ise). Uyarı: Eğer bir mesajın işlenme süresi 60 saniyeden daha uzun olursa, o mesaj tekrardan kuyruğa konulur ve işleyicilere görünür hale gelir. Bu olmasını istemediğimiz bir senaryodur.maxReceiveCount: 5
bir mesajı işleyici tarafından bir kuyruktan en fazla 5 kere alınacağını belirler. Eğer denemeler sonucunda halen başarıyla işlenememiş veya silinememiş ise mesaj ilgili dead-letter queue içine taşınır.Bu sonuç olarak elimizde olan queue listesidir.
AwsSqsUtil::createQueue('image_resize', true);
# Response (queue url)
https://sqs.eu-west-1.amazonaws.com/000000000000/APP_DEV_image_resize_DL
AwsSqsUtil::getQueueArn('https://sqs.eu-west-1.amazonaws.com/000000000000/APP_DEV_image_resize_DL');
# Response (queue arn)
arn:aws:sqs:eu-west-1:000000000000:APP_DEV_image_resize_DL
AwsSqsUtil::createQueue('image_resize', false, 'arn:aws:sqs:eu-west-1:000000000000:APP_DEV_image_resize_DL');
# Response (queue url)
https://sqs.eu-west-1.amazonaws.com/000000000000/APP_DEV_image_resize
Dead-letter redrive policy aşağıdaki gibi değişecektir.