Öğretici: Azure portalı ve konuları/abonelikleri kullanarak envanter güncelleştirme

Azure Service Bus, uygulamalar ve hizmetler arasında bilgi aktarımı sağlayan çok kiracılı bir bulut mesajlaşma hizmetidir. Zaman uyumsuz işlemler, esnek, aracılı mesajlaşmanın yanı sıra, ilk giren ilk çıkar (FIFO) yöntemiyle yapılandırılmış mesajlaşma ve yayımlama/abonelik olanakları da sunar. Azure Service Bus'a ayrıntılı genel bakış için bkz . Service Bus nedir?.

Bu öğretici, bir perakende stok senaryosunda, Azure portal ve .NET kullanan yayımlama/abonelik kanallarıyla Service Bus konu başlıklarını ve abonelikleri kullanmayı göstermektedir. Bu senaryonun bir örneği, birden çok perakende mağazası için stok sınıflama güncelleştirmesidir. Bu senaryoda, her mağaza veya mağaza grubu, sınıflamalarını güncelleştirmeye yönelik iletiler alır. Bu öğretici, bu senaryonun abonelikler ve filtreler kullanılarak uygulanmasını göstermektedir. İlk olarak, üç aboneliği olan bir konu başlığı oluşturur, bazı kurallar ve filtreler ekler ve ardından konu başlığı ve aboneliklerden ileti gönderip alırsınız.

Image showing a sender, a topic with three subscriptions, and three receivers.

Bu öğreticide aşağıdakilerin nasıl yapılacağını öğreneceksiniz:

  • Azure portalını kullanarak bir Service Bus konusu ve bu konuya üç abonelik oluşturma
  • .NET kodu kullanarak abonelikler için filtre ekleme
  • Farklı içeriğe sahip iletiler oluşturma
  • İleti gönderme ve beklenen aboneliklere ulaştıklarını doğrulama
  • Aboneliklerden ileti alma

Önkoşullar

Bu öğreticiyi tamamlamak için şunlar sahip olduğunuzdan emin olun:

  • Azure aboneliği. Azure Service Bus dahil olmak üzere Azure hizmetlerini kullanmak için bir aboneliğe ihtiyacınız vardır. Azure aboneliğiniz yoksa başlamadan önce ücretsiz bir hesap oluşturabilirsiniz.
  • Visual Studio 2019 veya üzeri.

Service Bus konu başlıkları ve abonelikler

Her konu başlığı aboneliği her iletinin bir kopyasını alabilir. Konular, protokol ve anlam açılarından Service Bus kuyrukları ile tam olarak uyumludur. Service Bus konu başlıkları, filtreleme koşullarını ve ileti özelliklerini belirleyen veya değiştiren isteğe bağlı eylemleri olan geniş bir seçim kuralı yelpazesini destekler. Bir kural eşleştiğinde bir ileti oluşturulur. Kurallar, filtreler ve eylemler hakkında daha fazla bilgi edinmek için bu bağlantıyı izleyin.

Azure portalında bir ad alanı oluşturma

Azure'da Service Bus mesajlaşma varlıklarını kullanmaya başlamak için öncelikle Azure'da benzersiz olan bir ad alanı oluşturmanız gerekir. Ad alanı, uygulamanızdaki Service Bus kaynakları (kuyruklar, konular vb.) için bir kapsam kapsayıcısı sağlar.

