Dela via


Självstudie: Uppdatera lagret med Azure-portalen och ämnen/prenumerationer

Azure Service Bus är en meddelandetjänst i molnet för flera klienter som skickar information mellan program och tjänster. Asynkrona åtgärder ger dig en flexibel, asynkron meddelandetjänst med funktioner för strukturerade meddelanden enligt FIFO-metoden (först-in-först-ut) och funktioner för publicering/prenumeration. Detaljerad översikt över Azure Service Bus finns i Vad är Service Bus?.

Den här kursen visar hur du använder Service Bus-ämnen och prenumerationer i ett scenario med butikslager, med publicera/prenumerera kanaler med Azure-portalen och .NET. Ett exempel på det här scenariot är en uppdatering av lagersortimentet för flera butiker. I det här scenariot, får varje butik eller uppsättning butiker meddelanden för att uppdatera sina sortiment. Den här självstudien visar hur du implementerar det här scenariot med prenumerationer och filter. Först skapar du ett ämne med tre prenumerationer, lägger till några regler och filter och skickar och tar sedan emot meddelanden från ämnet och prenumerationerna.

Bild som visar en avsändare, ett ämne med tre prenumerationer och tre mottagare.

I den här självstudien lär du dig att:

  • Skapa ett Service Bus-ämne och tre prenumerationer på det ämnet med hjälp av Azure-portalen
  • Lägga till filter för prenumerationer med hjälp av .NET-kod
  • Skapa meddelanden med olika innehåll
  • Skicka meddelanden och kontrollera att de kom till de förväntade prenumerationerna
  • Ta emot meddelanden från prenumerationerna

Förutsättningar

För att kunna följa den här självstudien måste du ha:

  • Azure-prenumeration. Om du vill använda Azure-tjänster, inklusive Azure Service Bus, behöver du en prenumeration. Om du inte har någon Azure-prenumeration kan du skapa ett kostnadsfritt konto innan du börjar.
  • Visual Studio 2019 eller senare.

Service Bus-ämnen och prenumerationer

Varje prenumeration på ett ämne får en kopia av varje meddelande. Ämnen är fullständigt protokollmässigt och semantiskt kompatibla med Service Bus-köer. Service Bus-ämnen stöder en mängd olika urvalsregler med filtervillkor, med valfria åtgärder som anger eller ändrar meddelandeegenskaperna. Varje gång en regel matchar så genererar den ett meddelande. Mer information om regler, filter och åtgärder, finns på den här länken.

Skapa ett namnområde i Azure Portal

För att komma igång med Service Bus-meddelandeentiteter i Azure måste du först skapa ett namnområde med ett namn som är unikt i Azure. Ett namnområde tillhandahåller en omfångscontainer för Service Bus-resurser (köer, ämnen osv.) i ditt program.

Så här skapar du ett namnområde:

  1. Logga in på Azure-portalen.

  2. Gå till sidan Alla tjänster.

  3. I det vänstra navigeringsfältet väljer du Integrering i listan över kategorier, hovra musen över Service Bus och välj + sedan knappen på Service Bus-panelen.

    Bild som visar val av Skapa en resurs, Integrering och sedan Service Bus på menyn.

  4. Följ dessa steg i taggen Grundläggande på sidan Skapa namnområde:

    1. För Prenumeration väljer du en Azure-prenumeration där du ska skapa namnrymden.

    2. För Resursgrupp väljer du en befintlig resursgrupp där namnrymden ska finnas, eller så skapar du en ny.

    3. Ange ett namn för namnrymden. Namnområdesnamnet bör följa följande namngivningskonventioner:

      • Namnet måste vara unikt i Hela Azure. Systemet kontrollerar omedelbart om namnet är tillgängligt.
      • Namnlängden är minst 6 och högst 50 tecken.
      • Namnet får endast innehålla bokstäver, siffror, bindestreck "-".
      • Namnet måste börja med en bokstav och sluta med en bokstav eller siffra.
      • Namnet slutar inte med "-sb" eller "-mgmt".
    4. För Plats väljer du land eller region där namnrymden ska finnas.

    5. För Prisnivå väljer du prisnivån (Basic, Standard eller Premium) för namnområdet. För den här snabbstarten väljer du Standard.

      Viktigt!

      Om du vill använda ämnen och prenumerationer väljer du antingen Standard eller Premium. Ämnen/prenumerationer stöds inte på prisnivån Basic.

      Om du har valt prisnivån Premium anger du antalet meddelandeenheter. Premium-nivån ger resursisolering på processor- och minnesnivå så att varje arbetsbelastning körs självständigt. Den här resurscontainern kallas för en meddelandefunktionsenhet. Ett premiumnamnområde har minst en meddelandeenhet. Du kan välja 1, 2, 4, 8 eller 16 meddelandeenheter för varje Service Bus Premium-namnområde. Mer information finns i Service Bus Premium-meddelanden.

    6. Välj Granska + skapa längst ned på sidan.

      Bild som visar sidan Skapa ett namnområde

    7. På sidan Granska + skapa granskar du inställningarna och väljer Skapa.

  5. När distributionen av resursen har slutförts väljer du Gå till resurs på distributionssidan.

    Bild som visar sidan distributionen lyckades med länken Gå till resurs.

  6. Startsidan för din Service Bus-namnrymd visas.

    Bild som visar startsidan för Service Bus-namnområdet som skapats.

