Yazılım Mimarileri ve Tasarım Desenleri Üzerine

Amazon SQS & Asp.NET Core – Scalable Messaging

Merhaba,

Biliyorsunuz ki, bir yazılım için önem arz eden birçok faktör arasından ölçeklenebilirlik ve güvenilir mesajlaşma yapılanması oldukça kritik arz etmektedir. Bu ihtiyaçlara karşın kullanabileceğimiz muhtelif teknolojiler olmasının yanında Amazon SQS’de imdadımıza yetişmekte ve oldukça esnek ve güçlü bir şekilde web ve mobil uygulamalar için alternatif olarak değerlendirilebilmektedir. Bu içeriğimizde Amazon SQS hakkında temel kavramları ve mimarisel yapıyı inceleyecek, .NET uygulamalarıyla nasıl entegre edileceği üzerine bir çalışma gerçekleştiriyor olacağız. O halde buyurun Amazon SQS ile .NET’in gücünü birlikte keşfetmeye başlayalım.

Amazon SQS(Amazon Simple Queue Service) Nedir?

Amazon SQS, AWS’nin genellikle microservice, distributed yahut event-driven mimarilerini kullanan uygulamalarda mesajların güvenli bir şekilde gönderilmesi, alınması ve saklanması için geliştirmiş olduğu yönetilebilir, yüksek düzeyde kullanılabilir, ölçeklenebilir, serverless bir servisidir. Oldukça uygun maliyetlerde kullanılabilir olan Amazon SQS, standart kuyruk yapılanmaları yanında FIFO davranış sergileyen kuyruk mimarisi sunabilmekte; AWS Lambda, EC2 ve diğer AWS servisleri ile kolayca entegre edilebilmektedir.

Amazon SQS’in Temel Kavramları Nelerdir?

Bu görsel https://codewithmukesh.com/blog/amazon-sqs-and-aspnet-core/ adresinden alınmıştır.

Amazon SQS’de queue ve message processing olmak üzere birbirleriyle yakından ilişkili olan iki temel kavram mevcuttur. Bu kavramları değerlendirirsek eğer;

Amazon SQS’in Avantajları Nelerdir?

Amazon SQS’in, RabbitMQ ve Kafka gibi diğer mesajlaşma sistemlerine kıyasla çeşitli avantajları mevcuttur. Bu avantajlar, belirli senaryolarda Amazon SQS’i daha cazip hale getirebilmektedirler. İşte Amazon SQS’in birkaç öne çıkan avantajları;

Amazon SQS’in Kullanımı

Şimdi Amazon SQS’i nasıl kullanabileceğimizi inceliyor olacağız. Bu incelemeyi hem AWS üzerinden gerçekleştireceğiz hem de Asp.NET Core uygulamaları üzerinden. İlk olarak AWS’de bir kuyruğun nasıl oluşturulup kullanılabileceğini değerlendireceğiz. Bu aşamadan sonra artık olayı programatik ele alacak ve biri producer diğeri consumer olmak üzere iki Asp.NET Core uygulaması oluşturacağız. Haliyle planlama belli. O halde hadi başlayalım.

MassTransit Entegrasyonu

Tabi eğer ki sahada bir message broker kullanılıyorsa bunu burada yaptığımız gibi manuel bir şekilde yapılandırıp kullanmaktansa türlü avantajlar ve sebeplerden dolayı bir Enterprise Service Bus (ESB) kullanmayı tercih ederiz. Ee haliyle ESB deyince de akla ilk gelen MassTransit kütüphanesi olacağından dolayı Amazon SQS’i MassTransit’le nasıl kullanabileceğimizi de inceleyip öyle içeriğimizi noktalayacağız. Aksi taktirde Amazon SQS ile MassTransit’i tecrübe etmeksizin bu içeriği noktalamak ciddi eksiklik olacaktır.

Bunun için öncelikle aşağıdaki paketi Shared projesine yükleyelim.
Install-Package MassTransit.AmazonSQS

Ardından producer’ın ‘Program.cs’ dosyasında aşağıdaki yapılandırmada bulunalım.

#region MassTransit
builder.Services.AddMassTransit(configurator =>
{
    configurator.UsingAmazonSqs((context, _configurator) =>
    {
        _configurator.Host(Amazon.RegionEndpoint.APSouth1.OriginalSystemName, hostConfigurator =>
        {
            hostConfigurator.AccessKey(builder.Configuration["AWS:AccessKey"]);
            hostConfigurator.SecretKey(builder.Configuration["AWS:SecretKey"]);
        });
    });
});
#endregion

Ve mesaj gönderebilmek için de aşağıdaki gibi bir action oluşturalım.