Ad alanı oluşturmak için:

  1. Azure Portal’ında oturum açın.

  2. Tüm hizmetler sayfasına gidin.

  3. Sol gezinti çubuğunda, kategoriler listesinden Tümleştirme'yi seçin, fareyi Service Bus'ın üzerine getirin ve ardından Service Bus kutucuğundaki düğmeyi seçin+.

    Image showing selection of Create a resource, Integration, and then Service Bus in the menu.

  4. Ad alanı oluştur sayfasının Temel bilgiler etiketinde şu adımları izleyin:

    1. Abonelik için ad alanının oluşturulacağı bir Azure aboneliği seçin.

    2. Kaynak grubu için, ad alanının yaşayacağı mevcut bir kaynak grubunu seçin veya yeni bir tane oluşturun.

    3. Ad alanı için bir ad girin. Ad alanı adı aşağıdaki adlandırma kurallarına uymalıdır:

      • Adın Azure genelinde benzersiz olması gerekir. Adın kullanılabilirliği sistem tarafından hemen denetlenir.
      • Ad uzunluğu en az 6 ve en fazla 50 karakterdir.
      • Ad yalnızca harf, sayı, kısa çizgi "-" içerebilir.
      • Ad bir harfle başlamalı ve bir harf veya numarayla bitmelidir.
      • Ad "-sb" veya "-mgmt" ile bitmiyor.
    4. Konum için ad alanınızın barındırılacağı bölgeyi seçin.

    5. Fiyatlandırma katmanı için ad alanı için fiyatlandırma katmanını (Temel, Standart veya Premium) seçin. Bu hızlı başlangıç için Standart'ı seçin.

      Önemli

      Konuları ve abonelikleri kullanmak istiyorsanız Standart veya Premium'u seçin. Konular/abonelikler Temel fiyatlandırma katmanında desteklenmez.

      Premium fiyatlandırma katmanını seçtiyseniz, mesajlaşma birimi sayısını belirtin. Premium katman, her iş yükünün yalıtılmış olarak çalışması için CPU ve bellek düzeyinde kaynak yalıtımı sağlar. Bu kaynak kapsayıcısı mesajlaşma birimi olarak adlandırılır. Premium ad alanında en az bir mesajlaşma birimi vardır. Her Service Bus Premium ad alanı için 1, 2, 4, 8 veya 16 mesajlaşma birimleri seçebilirsiniz. Daha fazla bilgi için bkz . Service Bus Premium Mesajlaşma.

    6. Sayfanın alt kısmındaki Gözden geçir ve oluştur'u seçin.

      Image showing the Create a namespace page

    7. Gözden geçir ve oluştur sayfasında ayarları gözden geçirin ve Oluştur'u seçin.

  5. Kaynağın dağıtımı başarılı olduktan sonra dağıtım sayfasında Kaynağa git'i seçin.

    Image showing the deployment succeeded page with the Go to resource link.

  6. Service Bus ad alanınızın giriş sayfasını görürsünüz.

    Image showing the home page of the Service Bus namespace created.

Ad alanına bağlantı dizesi alma (Azure portalı)

Yeni bir ad alanı oluşturmak otomatik olarak birincil ve ikincil anahtarlarla ilk Paylaşılan Erişim İmzası (SAS) ilkesini ve her birinin ad alanının tüm yönleri üzerinde tam denetim sağlayan birincil ve ikincil bağlantı dizesi oluşturur. Normal gönderenler ve alıcılar için daha kısıtlı haklara sahip kurallar oluşturma hakkında bilgi için bkz . Service Bus kimlik doğrulaması ve yetkilendirmesi .

İstemci, Service Bus ad alanına bağlanmak için bağlantı dizesi kullanabilir. Ad alanınızın birincil bağlantı dizesi kopyalamak için şu adımları izleyin:

  1. Service Bus Ad Alanı sayfasında soldaki menüden Paylaşılan erişim ilkeleri'ni seçin.

  2. Paylaşılan erişim ilkeleri sayfasında RootManageSharedAccessKey'i seçin.

  3. İlke: RootManageSharedAccessKey penceresinde Birincil Bağlan Ion Dizesi'nin yanındaki kopyala düğmesini seçerek bağlantı dizesi daha sonra kullanmak üzere panonuza kopyalayın. Bu değeri Not Defteri veya başka bir geçici konuma yapıştırın.

    Screenshot shows an S A S policy called RootManageSharedAccessKey, which includes keys and connection strings.

    Birincil anahtar, ikincil anahtar, birincil bağlantı dizesi ve ikincil bağlantı dizesi kopyalamak için bu sayfayı kullanabilirsiniz.