Hämta niska veze till namnområdet (Azure-portalen)

När du skapar ett nytt namnområde genereras automatiskt en inledande SAS-princip (Signatur för delad åtkomst) med primära och sekundära nycklar och primära och sekundära niska veze som var och en ger fullständig kontroll över alla aspekter av namnområdet. Se Service Bus – autentisering och auktorisering för mer information om hur du skapar regler med mer begränsade rättigheter för regelbundna sändare och mottagare.

En klient kan använda niska veze för att ansluta till Service Bus-namnområdet. Följ dessa steg för att kopiera den primära niska veze för ditt namnområde:

  1. På sidan Service Bus-namnområde väljer du Principer för delad åtkomst på den vänstra menyn.

  2. På sidan Principer för delad åtkomst väljer du RootManageSharedAccessKey.

  3. I fönstret Princip: RootManageSharedAccessKey väljer du kopieringsknappen bredvid Primär anslutningssträng för att kopiera niska veze till Urklipp för senare användning. Klistra in det här värdet i Anteckningar eller på en tillfällig plats.

    Skärmbild som visar en S A S-princip med namnet RootManageSharedAccessKey, som innehåller nycklar och niska veze.

    Du kan använda den här sidan för att kopiera primärnyckel, sekundär nyckel, primär niska veze och sekundär niska veze.

Skapa ett ämne med Azure Portal

  1. På sidan Service Bus Namespace (Service Bus-namnrymd) väljer du Ämnen på den vänstra menyn.

  2. Välj + Ämne i verktygsfältet.

  3. Ange ett namn för ämnet. Lämna standardvärdena för de andra alternativen.

  4. Välj Skapa.

    Skärmbild av sidan Skapa ämne.

Skapa prenumerationer på ämnet

  1. Välj det ämne som du skapade i föregående avsnitt.

    Skärmbild av sidan Ämnen med ditt ämne valt.

  2. På sidan Service Bus-ämne väljer du Prenumerationer från den vänstra menyn och sedan + Prenumeration i verktygsfältet.

    Skärmbild av sidan Prenumerationer med knappen Lägg till prenumeration markerad.

  3. Följ dessa steg på sidan Skapa prenumeration :

    1. Ange S1 som namn på prenumerationen.

    2. Välj sedan Skapa för att skapa prenumerationen.

      Skärmbild av sidan Skapa prenumeration.

  4. Upprepa föregående steg två gånger för att skapa prenumerationer med namnet S2 och S3.

Skapa filterregler för prenumerationer

När namnområdet och ämnet/prenumerationerna har etablerats och du har niska veze till namnområdet är du redo att skapa filterregler för prenumerationerna och sedan skicka och ta emot meddelanden. Du kan granska koden i den här GitHub-exempelmappen.

Skicka och ta emot meddelanden