#region MassTransit
app.MapGet("/create-order-masstransit", async (IPublishEndpoint publishEndpoint, ISendEndpointProvider sendEndpointProvider) =>
{
    OrderCreatedEvent orderCreatedEvent = new()
    {
        CustomerId = Guid.NewGuid(),
        OrderId = Guid.NewGuid()
    };

    #region Publish
    //await publishEndpoint.Publish(orderCreatedEvent);
    #endregion

    #region Send
    var sendEndpoint = await sendEndpointProvider.GetSendEndpoint(new Uri($"queue:masstransit-order-created-event-queue"));
    await sendEndpoint.Send(orderCreatedEvent);
    #endregion

    return Results.Ok();
});
#endregion

Benzer mantıkla consumer’ın ‘Program.cs’ dosyasında da yapılandırmada bulunmamız gerekmektedir.

#region MassTransit
builder.Services.AddMassTransit(configurator =>
{
    configurator.AddConsumer<Consumers.OrderCreatedEventConsumer>().Endpoint(e => e.InstanceId = "queue");

    configurator.UsingAmazonSqs((context, _configurator) =>
    {
        _configurator.Host(Amazon.RegionEndpoint.APSouth1.OriginalSystemName, hostConfigurator =>
        {
            hostConfigurator.AccessKey(builder.Configuration["AWS:AccessKey"]);
            hostConfigurator.SecretKey(builder.Configuration["AWS:SecretKey"]);
        });

        _configurator.ConfigureEndpoints(context, new KebabCaseEndpointNameFormatter("masstransit", false));
    });
});
#endregion

Burada MassTransit konfigürasyonu açısından önceki içeriklerimizden tecrübe ettiklerimizin dışında Endpoint ve ConfigureEndpoints metotlarıyla birlikte KebabCaseEndpointNameFormatter sınıfını görmekteyiz. Hemen bunların izahını yaparsak eğer;

Velhasıl, şimdi de OrderCreatedEvent‘i tüketecek olan consumer’ı oluşturalım.

    public class OrderCreatedEventConsumer : IConsumer<OrderCreatedEvent>
    {
        public Task Consume(ConsumeContext<OrderCreatedEvent> context)
        {
            Console.WriteLine($"{context.Message.OrderId} - {context.Message.CustomerId}");
            return Task.CompletedTask;
        }
    }

Makale boyunca AWS kanadında işlemlerin gerçekleştirilebilmesi için IAM servisinde gerekli olan AmazonSNSFullAccess ve AmazonSQSFullAccess izinlerini kapsayan politikanın yapılandırılması ve permissions boundary olarak da AdministratorAccess belirlenmesi gerekmektedir. Ya da aşağıdaki gibi komple IAM Politikalarının kullanılması yeterlidir…

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "SqsAccess",
            "Effect": "Allow",
            "Action": [
                "sqs:SetQueueAttributes",
                "sqs:ReceiveMessage",
                "sqs:CreateQueue",
                "sqs:DeleteMessage",
                "sqs:SendMessage",
                "sqs:GetQueueUrl",
                "sqs:GetQueueAttributes",
                "sqs:ChangeMessageVisibility",
                "sqs:PurgeQueue",
                "sqs:DeleteQueue",
                "sqs:TagQueue"
            ],
            "Resource": "arn:aws:sqs:*:YOUR_ACCOUNT_ID:*"
        },{
            "Sid": "SnsAccess",
            "Effect": "Allow",
            "Action": [
                "sns:GetTopicAttributes",
                "sns:CreateTopic",
                "sns:Publish",
                "sns:Subscribe"
            ],
            "Resource": "arn:aws:sns:*:YOUR_ACCOUNT_ID:*"
        },{
            "Sid": "SnsListAccess",
            "Effect": "Allow",
            "Action": [
                "sns:ListTopics"
            ],
            "Resource": "*"
        }
    ]
}

Ve son olarak her iki uygulamanın ‘appsettings.json’ dosyasında aşağıdaki yapılandırmalarda bulunalım;

  "AWS": {
    "Profile": "sqs-profile",
    "Region": "ap-south-1",
    "AccessKey": "***",
    "SecretKey": "***"
  }

İşte bu yapılandırmalar ve çalışmalardan sonra uygulamayı topyekün derleyip çalıştırdığımızda MassTransit aracılığıyla başarılı bir haberleşmenin sağlandığını tecrübe etmiş olacağız.

İçerik boyunca oluşturduğumuz kuyruklara göz atarsak eğer aşağıdaki gibi gözükecektir.

Nihai olarak;
Amazon SQS hakkında bilgi edinmiş ve kuyruk yapısına dair temel kavramları keşfetmiş bulunuyoruz. Artık ihtiyaç noktalarında RabbitMQ ve Kafka teknolojilerine karşın Amazon SQS’i bir alternatif olarak değerlendirebilir ve Amazon’un sunduğu avantajlardan istifade edebiliriz.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar..

Not : Örnek çalışmanın github adresine aşağıdan erişebilirsiniz.
https://github.com/gncyyldz/AmazonSQS.Example

Mobil sürümden çık