Tutorial: Memperbarui inventaris menggunakan portal Microsoft Azure dan topik/langganan

Azure Service Bus adalah layanan pesan cloud multi-penyewa yang mengirimkan informasi antara aplikasi dan layanan. Operasi asinkron memberi Anda pesan yang fleksibel dan ditengahi, bersama dengan pesan pertama terstruktur, first-out (FIFO), dan kemampuan publikasi/ berlangganan. Untuk gambaran umum terperinci tentang Azure Service Bus, lihat Apa itu Bus Layanan?.

Tutorial ini menunjukkan cara menggunakan topik dan langganan Bus Layanan dalam skenario inventaris ritel, dengan saluran publikasi/berlangganan menggunakan portal Microsoft Azure dan .NET. Contoh skenario ini adalah pembaruan bermacam-macam inventaris untuk beberapa toko ritel. Dalam skenario ini, setiap toko, atau sekumpulan toko, mendapatkan pesan yang ditujukan bagi mereka untuk memperbarui bermacam-macam. Tutorial ini menunjukkan cara mengimplementasikan skenario ini menggunakan langganan dan filter. Pertama, Anda membuat topik dengan tiga langganan, menambahkan beberapa aturan dan filter, lalu mengirim dan menerima pesan dari topik dan langganan.

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

Dalam tutorial ini, Anda akan mempelajari cara:

  • Membuat topik Bus Layanan dan tiga langganan ke topik tersebut menggunakan portal Azure
  • Menambahkan filter untuk langganan menggunakan kode .NET
  • Membuat pesan dengan konten yang berbeda
  • Mengirim pesan dan memverifikasi bahwa pesan tersebut tiba di langganan yang diharapkan
  • Anda tidak dapat menerima pesan dari langganan

Prasyarat

Untuk menyelesaikan tutorial ini, pastikan Anda memiliki:

  • Langganan Azure. Untuk menggunakan layanan Azure, termasuk Azure Service Bus, Anda memerlukan langganan. Jika Anda tidak memiliki langganan Azure, Anda dapat membuat akun gratis sebelum memulai.
  • Visual Studio 2019 atau versi yang lebih baru.

Topik dan langganan Bus Layanan

Setiap langganan ke topik dapat menerima salinan dari setiap pesan. Topik sepenuhnya kompatibel secara protokol dan semantik dengan antrean Bus Layanan. Topik Microsoft Azure Service Bus mendukung berbagai aturan pemilihan dengan kondisi filter, dengan tindakan opsional yang mengatur atau mengubah properti pesan. Setiap kali aturan cocok, aturan akan menghasilkan pesan. Untuk mempelajari selengkapnya tentang aturan, filter, dan tindakan, ikuti tautan ini.

Membuat namespace layanan di portal Microsoft Azure

Untuk mulai menggunakan entitas Olahpesan Azure Service Bus di Azure, Anda harus terlebih dahulu membuat namespace layanan dengan nama yang unik di Azure. Namespace menyediakan kontainer cakupan untuk sumber daya Bus Layanan (antrean, topik, dll.) dalam aplikasi Anda.

Untuk membuat namespace layanan:

  1. Masuk ke portal Azure.

  2. Navigasi ke halaman Semua layanan.

  3. Di bilah navigasi kiri, pilih Integrasi dari daftar kategori, arahkan mouse ke atas Bus Layanan, lalu pilih + tombol pada petak peta Bus Layanan.

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

  4. Di tag Dasar-Dasar pada halaman Buat kumpulan nama, ikuti langkah-langkah berikut:

    1. Untuk Langganan, pilih langganan Azure untuk membuat namespace layanan.

    2. Untuk Grup sumber daya, pilih grup sumber daya yang sudah ada tempat namespace layanan akan aktif, atau buat grup baru.

    3. Masukkan nama untuk kumpulan nama. Nama namespace harus mematuhi konvensi penamaan berikut:

      • Nama yang Anda pilih harus unik di seluruh Azure. Sistem akan segera memeriksa untuk melihat apakah nama tersebut tersedia.
      • Panjang nama minimal 6 dan maksimal 50 karakter.
      • Nama hanya boleh berisi huruf, angka, tanda hubung “-“.
      • Nama harus dimulai dengan huruf dan diakhiri dengan huruf atau angka.
      • Nama tidak diakhiri dengan “-sb“ atau “-mgmt“.
    4. Untuk Lokasi, pilih wilayah tempat namespace layanan Anda akan dihosting.

    5. Untuk Tingkat harga, pilih tingkat harga (Dasar, Standar, atau Premium) untuk kumpulan namanya. Untuk mulai cepat ini, pilih Standar.

      Penting

      Jika Anda ingin menggunakan topik dan langganan, pilih Standar atau Premium. Topik/langganan tidak didukung di tingkat harga Dasar.

      Jika Anda memilih tingkat harga Premium, tentukan jumlah unit olahpesan. Tingkat premium menyediakan isolasi sumber daya di tingkat CPU dan memori sehingga setiap beban kerja berjalan dalam isolasi. Kontainer sumber daya ini disebut unit Olahpesan. Namespace layanan premium memiliki setidaknya satu unit Olahpesan. Anda dapat membeli 1, 2, 4, 8, atau 16 unit Olahpesan untuk setiap namespace layanan Service Bus Premium. Untuk mengetahui informasi selengkapnya, lihat Olahpesan Premium Azure Service Bus.

    6. Pilih Tinjau + buat di bagian bawah halaman.

      Image showing the Create a namespace page

    7. Pada halaman Tinjau + buat, tinjau pengaturan, dan pilih Buat.

  5. Setelah penyebaran sumber daya berhasil, pilih Buka sumber daya di halaman penyebaran.

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

  6. Anda melihat beranda untuk namespace layanan bus layanan Anda.

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

