Kurz: Aktualizace zásob pomocí portálu Azure Portal a témat/odběrů

Azure Service Bus je víceklientská cloudová služba pro zasílání zpráv, která odesílá informace mezi aplikacemi a službami. Asynchronní operace umožňují flexibilní zprostředkované zasílání zpráv a také strukturované zasílání zpráv typu FIFO (first-in-first-out) a funkce pro publikování a přihlášení k odběru. Podrobný přehled služby Azure Service Bus najdete v tématu Co je Service Bus?

Tento kurz ukazuje, jak můžete témata a odběry ve službě Service Bus využít ve scénáři aktualizace maloobchodních zásob. Pracuje se při tom s kanály publikování a přihlášení k odběru s využitím portálu Azure Portal a rozhraní .NET. V tomto scénáři pracujeme s příkladem aktualizace sortimentu zásob pro několik prodejen. Každá prodejna nebo sada prodejen v našem příkladu přijímá zprávy s pokyny, jak konkrétně má aktualizovat sortiment. Tento kurz vysvětluje, jak tento scénář využívající odběry a filtry implementujete. Nejprve vytvoříte téma se třemi odběry, přidáte některá pravidla a filtry a pak odešlete a přijmete zprávy z tématu a odběrů.

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

V tomto kurzu se naučíte:

  • Vytvoření tématu služby Service Bus a tří odběrů pro toto téma pomocí webu Azure Portal
  • Přidání filtrů pro předplatná pomocí kódu .NET
  • Vytváření zpráv s jiným obsahem
  • Odesílání zpráv a ověření doručení do očekávaných odběrů
  • Přijímat zprávy z odběrů

Požadavky

Abyste mohli absolvovat tento kurz, ujistěte se, že máte následující:

  • Předplatné Azure. Pokud chcete používat služby Azure, včetně Služby Azure Service Bus, potřebujete předplatné. Pokud ještě nemáte předplatné Azure, můžete si vytvořit bezplatný účet před tím, než začnete.
  • Visual Studio 2019 nebo novější

Témata a odběry služby Service Bus

Každý odběr tématu může přijímat kopie všech zpráv. Témata jsou co do protokolu a sémantiky plně kompatibilní s frontami služby Service Bus. Témata služby Service Bus podporují širokou škálu pravidel pro výběr s podmínkami filtrů, včetně volitelných akcí, kterými se nastavují nebo upravují vlastnosti zprávy. Při každé shodě s pravidlem se vytvoří zpráva. Další informace o pravidlech, filtrech a akcích získáte pomocí tohoto odkazu.

Vytvoření oboru názvů na webu Azure Portal

Pokud chcete začít používat entity zasílání zpráv služby Service Bus v Azure, musíte nejprve vytvořit obor názvů s jedinečným názvem v rámci Azure. Obor názvů poskytuje kontejner oborů pro prostředky služby Service Bus (fronty, témata atd.) v rámci vaší aplikace.

Vytvoření oboru názvů:

  1. Přihlaste se k portálu Azure.

  2. Přejděte na stránku Všechny služby.

  3. Na levém navigačním panelu vyberte Možnost Integrace ze seznamu kategorií, najeďte myší na Service Bus a pak vyberte + tlačítko na dlaždici Service Bus.

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

  4. Na stránce Základy na stránce Vytvořit obor názvů postupujte takto:

    1. V části Předplatné zvolte předplatné Azure, ve kterém chcete vytvořit obor názvů.

    2. V části Skupina prostředků zvolte existující skupinu prostředků, ve které bude obor názvů aktivní, nebo vytvořte novou.

    3. Zadejte název oboru názvů. Název oboru názvů by měl dodržovat následující zásady vytváření názvů:

      • Název musí být jedinečný v rámci Azure. Systém okamžitě kontroluje, jestli je název dostupný.
      • Délka názvu je nejméně 6 a maximálně 50 znaků.
      • Název může obsahovat pouze písmena, číslice, pomlčky -.
      • Název musí začínat písmenem a končit písmenem nebo číslem.
      • Název nekončí "-sb" nebo "-mgmt".
    4. V části Umístění zvolte oblast, ve které má být váš obor názvů hostovaný.

    5. V části Cenová úroveň vyberte cenovou úroveň (Basic, Standard nebo Premium) pro obor názvů. Pro účely tohoto rychlého startu vyberte Standard.

      Důležité

      Pokud chcete použít témata a předplatná, zvolte Standard nebo Premium. Témata nebo předplatná se nepodporují v cenové úrovni Basic.

      Pokud jste vybrali cenovou úroveň Premium , zadejte počet jednotek zasílání zpráv. Úroveň Premium poskytuje izolaci prostředků na úrovni procesoru a paměti, aby každá úloha běžela izolovaně. Kontejner prostředků se nazývá jednotka zasílání zpráv. Obor názvů premium má alespoň jednu jednotku zasílání zpráv. Pro každý obor názvů služby Service Bus Premium můžete vybrat 1, 2, 4, 8 nebo 16 jednotek zasílání zpráv. Další informace najdete v tématu Zasílání zpráv Service Bus Premium.

    6. Vyberte Zkontrolovat a vytvořit v dolní části stránky.

      Image showing the Create a namespace page

    7. Na stránce Zkontrolovat a vytvořit zkontrolujte nastavení a vyberte Vytvořit.

  5. Po úspěšném nasazení prostředku vyberte na stránce nasazení možnost Přejít k prostředku .

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

  6. Zobrazí se domovská stránka vašeho oboru názvů služby Service Bus.

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