Azure portalını kullanarak konu oluşturma

  1. Service Bus Ad Alanı sayfasında, soldaki menüden Konular'ı seçin.

  2. Araç çubuğunda + Konu'ya tıklayın.

  3. Konu için bir ad girin. Diğer seçenekleri varsayılan değerlerinde bırakın.

  4. Oluştur'u belirleyin.

    Screenshot of the Create topic page.

Konu başlığına abonelik oluşturma

  1. Önceki bölümde oluşturduğunuz konuyu seçin.

    Screenshot of the Topics page with your topic selected.

  2. Service Bus Konusu sayfasında, soldaki menüden Abonelikler'ive ardından araç çubuğunda + Abonelik'i seçin.

    Screenshot of the Subscriptions page with the Add subscription button selected.

  3. Abonelik oluştur sayfasında şu adımları izleyin:

    1. Aboneliğin adı olarak S1 girin.

    2. Ardından, aboneliği oluşturmak için Oluştur'u seçin.

      Screenshot of the Create subscription page.

  4. S2 ve S3 adlı abonelikler oluşturmak için önceki adımı iki kez yineleyin.

Aboneliklerde filtre kuralları oluşturma

Ad alanı ve konu başlığı/abonelikler sağlandıktan ve ad alanında bağlantı dizesi sahip olduktan sonra aboneliklerde filtre kuralları oluşturmaya, ardından ileti gönderip almaya hazır olursunuz. Bu örnek GitHub klasöründeki kodu inceleyebilirsiniz.

İleti alma ve gönderme

Kodu çalıştırmak için şu adımları izleyin:

  1. Bir komut veya PowerShell komut isteminde aşağıdaki komutu göndererek Service Bus GitHub deposunu kopyalayın:

    git clone https://github.com/Azure/azure-service-bus.git
    
  2. Örnek klasörü azure-service-bus\samples\DotNet\Azure.Messaging.ServiceBus\BasicSendReceiveTutorialWithFilters gidin.

  3. Bu öğreticinin önceki bölümlerinde Not Defteri kopyaladığınız bağlantı dizesi edinin. Ayrıca önceki bölümde oluşturduğunuz konu adı da gerekir.

  4. Komut isteminde aşağıdaki komutu yazın:

    dotnet build
    
  5. BasicSendReceiveTutorialWithFilters\bin\Debug\netcoreapp3.1 klasörüne gidin.

  6. Programı çalıştırmak için aşağıdaki komutu yazın. myConnectionString yerine daha önce edindiğiniz değeri ve myTopicName yerine oluşturduğunuz konu başlığının adını koymayı unutmayın:

    dotnet --roll-forward Major BasicSendReceiveTutorialWithFilters.dll -ConnectionString "myConnectionString" -TopicName "myTopicName"
    
  7. İlk önce filtre oluşturmayı seçmek için konsoldaki yönergeleri izleyin. Varsayılan filtreleri kaldırmak filtre oluşturmanın bir parçasıdır. PowerShell veya CLI kullanırken varsayılan filtreyi kaldırmanız gerekmez, ancak bunu kodda yaparsanız, bunları kaldırmanız gerekir. 1 ve 3 konsol komutları, daha önce oluşturduğunuz aboneliklerdeki filtreleri yönetmenize yardımcı olur:

    • Varsayılan filtreleri kaldırmak için 1'i yürütün.

    • Kendi filtrelerini eklemek için 2'yi yürütün.

    • 3. Yürütme: Öğretici için bu adımı atlayın. Bu seçenek isteğe bağlı olarak kendi filtrelerinizi kaldırır. Varsayılan filtreleri yeniden oluşturmaz.

      Showing output of 2

  8. Filtre oluşturulduktan sonra ileti gönderebilirsiniz. 4'e basın ve konu başlığına gönderilen 10 iletiyi gözlemleyin:

    Send output

  9. 5'e basın ve alınan iletileri gözlemleyin. 10 iletiyi geri almadıysanız menüyü görüntülemek için "m" tuşuna basın, ardından yeniden 5 tuşuna basın.

    Receive output