Följ dessa steg för att köra koden:

  1. I en kommandotolk eller PowerShell-prompt, klonar du Service Bus GitHub-lagringsplatsen genom att utfärda följande kommando:

    git clone https://github.com/Azure/azure-service-bus.git
    
  2. Navigera till exempelmappen azure-service-bus\samples\DotNet\Azure.Messaging.ServiceBus\BasicSendReceiveTutorialWithFilters.

  3. Hämta niska veze du kopierade till Anteckningar tidigare i den här självstudien. Du behöver också namnet på det ämne som du skapade i föregående avsnitt.

  4. Skriv följande kommando i kommandotolken:

    dotnet build
    
  5. Gå till mappen BasicSendReceiveTutorialWithFilters\bin\Debug\netcoreapp3.1.

  6. Skriv följande kommando för att köra programmet. Se till att ersätta myConnectionString med värdet som du tidigare fick och myTopicName med namnet på det ämne som du skapade:

    dotnet --roll-forward Major BasicSendReceiveTutorialWithFilters.dll -ConnectionString "myConnectionString" -TopicName "myTopicName"
    
  7. Följ instruktionerna i konsolen för att välja filterskapande först. En del av att skapa filter är att ta bort standardfiltren. När du använder PowerShell eller CLI behöver du inte ta bort standardfiltret, men om du gör det i kod måste du ta bort dem. Konsolkommandona 1 och 3 hjälper dig att hantera filter för de prenumerationer som du skapade tidigare:

    • Kör 1: för att ta bort standardfiltren.

    • Kör 2: för att lägga till dina egna filter.

    • Kör 3: Hoppa över det här steget för självstudien. Det här alternativet tar eventuellt bort dina egna filter. Standardfiltren återskapas inte.

      Visar resultat av 2

  8. Efter att filtret har skapats, kan du skicka meddelanden. Tryck på 4 och notera 10 meddelanden som skickas till ämnet:

    Skicka utdata

  9. Tryck på 5 och se de meddelanden som tas emot. Om du inte fick tillbaka 10 meddelanden trycker du på "m" för att visa menyn och trycker sedan på 5 igen.

    Ta emot utdata

Rensa resurser

När de inte längre behövs följer du de här stegen för att rensa resurser.

  1. Navigera till ditt namnområde i Azure-portalen.
  2. På sidan Service Bus-namnområde väljer du Ta bort från kommandofältet för att ta bort namnområdet och resurserna (köer, ämnen och prenumerationer) i det.

Förstå exempelkoden

Det här avsnittet innehåller mer information om vad exempelkoden gör.

Hämta anslutningssträngen och ämnet

Koden deklarerar först en uppsättning variabler som driver den återstående körningen av programmet.

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.

Anslutningssträngen och ämnets namn skickas in via kommandoradsparametrar som det visas och därefter läses de i Main()-metoden:

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

Ta bort standardfiltren

När du skapar en prenumeration, skapar Service Bus ett standardfilter per prenumeration. Det här filtret låter dig ta emot alla meddelanden som skickas till ämnet. Om du vill använda anpassade filter kan du ta bort standardfiltret som visas i följande kod:

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

Skapa filter

Följande kod lägger till anpassade filter som definierats i den självstudien:

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

Ta bort dina anpassade skapade filter

Om du vill ta bort alla filter för din prenumeration, visar följande kod hur du gör detta:

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

Skicka meddelanden

Att skicka meddelanden till ett ämne liknar att skicka meddelanden till en kö. Det här exemplet visar hur du skickar meddelanden med hjälp av en uppgiftslista och asynkron bearbetning:

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

Ta emot meddelanden

Meddelanden tas emot igen via en uppgiftslista och koden använder batchbearbetning. Du kan skicka och ta emot med batchbearbetning, men det här exemplet visar bara hur du tar emot i batch. I verkligheten skulle du inte bryta dig ur loopen, utan fortsätta loopa och ange ett högre tidsintervall, till exempel en minut. Det mottagna samtalet till koordinatorn hålls öppet under den här tiden och om meddelandena tas emot returneras de omedelbart och ett nytt mottagningssamtal utfärdas. Det här konceptet kallas lång avsökning. Att använda mottagningspumpen, som du kan se i snabbstarten och i flera andra exempel på lagringsplatsen, är ett mer typiskt alternativ.

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

Kommentar

Du kan hantera Service Bus-resurser med Service Bus Explorer. Med Service Bus Explorer kan användare ansluta till ett Service Bus-namnområde och administrera meddelandeentiteter på ett enkelt sätt. Verktyget innehåller avancerade funktioner som import-/exportfunktioner eller möjligheten att testa ämne, köer, prenumerationer, relätjänster, meddelandehubbar och händelsehubbar.

Nästa steg

I den här självstudien, etablerade du resurser med hjälp av Azure-portalen och därefter skickade du och tog emot meddelanden från ett Service Bus-ämne och dess prenumerationer. Du har lärt dig att:

  • Skapa ett Service Bus-ämne och en eller flera prenumerationer på det ämnet med Azure-portalen
  • Lägg till ämnesfilter med .NET-kod
  • Skapa två meddelanden med olika innehåll
  • Skicka meddelandena och verifiera att de anlände i de förväntade prenumerationerna
  • Ta emot meddelanden från prenumerationerna

Om du vill ha fler exempel på att skicka och ta emot meddelanden, kan du komma igång med Service Bus-exempel på GitHub.

Gå vidare till nästa självstudie för att läsa mer om att använda Service Bus-funktionerna publicera/prenumerera.