Získání připojovací řetězec k oboru názvů (Azure Portal)

Vytvoření nového oboru názvů automaticky vygeneruje počáteční zásadu sdíleného přístupového podpisu (SAS) s primárními a sekundárními klíči a primárními a sekundárními připojovací řetězec, které každý z nich uděluje úplnou kontrolu nad všemi aspekty oboru názvů. Informace o vytváření pravidel s omezenými právy pro běžné odesílatele a příjemce najdete v tématu Ověřování a autorizace služby Service Bus.

Klient se může pomocí připojovací řetězec připojit k oboru názvů služby Service Bus. Pokud chcete zkopírovat primární připojovací řetězec pro váš obor názvů, postupujte takto:

  1. Na stránce Obor názvů služby Service Bus vyberte v nabídce vlevo zásady sdíleného přístupu.

  2. Na stránce Zásady sdíleného přístupu vyberte RootManageSharedAccessKey.

  3. V okně Zásady: RootManageSharedAccessKey vyberte tlačítko kopírování vedle primárního Připojení ion String a zkopírujte připojovací řetězec do schránky pro pozdější použití. Vložte tuto hodnotu do Poznámkového bloku nebo jiného dočasného umístění.

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

    Na této stránce můžete kopírovat primární klíč, sekundární klíč, primární připojovací řetězec a sekundární připojovací řetězec.

Vytvoření tématu pomocí webu Azure Portal

  1. Na stránce Obor názvů služby Service Bus vyberte Témata v nabídce vlevo.

  2. Na panelu nástrojů vyberte + Téma .

  3. Zadejte název tématu. U ostatních možností ponechte jejich výchozí hodnoty.

  4. Vyberte Vytvořit.

    Screenshot of the Create topic page.

Vytvoření odběrů tématu

  1. Vyberte téma, které jste vytvořili v předchozí části.

    Screenshot of the Topics page with your topic selected.

  2. Na stránce Téma služby Service Bus vyberte v nabídce vlevo předplatná a pak na panelu nástrojů vyberte + Předplatné.

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

  3. Na stránce Vytvořit předplatné postupujte takto:

    1. Jako název předplatného zadejte S1.

    2. Potom vyberte Vytvořit a vytvořte předplatné.

      Screenshot of the Create subscription page.

  4. Opakováním předchozího kroku dvakrát vytvořte předplatná s názvem S2 a S3.

Vytvoření pravidel filtrů u odběrů

Po zřízení oboru názvů a témat nebo odběrů a máte připojovací řetězec do oboru názvů, jste připraveni vytvořit pravidla filtru pro odběry a pak odesílat a přijímat zprávy. Kód můžete zkontrolovat v této složce s ukázkami na GitHubu.

Odesílání a příjem zpráv

Kód spustíte takto:

  1. V příkazovém řádku nebo v příkazovém řádku PowerShellu naklonujte pomocí následujícího příkazu úložiště Service Bus na GitHubu:

    git clone https://github.com/Azure/azure-service-bus.git
    
  2. Přejděte do složky s ukázkou azure-service-bus\samples\DotNet\Azure.Messaging.ServiceBus\BasicSendReceiveTutorialWithFilters.

  3. Získejte připojovací řetězec, které jste zkopírovali do Poznámkový blok dříve v tomto kurzu. Budete potřebovat také název tématu, které jste vytvořili v předchozí části.

  4. Do příkazového řádku zadejte následující příkaz:

    dotnet build
    
  5. Přejděte do složky BasicSendReceiveTutorialWithFilters\bin\Debug\netcoreapp3.1.

  6. Zadáním následujícího příkazu spusťte program. myConnectionString nezapomeňte nahradit hodnotou, kterou jste předtím získali, a myTopicName názvem tématu, které jste vytvořili:

    dotnet --roll-forward Major BasicSendReceiveTutorialWithFilters.dll -ConnectionString "myConnectionString" -TopicName "myTopicName"
    
  7. Podle pokynů v konzole nejprve vyberte vytvoření filtru. Součástí vytváření filtrů je odebrání výchozích filtrů. Pokud používáte PowerShell nebo rozhraní příkazového řádku, nemusíte odebírat výchozí filtr, ale pokud to uděláte v kódu, musíte je odebrat. Příkazy konzoly 1 a 3 vám pomůžou se správou filtrů u odběrů, které jste už vytvořili:

    • Příkaz 1 slouží k odebrání výchozích filtrů.

    • Příkazem 2 můžete přidat vlastní filtry.

    • Spusťte 3: Tento krok pro kurz přeskočte. Tato možnost volitelně odebere vlastní filtry. Výchozí filtry se znovu nevytvářet.

      Showing output of 2

  8. Po vytvoření filtru můžete odesílat zprávy. Stiskněte klávesu 4 a sledujte, jak se do tématu odešle 10 zpráv:

    Send output

  9. Stiskněte klávesu 5 a sledujte příjem zprávy. Pokud jste zpátky nedostali 10 zpráv, stisknutím klávesy "m" zobrazte nabídku a pak znovu stiskněte 5.

    Receive output