Dapatkan string koneksi ke namespace (portal Azure)

Membuat namespace layanan baru secara otomatis menghasilkan kebijakan Tanda Tangan Akses Bersama (SAS) awal dengan kunci primer dan sekunder, serta string koneksi primer dan sekunder yang masing-masing memberikan kontrol penuh atas semua aspek namespace layanan. Lihat Autentikasi dan otorisasi Azure Service Bus untuk informasi tentang cara membuat aturan dengan hak yang lebih terkendala untuk pengirim dan penerima reguler.

Klien dapat menggunakan string koneksi untuk menyambungkan ke namespace Bus Layanan. Untuk menyalin string koneksi utama namespace layanan Anda, ikuti langkah-langkah berikut:

  1. Pada halaman Namespace layanan Azure Service Bus, pilih Kebijakan akses bersama di menu sebelah kiri.

  2. Pada halaman Kebijakan akses bersama, pilih RootManageSharedAccessKey.

  3. Di jendela Kebijakan: RootManageSharedAccessKey, pilih tombol salin di samping String Koneksi Utama, untuk menyalin string koneksi ke clipboard Anda untuk digunakan nanti. Tempelkan nilai ini ke Notepad atau beberapa lokasi sementara lainnya.

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

    Anda dapat menggunakan halaman ini untuk menyalin kunci primer, kunci sekunder, dan string koneksi sekunder.

Membuat topik menggunakan portal Microsoft Azure

  1. Di halaman Namespace Bus Layanan, pilih Topik di menu sebelah kiri.

  2. Pilih + Topik di toolbar.

  3. Masukkan nama untuk topik. Biarkan opsi lain dengan nilai defaultnya.

  4. Pilih Buat.

    Screenshot of the Create topic page.

Membuat langganan ke topik

  1. Pilih topik yang Anda buat di sesi sebelumnya.

    Screenshot of the Topics page with your topic selected.

  2. Di halaman Topik Bus Layanan, pilih Langganan dari menu sebelah kiri, lalu pilih + Langganan di toolbar.

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

  3. Di halaman Membuat Langganan, ikuti langkah-langkah berikut:

    1. Masukkan S1 untuk nama langganan.

    2. Lalu, pilih Buat untuk membuat langganan.

      Screenshot of the Create subscription page.

  4. Ulangi langkah sebelumnya dua kali untuk membuat langganan bernama S2 dan S3.

Membuat aturan filter pada langganan

Setelah namespace layanan dan topik/langganan disediakan, dan Anda memiliki string koneksi ke namespace, Anda siap untuk membuat aturan filter pada langganan, lalu mengirim dan menerima pesan. Anda dapat memeriksa kode dalam folder sampel GitHub ini.

Mengirim dan menerima pesan

Untuk menjalankan kode, ikuti langkah-langkah berikut:

  1. Dalam prompt perintah atau prompt PowerShell, kloning repositori Microsoft Azure Service Bus GitHub dengan mengeluarkan perintah berikut:

    git clone https://github.com/Azure/azure-service-bus.git
    
  2. Navigasi ke folder sampel azure-service-bus\samples\DotNet\Azure.Messaging.ServiceBus\BasicSendReceiveTutorialWithFilters.

  3. Dapatkan string koneksi yang Anda salin ke Notepad sebelumnya dalam tutorial ini. Anda juga memerlukan nama topik yang Anda buat di bagian sebelumnya.

  4. Pada prompt perintah, jalankan perintah berikut ini:

    dotnet build
    
  5. Navigasi ke folder BasicSendReceiveTutorialWithFilters\bin\Debug\netcoreapp3.1.

  6. Ketik perintah berikut ini untuk menjalankan program. Pastikan untuk mengganti myConnectionString dengan nilai yang sebelumnya Anda peroleh, dan dengan nama topik yang Anda myTopicName buat:

    dotnet --roll-forward Major BasicSendReceiveTutorialWithFilters.dll -ConnectionString "myConnectionString" -TopicName "myTopicName"
    
  7. Ikuti petunjuk di konsol untuk memilih pembuatan filter terlebih dahulu. Bagian dari membuat filter adalah menghapus filter default. Saat Anda menggunakan PowerShell atau CLI, Anda tidak perlu menghapus filter default, tetapi jika Anda melakukannya dalam kode, Anda harus menghapusnya. Perintah konsol 1 dan 3 membantu Anda mengelola filter pada langganan yang sebelumnya Anda buat:

    • Jalankan 1: untuk menghapus filter default.

    • Jalankan 2: untuk menambahkan filter Anda sendiri.

    • Jalankan 3: Lewati langkah ini untuk tutorial. Opsi ini secara opsional menghapus filter Anda sendiri. Ini tidak akan membuat ulang filter default.

      Showing output of 2

  8. Setelah pembuatan filter, Anda dapat mengirim pesan. Tekan 4 dan amati 10 pesan yang dikirim ke topik:

    Send output

  9. Tekan 5 dan amati pesan yang diterima. Jika Anda tidak mendapatkan kembali 10 pesan, tekan "m" untuk menampilkan menu, lalu tekan 5 lagi.

    Receive output