Kaynakları temizleme

Artık gerekli olmadığında, kaynakları temizlemek için bu adımları izleyin.

  1. Azure portalında ad alanınıza gidin.
  2. Service Bus Ad Alanı sayfasında, komut çubuğundan Sil'i seçerek içindeki ad alanını ve kaynakları (kuyruklar, konular ve abonelikler) silin.

Örnek kodu anlama

Bu bölümde, örnek kodun yaptıkları hakkında daha fazla ayrıntı bulunmaktadır.

Bağlantı dizesini ve konu başlığını alma

Kod öncelikle programın geri kalanını yürüten bir dizi değişken bildirir.

string ServiceBusConnectionString;
string TopicName;

static string[] Subscriptions = { "S1", "S2", "S3" };
static IDictionary<string, string[]> SubscriptionFilters = new Dictionary<string, string[]> {
    { "S1", new[] { "StoreId IN('Store1', 'Store2', 'Store3')", "StoreId = 'Store4'"} },
    { "S2", new[] { "sys.To IN ('Store5','Store6','Store7') OR StoreId = 'Store8'" } },
    { "S3", new[] { "sys.To NOT IN ('Store1','Store2','Store3','Store4','Store5','Store6','Store7','Store8') OR StoreId NOT IN ('Store1','Store2','Store3','Store4','Store5','Store6','Store7','Store8')" } }
};
// You can have only have one action per rule and this sample code supports only one action for the first filter, which is used to create the first rule. 
static IDictionary<string, string> SubscriptionAction = new Dictionary<string, string> {
    { "S1", "" },
    { "S2", "" },
    { "S3", "SET sys.Label = 'SalesEvent'"  }
};
static string[] Store = { "Store1", "Store2", "Store3", "Store4", "Store5", "Store6", "Store7", "Store8", "Store9", "Store10" };
static string SysField = "sys.To";
static string CustomField = "StoreId";
static int NrOfMessagesPerStore = 1; // Send at least 1.

Bağlantı dizesi ve konu başlığı adı gösterildiği gibi komut satırı parametreleri aracılığıyla geçirilir ve ardından Main() yönteminde okunur:

static void Main(string[] args)
{
    string ServiceBusConnectionString = "";
    string TopicName = "";

    for (int i = 0; i < args.Length; i++)
    {
        if (args[i] == "-ConnectionString")
        {
            Console.WriteLine($"ConnectionString: {args[i + 1]}");
            ServiceBusConnectionString = args[i + 1]; // Alternatively enter your connection string here.
        }
        else if (args[i] == "-TopicName")
        {
            Console.WriteLine($"TopicName: {args[i + 1]}");
            TopicName = args[i + 1]; // Alternatively enter your queue name here.
        }
    }

    if (ServiceBusConnectionString != "" && TopicName != "")
    {
        Program P = StartProgram(ServiceBusConnectionString, TopicName);
        P.PresentMenu().GetAwaiter().GetResult();
    }
    else
    {
        Console.WriteLine("Specify -Connectionstring and -TopicName to execute the example.");
        Console.ReadKey();
    }
}

Varsayılan filtreleri kaldırma

Bir abonelik oluşturduğunuzda, Service Bus abonelik başına varsayılan birer filtre oluşturur. Bu filtre, konu başlığına gönderilen her iletiyi almayı etkinleştirir. Özel filtreler kullanmak istiyorsanız, aşağıdaki kodda gösterildiği gibi varsayılan filtreyi kaldırabilirsiniz:

private async Task RemoveDefaultFilters()
{
    Console.WriteLine($"Starting to remove default filters.");

    try
    {
        var client = new ServiceBusAdministrationClient(ServiceBusConnectionString);
        foreach (var subscription in Subscriptions)
        {
            await client.DeleteRuleAsync(TopicName, subscription, CreateRuleOptions.DefaultRuleName);
            Console.WriteLine($"Default filter for {subscription} has been removed.");
        }

        Console.WriteLine("All default Rules have been removed.\n");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }

    await PresentMenu();
}

Filtre oluşturma