Vyčištění prostředků

Pokud už prostředky nepotřebujete, vyčistěte prostředky podle těchto kroků.

  1. Na webu Azure Portal přejděte do svého oboru názvů.
  2. Na stránce Obor názvů služby Service Bus vyberte z panelu příkazů odstranit obor názvů a prostředky (fronty, témata a odběry).

Vysvětlení vzorového kódu

Tato část obsahuje další podrobnosti o chování ukázkového kódu.

Získání připojovacího řetězce a tématu

Nejprve kód deklaruje sadu proměnných, které řídí další provádění programu.

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.

Připojovací řetězec a název tématu se předají prostřednictvím parametrů příkazového řádku, jak je vidět v ukázce, a pak se načtou v metodě Main():

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();
    }
}

Odebrání výchozích filtrů

Při vytváření odběru pro něj služba Service Bus vytvoří výchozí filtr. Ten umožňuje příjem všech zpráv odeslaných do tématu. Pokud chcete použít vlastní filtry, můžete výchozí filtr odebrat, jak je vidět v následujícím kódu:

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();
}

Vytváření filtrů

Následujícím kódem přidáte vlastní filtry definované v tomto kurzu:

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();
}

Odebrání vašich vlastních filtrů

Pokud u odběru chcete odebrat všechny filtry, použijte následující kód:

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();
}

Odesílání zpráv

Odeslání zprávy do tématu je podobné jako odesílání zpráv do fronty. Tento příklad ukazuje, jak odesílat zprávy pomocí seznamu úloh a asynchronního zpracování:

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()}"); ;
    }
}

Příjem zpráv

Zprávy se přijímají zase prostřednictvím seznamu úloh a kód využívá dávkové zpracování. Pomocí dávkování můžete zprávy odesílat i přijímat, tento příklad ale ukazuje jenom postup při dávkovém příjmu. Ve skutečnosti byste smyčku neprolomili, ale zachovali smyčku a nastavili vyšší časový rozsah, například jednu minutu. Příjem volání do zprostředkovatele je po tuto dobu otevřené a pokud zprávy dorazí, vrátí se okamžitě a vydá se nový přijatý hovor. Tato technika se označuje jako dlouhé intervaly dotazování. Použití čerpadla pro příjem, které můžete vidět v rychlém startu, a v několika dalších ukázkách v úložišti je typická možnost.

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());
        }
    }
}

Poznámka:

Prostředky služby Service Bus můžete spravovat pomocí Service Bus Exploreru. Service Bus Explorer umožňuje uživatelům připojit se k oboru názvů služby Service Bus a snadno spravovat entity zasílání zpráv. Nástroj poskytuje pokročilé funkce, jako jsou funkce importu a exportu nebo možnost testovat téma, fronty, odběry, předávací služby, centra oznámení a centra událostí.

Další kroky

V tomto kurzu jste zřídili prostředky na portálu Azure Portal a poté odesílali a přijímali zprávy z tématu služby Service Bus a jeho odběrů. Naučili jste se:

  • Pomocí portálu Azure Portal vytvořit téma služby Service Bus a k němu jeden nebo více odběrů
  • Přidávat filtry témat pomocí kódu .NET
  • Vytvořit dvě zprávy s různým obsahem
  • Odeslat zprávy a ověřit, že dorazily do očekávaných odběrů
  • Přijímat zprávy z odběrů

Pokud vás zajímají další příklady odesílání a přijímání zpráv, pomůžou vám začít ukázky služby Service Bus na GitHubu.

Přejděte k dalšímu kurzu, kde se dozvíte více o možnostech publikování a přihlášení k odběru ve službě Service Bus.