Membersihkan sumber daya

Jika tidak lagi diperlukan, ikuti langkah-langkah ini untuk membersihkan sumber daya.

  1. Navigasikan ke namespace layanan Anda di portal Azure.
  2. Pada halaman Bus Layanan Namespace Layanan, pilih Hapus dari bilah perintah untuk menghapus namespace layanan dan sumber daya (antrean, topik, dan langganan) di dalamnya.

Memahami kode sampel

Bagian ini berisi detail lebih lanjut tentang apa yang dilakukan kode sampel.

Mendapatkan string dan topik koneksi

Pertama, kode mendeklarasikan serangkaian variabel, yang mendorong sisa eksekusi program.

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.

String koneksi dan nama topik diteruskan melalui parameter baris perintah seperti yang ditunjukkan, dan kemudian dibaca dalam metode 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();
    }
}

Menghapus filter default

Saat Anda membuat langganan, Microsoft Azure Service Bus akan membuat filter default per langganan. Filter ini memungkinkan menerima setiap pesan yang dikirim ke topik tersebut. Jika Anda ingin menggunakan filter kustom, Anda bisa menghapus filter default, seperti yang diperlihatkan dalam kode berikut:

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

Membuat filter

Kode berikut menambahkan filter kustom yang didefinisikan dalam tutorial ini:

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

Menghapus filter yang dibuat kustom

Jika Anda ingin menghapus semua filter pada langganan Anda, kode berikut ini memperlihatkan cara melakukannya:

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

Mengirim pesan

Mengirim pesan ke topik mirip dengan mengirim pesan ke antrean. Contoh ini memperlihatkan cara mengirim pesan, menggunakan daftar tugas dan pemrosesan asinkron:

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

Terima pesan

Pesan kembali diterima melalui daftar tugas, dan kode menggunakan batching. Anda dapat mengirim dan menerima menggunakan batching, tetapi contoh ini hanya menunjukkan cara menerima batch. Pada kenyataannya, Anda tidak akan keluar dari perulangan, tetapi terus melakukan perulangan dan mengatur waktu yang lebih tinggi, seperti satu menit. Panggilan penerima ke broker tetap terbuka untuk jumlah waktu ini dan jika pesan tiba, mereka segera dikembalikan dan panggilan penerima baru dikeluarkan. Konsep ini disebut polling panjang. Menggunakan pompa penerima, yang dapat Anda lihat di mulai cepat, dan dalam beberapa sampel lain di repositori, adalah pilihan yang lebih umum.

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

Catatan

Anda dapat mengelola sumber daya Azure Service Bus dengan Azure Service Bus Explorer. Service Bus Explorer memungkinkan pengguna untuk terhubung ke namespace Bus Layanan dan mengelola entitas pesan dengan cara yang mudah. Alat tersebut menyediakan fitur-fitur canggih, seperti fungsionalitas impor/ekspor atau kemampuan untuk menguji topik, antrean, langganan, layanan relai, hub pemberitahuan, dan hub peristiwa.

Langkah berikutnya

Dalam tutorial ini, Anda menyediakan sumber daya menggunakan portal Microsoft Azure, lalu mengirim dan menerima pesan dari topik Bus Layanan dan langganannya. Anda mempelajari cara untuk:

  • Membuat topik Bus Layanan dan satu atau beberapa langganan ke topik tersebut menggunakan portal Microsoft Azure
  • Menambahkan filter topik menggunakan kode .NET
  • Membuat dua pesan dengan konten yang berbeda
  • Mengirim pesan dan memverifikasi bahwa pesan tersebut tiba di langganan yang diharapkan
  • Anda tidak dapat menerima pesan dari langganan

Untuk contoh lebih lanjut mengirim dan menerima pesan, mulailah dengan sampel Microsoft Azure Service Bus di GitHub.

Lanjutkan ke tutorial berikutnya untuk mempelajari lebih lanjut tentang menggunakan kemampuan mempublikasikan/berlangganan Microsoft Azure Service Bus.