Aşağıdaki kod, bu öğreticide tanımlanan özel filtreleri eklemektedir:

private async Task CreateCustomFilters()
{
    try
    {
        for (int i = 0; i < Subscriptions.Length; i++)
        {
            var client = new ServiceBusAdministrationClient(ServiceBusConnectionString);
            string[] filters = SubscriptionFilters[Subscriptions[i]];
            if (filters[0] != "")
            {
                int count = 0;
                foreach (var myFilter in filters)
                {
                    count++;

                    string action = SubscriptionAction[Subscriptions[i]];
                    if (action != "")
                    {
                        await client.CreateRuleAsync(TopicName, Subscriptions[i], new CreateRuleOptions
                        {
                            Filter = new SqlRuleFilter(myFilter),
                            Action = new SqlRuleAction(action),
                            Name = $"MyRule{count}"
                        });
                    }
                    else
                    {
                        await client.CreateRuleAsync(TopicName, Subscriptions[i], new CreateRuleOptions
                        {
                            Filter = new SqlRuleFilter(myFilter),
                            Name = $"MyRule{count}"
                        });
                    }
                }
            }

            Console.WriteLine($"Filters and actions for {Subscriptions[i]} have been created.");
        }

        Console.WriteLine("All filters and actions have been created.\n");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }

    await PresentMenu();
}

Özel oluşturulan filtrelerinizi kaldırma

Aboneliğinizdeki tüm filtreleri kaldırmak istiyorsanız, aşağıdaki kod bunun nasıl yapılacağını göstermektedir:

private async Task CleanUpCustomFilters()
{
    foreach (var subscription in Subscriptions)
    {
        try
        {
            var client = new ServiceBusAdministrationClient(ServiceBusConnectionString);
            IAsyncEnumerator<RuleProperties> rules = client.GetRulesAsync(TopicName, subscription).GetAsyncEnumerator();
            while (await rules.MoveNextAsync())
            {
                await client.DeleteRuleAsync(TopicName, subscription, rules.Current.Name);
                Console.WriteLine($"Rule {rules.Current.Name} has been removed.");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }
    Console.WriteLine("All default filters have been removed.\n");

    await PresentMenu();
}

İleti gönderme

Bir konu başlığına ileti göndermek bir kuyruğa ileti göndermeye benzer. Bu örnek, bir görev listesi ve zaman uyumsuz işleme kullanarak ileti göndermeyi göstermektedir:

public async Task SendMessages()
{
    try
    {
        await using var client = new ServiceBusClient(ServiceBusConnectionString);
        var taskList = new List<Task>();
        for (int i = 0; i < Store.Length; i++)
        {
            taskList.Add(SendItems(client, Store[i]));
        }

        await Task.WhenAll(taskList);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
    Console.WriteLine("\nAll messages sent.\n");
}

private async Task SendItems(ServiceBusClient client, string store)
{
    // create the sender
    ServiceBusSender tc = client.CreateSender(TopicName);

    for (int i = 0; i < NrOfMessagesPerStore; i++)
    {
        Random r = new Random();
        Item item = new Item(r.Next(5), r.Next(5), r.Next(5));

        // Note the extension class which is serializing an deserializing messages
        ServiceBusMessage message = item.AsMessage();
        message.To = store;
        message.ApplicationProperties.Add("StoreId", store);
        message.ApplicationProperties.Add("Price", item.GetPrice().ToString());
        message.ApplicationProperties.Add("Color", item.GetColor());
        message.ApplicationProperties.Add("Category", item.GetItemCategory());

        await tc.SendMessageAsync(message);
        Console.WriteLine($"Sent item to Store {store}. Price={item.GetPrice()}, Color={item.GetColor()}, Category={item.GetItemCategory()}"); ;
    }
}

İleti alma

İletiler de bir görev listesi aracılığıyla alınmakta ve kod toplu işlem kullanmaktadır. İletileri toplu işlem kullanarak gönderip alabilirsiniz, ancak bu örnek yalnızca toplu almayı göstermektedir. Gerçekte, döngüden ayrılmazsınız, ancak döngüye devam edin ve bir dakika gibi daha yüksek bir zaman aralığı ayarlayın. Aracıya yapılan alma çağrısı bu süre boyunca açık tutulur ve iletiler gelirse hemen döndürülür ve yeni bir alma çağrısı verilir. Bu kavrama uzun süreli yoklama denir. Hızlı başlangıçta ve depodaki diğer birkaç örnekte görebileceğiniz alma pompasını kullanmak daha tipik bir seçenektir.

public async Task Receive()
{
    var taskList = new List<Task>();
    for (var i = 0; i < Subscriptions.Length; i++)
    {
        taskList.Add(this.ReceiveMessages(Subscriptions[i]));
    }

    await Task.WhenAll(taskList);
}

private async Task ReceiveMessages(string subscription)
{
    await using var client = new ServiceBusClient(ServiceBusConnectionString);
    ServiceBusReceiver receiver = client.CreateReceiver(TopicName, subscription);

    // In reality you would not break out of the loop like in this example but would keep looping. The receiver keeps the connection open
    // to the broker for the specified amount of seconds and the broker returns messages as soon as they arrive. The client then initiates
    // a new connection. So in reality you would not want to break out of the loop. 
    // Also note that the code shows how to batch receive, which you would do for performance reasons. For convenience you can also always
    // use the regular receive pump which we show in our Quick Start and in other GitHub samples.
    while (true)
    {
        try
        {
            //IList<Message> messages = await receiver.ReceiveAsync(10, TimeSpan.FromSeconds(2));
            // Note the extension class which is serializing an deserializing messages and testing messages is null or 0.
            // If you think you did not receive all messages, just press M and receive again via the menu.
            IReadOnlyList<ServiceBusReceivedMessage> messages = await receiver.ReceiveMessagesAsync(maxMessages: 100);

            if (messages.Any())
            {
                foreach (ServiceBusReceivedMessage message in messages)
                {
                    lock (Console.Out)
                    {
                        Item item = message.As<Item>();
                        IReadOnlyDictionary<string, object> myApplicationProperties = message.ApplicationProperties;
                        Console.WriteLine($"StoreId={myApplicationProperties["StoreId"]}");
                        if (message.Subject != null)
                        {
                            Console.WriteLine($"Subject={message.Subject}");
                        }
                        Console.WriteLine(
                            $"Item data: Price={item.GetPrice()}, Color={item.GetColor()}, Category={item.GetItemCategory()}");
                    }

                    await receiver.CompleteMessageAsync(message);
                }
            }
            else
            {
                break;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }
}

Not

Service Bus kaynaklarını Service Bus Gezgini ile yönetebilirsiniz. Service Bus Gezgini, kullanıcıların bir Service Bus ad alanına bağlanmasına ve mesajlaşma varlıklarını kolay bir şekilde yönetmesine olanak tanır. Araç içeri/dışarı aktarma işlevselliği veya konu başlığı, kuyruklar, abonelikler, geçiş hizmetleri, bildirim hub'ları ve olay hub'ları gibi gelişmiş özellikler sağlar.

Sonraki adımlar

Bu öğreticide Azure portalı kullanarak kaynaklar sağladınız, sonra bir Service Bus konu başlığından ve bunun aboneliklerinden iletiler gönderip aldınız. Şunları öğrendiniz:

  • Azure portalı kullanarak bir Service Bus konu başlığı ve bunun için bir veya daha fazla abonelik oluşturma
  • .NET kodu kullanarak konu filtreleri ekleme
  • Farklı içerikle iki ileti oluşturma
  • İletileri gönderme ve bunların beklenen aboneliklere vardığını doğrulama
  • Aboneliklerden ileti alma

Daha fazla ileti gönderme ve alma örneği için GitHub’daki Service Bus örnekleri ile çalışmaya başlayın.

Service Bus’ın yayımlama/abone olma özelliklerini kullanma hakkında daha fazla bilgi edinmek için bir sonraki öğreticiye ilerleyin.