Panduan pemecahan masalah umum Azure SignalR Service

Artikel ini menyediakan panduan pemecahan masalah untuk beberapa masalah umum yang mungkin dihadapi pelanggan.

Akses token terlalu panjang

Kemungkinan kesalahan

  • Sisi klien ERR_CONNECTION_
  • URI 414 URI Terlalu Panjang
  • 413 Payload Too Large
  • Token Akses tidak boleh lebih panjang dari 4K. Entitas Permintaan 413 Terlalu Besar

Akar masalah

Untuk HTTP/2, panjang maksimum untuk satu header adalah 4 K, jadi jika menggunakan browser untuk mengakses layanan Azure, akan muncul kesalahan ERR_CONNECTION_ karena batasan ini.

Untuk HTTP/1.1, atau klien C#, panjang URI maksimum adalah 12 K dan panjang header maksimum adalah 16 K.

Dengan SDK versi 1.0.6 atau versi yang lebih baru, /negotiate akan menghilangkan 413 Payload Too Large jika token akses yang dihasilkan lebih besar daripada 4 K.

Solusi

Secara default, klaim dari context.User.Claims disertakan saat menghasilkan token akses JWT ke ASRS(LayananZure SignalRS), sehingga klaim dipertahankan dan dapat diteruskan dari ASRS ke Hub ketika klien terhubung ke Hub.

Dalam beberapa kasus, context.User.Claims digunakan untuk menyimpan banyak informasi untuk server aplikasi, yang sebagian besar tidak digunakan oleh Hubtetapi oleh komponen lain.

Token akses yang dihasilkan diteruskan melalui jaringan, dan untuk koneksi WebSocket/SSE, token akses diteruskan melalui string kueri. Jadi, sebagai praktik terbaik, sebaiknya teruskan klaim yang diperlukan dari klien melalui ASRS ke server aplikasi Anda jika Hub membutuhkan.

Ada bagi Anda untuk menyesuaikan klaim yang ClaimsProvider diteruskan ke ASRS di dalam token akses.

Untuk ASP.NET Core:

services.AddSignalR()
        .AddAzureSignalR(options =>
            {
                // pick up necessary claims
                options.ClaimsProvider = context => context.User.Claims.Where(...);
            });

Untuk ASP.NET:

services.MapAzureSignalR(GetType().FullName, options =>
            {
                // pick up necessary claims
                options.ClaimsProvider = context.Authentication?.User.Claims.Where(...);
            });

Mengalami masalah atau umpan balik tentang pemecahan masalah? Beri tahu kami.

TLS 1.2 diperlukan

Kemungkinan kesalahan

  • Kesalahan ASP.NET "Server tidak tersedia" #279
  • ASP.NET "Koneksi tidak aktif, data tidak dapat dikirim ke layanan." kesalahan #324
  • "Terjadi kesalahan saat membuat permintaan HTTP ke https://<API endpoint>. Kesalahan ini bisa terjadi karena sertifikat server tak dikonfigurasi dengan benar dengan HTTP.SYS dalam kasus HTTPS. Kesalahan ini juga bisa terjadi karena ketidakcocokan pengikatan keamanan antara klien dan server."

Akar masalah

Layanan Azure hanya mendukung TLS1.2 untuk masalah keamanan. Dengan .NET framework, ada kemungkinan bahwa TLS1.2 bukan protokol default. Akibatnya, koneksi server ke ASRS tidak dapat berhasil dibuat.

Panduan pemecahan masalah

  1. Jika kesalahan ini dapat direkonstruksi secara lokal, hapus centang Hanya Kode Saya dan hilangkan semua pengecualian CLR dan debug server aplikasi secara lokal untuk melihat pengecualian yang dihilangkan.

    • Hapus centang Hanya Kode Saya

      Uncheck Just My Code

    • Hilangkan pengecualian CLR

      Throw CLR exceptions

    • Lihat penghilangan pengecualian saat menelusuri masalah kode sisi server aplikasi:

      Exception throws

  2. Untuk ASP.NET, Anda juga dapat menambahkan kode berikut ke Startup.cs untuk mengaktifkan pelacakan terperinci dan melihat kesalahan dari log.

    app.MapAzureSignalR(this.GetType().FullName);
    // Make sure this switch is called after MapAzureSignalR
    GlobalHost.TraceManager.Switch.Level = SourceLevels.Information;
    

Solusi

Tambahkan kode berikut ke Startup:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Mengalami masalah atau umpan balik tentang pemecahan masalah? Beri tahu kami.

400 Bad Request dikembalikan untuk permintaan klien

Akar masalah

Periksa apakah permintaan klien Anda memiliki beberapa string kueri hub. hub adalah parameter kueri yang dicadangkan dan 400 akan dihilangkan jika layanan mendeteksi lebih dari satu hub dalam kueri.

Mengalami masalah atau umpan balik tentang pemecahan masalah? Beri tahu kami.

401 Tidak sah ditampilkan untuk permintaan klien

Akar masalah

Saat ini nilai default masa pakai token JWT adalah satu (1) jam.

Untuk ASP.NET Core SignalR, saat menggunakan jenis transportasi WebSocket, tidak apa-apa.

Untuk ASP.NET jenis transportasi Core SignalR lainnya, SSE dan polling panjang, masa pakai default berarti secara default koneksi paling dapat bertahan selama satu jam.

Untuk ASP.NET SignalR, klien mengirim /ping permintaan "tetap hidup" ke layanan dari waktu ke waktu, ketika /ping gagal, klien membatalkan koneksi dan tidak pernah tersambung kembali. Untuk ASP.NET SignalR, masa pakai token default membuat koneksi bertahan paling lama selama satu jam untuk semua jenis transportasi.

Solusi

Untuk masalah keamanan, perluas TTL tidak didorong. Sebaiknya tambahkan logika sambungkan kembali dari klien untuk memulai ulang koneksi jika 401 tersebut terjadi. Ketika klien memulai ulang koneksi, ini akan bernegosiasi dengan server aplikasi untuk mendapatkan token JWT lagi dan mendapatkan token yang diperbarui.

Lihat di sini tentang cara memulai ulang koneksi klien.

Mengalami masalah atau umpan balik tentang pemecahan masalah? Beri tahu kami.

404 ditampilkan untuk permintaan klien

Untuk koneksi persisten SignalR, ini /negotiate terlebih dahulu ke layanan Azure SignalR dan kemudian menetapkan koneksi nyata ke layanan Azure SignalR.

Panduan pemecahan masalah

  • Ikuti Cara melihat permintaan keluar untuk mendapatkan permintaan dari klien ke layanan.
  • Periksa URL permintaan jika 404 terjadi. Jika URL menargetkan ke aplikasi web Anda, dan sama dengan {your_web_app}/hubs/{hubName}, periksa apakah klien SkipNegotiationtrue. Klien menerima URL pengalihan saat pertama kali bernegosiasi dengan server aplikasi. Klien tidak boleh melewati negosiasi saat menggunakan Azure SignalR.
  • 404 lainnya dapat terjadi ketika permintaan koneksi ditangani lebih dari lima (5) detik setelah /negotiate dipanggil. Periksa tanda waktu permintaan klien, dan buka masalah untuk kami jika permintaan ke layanan mengalami respons lambat.

Mengalami masalah atau umpan balik tentang pemecahan masalah? Beri tahu kami.

404 ditampilkan permintaan sambungkan kembali ASP.NET SignalR

Untuk ASP.NET SignalR, saat koneksi klien terputus, ini akan terhubung kembali menggunakan connectionId yang sama selama tiga kali sebelum menghentikan koneksi. /reconnect dapat membantu jika koneksi terputus karena masalah terputus-putusnya jaringan yang /reconnect dapat membangun kembali koneksi persisten dengan sukses. Dalam kondisi lain, misalnya, koneksi klien terputus karena koneksi server yang dirutekan terputus, atau SignalR Service mengalami kesalahan internal seperti mulai ulang/failover/penyebaran instans, koneksi tidak akan ada lagi, sehingga /reconnect menampilkan 404. Ini adalah perilaku yang diharapkan untuk /reconnect dan setelah tiga kali mencoba kembali koneksi berhenti. Sebaiknya gunakan logika mulai ulang koneksi saat koneksi berhenti.

Mengalami masalah atau umpan balik tentang pemecahan masalah? Beri tahu kami.

429 (Terlalu Banyak Permintaan) ditampilkan untuk permintaan klien

Ada dua kasus.

Jumlah koneksi Bersamaan melampaui batas

Untuk instans Gratis, batas jumlah koneksi Bersamaan adalah 20. Untuk instans Standar, batas jumlah koneksi bersamaanper unit adalah 1 K, yang berarti bahwa Unit100 memungkinkan 100-K koneksi bersamaan.

Koneksi ini mencakup koneksi klien dan server. Lihat di sini untuk mengetahui cara koneksi dihitung.

Terlalu banyak permintaan negosiasi pada saat yang sama

Sebaiknya gunakan penundaan acak sebelum menghubungkan kembali, lihat di sini untuk mengetahui contoh coba lagi.

Mengalami masalah atau umpan balik tentang pemecahan masalah? Beri tahu kami.

500 Kesalahan saat bernegosiasi: Azure SignalR Service belum terhubung, coba lagi nanti

Akar masalah

Kesalahan ini dilaporkan ketika tidak ada koneksi server ke Azure SignalR Service yang tersambung.

Panduan pemecahan masalah

Aktifkan pelacakan sisi server untuk mengetahui detail kesalahan saat server mencoba terhubung ke Azure SignalR Service.

Aktifkan pengelogan sisi server untuk ASP.NET Core SignalR

Pengelogan sisi server untuk ASP.NET Core SignalR terintegrasi dengan ILoggerpengelogan berbasis yang disediakan dalam kerangka kerja ASP.NET Core. Anda dapat mengaktifkan pembuatan log sisi server dengan menggunakan ConfigureLogging, contoh penggunaan sebagai berikut:

.ConfigureLogging((hostingContext, logging) =>
        {
            logging.AddConsole();
            logging.AddDebug();
        })

Kategori pencatat untuk Azure SignalR selalu dimulai dengan Microsoft.Azure.SignalR. Untuk mengaktifkan log terperinci dari Azure SignalR, konfigurasikan awalan sebelumnya untuk Debug meratakan file appsettings.json Anda seperti di bawah ini:

{
    "Logging": {
        "LogLevel": {
            ...
            "Microsoft.Azure.SignalR": "Debug",
            ...
        }
    }
}

Mengaktifkan pelacakan sisi server untuk ASP.NET SignalR

Saat menggunakan versi >SDK = 1.0.0, Anda dapat mengaktifkan jejak dengan menambahkan yang berikut ke web.config: (Detail)

<system.diagnostics>
    <sources>
      <source name="Microsoft.Azure.SignalR" switchName="SignalRSwitch">
        <listeners>
          <add name="ASRS" />
        </listeners>
      </source>
    </sources>
    <!-- Sets the trace verbosity level -->
    <switches>
      <add name="SignalRSwitch" value="Information" />
    </switches>
    <!-- Specifies the trace writer for output -->
    <sharedListeners>
      <add name="ASRS" type="System.Diagnostics.TextWriterTraceListener" initializeData="asrs.log.txt" />
    </sharedListeners>
    <trace autoflush="true" />
  </system.diagnostics>

Mengalami masalah atau umpan balik tentang pemecahan masalah? Beri tahu kami.

Koneksi klien terputus

Jika klien terhubung ke Azure SignalR, koneksi persisten antara klien dan Azure SignalR terkadang dapat terputus karena berbagai alasan. Bagian ini menjelaskan beberapa kemungkinan yang menyebabkan terputusnya koneksi dan memberikan berisi panduan tentang cara mengidentifikasi akar penyebabnya.

Kemungkinan kesalahan yang terlihat dari sisi klien

  • The remote party closed the WebSocket connection without completing the close handshake
  • Service timeout. 30000.00ms elapsed without receiving a message from service.
  • {"type":7,"error":"Connection closed with an error."}
  • {"type":7,"error":"Internal server error."}

Akar masalah

Koneksi klien dapat terputus dalam berbagai keadaan:

  • Saat Hub melempar pengecualian dengan permintaan masuk
  • Ketika koneksi server, yang dirutekan klien, turun, lihat bagian di bawah ini untuk detail tentang koneksi server yang terputus
  • Ketika masalah konektivitas jaringan terjadi antara klien dan SignalR Service
  • Ketika SignalR Service memiliki beberapa kesalahan internal seperti mulai ulang instans, failover, penyebaran, dan sebagainya

Panduan pemecahan masalah

  1. Buka log sisi server aplikasi untuk melihat apakah terjadi sesuatu yang tidak normal
  2. Periksa log peristiwa sisi server aplikasi untuk melihat apakah server aplikasi dimulai ulang
  3. Ajukan masalah kepada kami dengan menyertakan jangka waktu, dan kirim nama sumber daya melalui email kepada kami

Mengalami masalah atau umpan balik tentang pemecahan masalah? Beri tahu kami.

Koneksi klien meningkat terus-menerus

Ini mungkin disebabkan oleh penggunaan koneksi klien yang tidak tepat. Jika seseorang lupa untuk menghentikan/melepaskan klien SignalR, koneksi tetap terbuka.

Kemungkinan kesalahan yang terlihat dari metrik SignalR yang ada di bagian Pemantauan pada menu sumber daya portal Azure

Koneksi klien naik terus-menerus untuk waktu yang lama di Metrik Azure SignalR.

Client connection increasing constantly

Akar masalah

DisposeAsync koneksi klien SignalR tidak pernah digunakan, koneksi terus terbuka.

Panduan pemecahan masalah

Periksa apakah klien SignalR tidak pernah ditutup.

Solusi

Periksa apakah Anda menutup koneksi. Gunakan HubConnection.DisposeAsync() secara manual untuk menghentikan koneksi setelah menggunakannya.

Contohnya:

var connection = new HubConnectionBuilder()
	.WithUrl(...)
	.Build();
try
{
	await connection.StartAsync();
	// Do your stuff
	await connection.StopAsync();
}
finally
{
	await connection.DisposeAsync();
}

Penggunaan koneksi klien umum yang tidak tepat

Contoh Fungsi Azure

Masalah ini sering terjadi ketika seseorang membuat koneksi klien SignalR dalam metode Azure Function alih-alih menjadikannya anggota statis di kelas fungsi. Anda mungkin hanya mengharapkan satu koneksi klien dibuat, tetapi sebaliknya Anda melihat jumlah koneksi klien meningkat terus-menerus dalam metrik. Semua koneksi ini hilang hanya setelah layanan Azure Function atau Azure SignalR dimulai ulang. Perilaku ini karena untuk setiap permintaan, Azure Function membuat satu koneksi klien, dan jika Anda tidak menghentikan koneksi klien dalam metode fungsi, klien menjaga koneksi tetap hidup ke layanan Azure SignalR.

Solusi

Mengalami masalah atau umpan balik tentang pemecahan masalah? Beri tahu kami.

Koneksi server terputus

Ketika server aplikasi dimulai, di latar belakang, Azure SDK mulai menginisiasi koneksi server ke Azure SignalR jarak jauh. Seperti dijelaskan di Internal Azure SignalR Service, Azure SignalR merutekan lalu lintas klien masuk ke koneksi server ini. Setelah koneksi server terputus, semua koneksi klien yang berfungsi akan ditutup juga.

Karena koneksi antara server aplikasi dan SignalR Service adalah koneksi persisten, masalah konektivitas jaringan mungkin dialami. Di Server SDK, kami memiliki strategi Always Reconnect ke koneksi server. Sebagai praktik terbaik, kami juga mendorong pengguna untuk menambahkan logika koneksi ulang berkelanjutan ke klien dengan waktu penundaan acak untuk menghindari permintaan simultan besar-besaran ke server.

Secara teratur, ada rilis versi baru untuk Azure SignalR Service, dan terkadang patching atau peningkatan di seluruh Azure atau terkadang gangguan dari layanan dependen kami. Peristiwa ini dapat menyebabkan gangguan layanan dalam waktu singkat, tetapi selama sisi klien memiliki mekanisme pemutusan/koneksi ulang, efeknya minimal seperti sisi klien yang menyebabkan pemutusan sambungan ulang.

Bagian ini menjelaskan beberapa kemungkinan yang menyebabkan terputusnya koneksi server, dan memberikan panduan tentang cara mengidentifikasi akar penyebabnya.

Kemungkinan kesalahan yang terlihat dari sisi server

  • [Error]Connection "..." to the service was dropped
  • The remote party closed the WebSocket connection without completing the close handshake
  • Service timeout. 30000.00ms elapsed without receiving a message from service.

Akar masalah

Koneksi layanan server ditutup oleh ASRS(Layanan Zure SignalRS).

Untuk habisnya waktu ping, ini mungkin disebabkan oleh penggunaan CPU yang tinggi atau kurangnya kumpulan rangkaian di sisi server.

Untuk ASP.NET SignalR, masalah umum telah diperbaiki dalam SDK 1.6.0. Tingkatkan SDK Anda ke versi terbaru.

Kurangnya kumpulan alur

Jika server Anda kekurangan, ini berarti tidak ada alur yang bekerja pada pemrosesan pesan. Semua utas tidak merespons dalam metode tertentu.

Biasanya, skenario ini disebabkan oleh asinkron di atas sinkron atau dengan Task.Result/Task.Wait() dalam metode asinkron.

Lihat Praktik terbaik performa ASP.NET Core.

Lihat selengkapnya tentang kurangnya kumpulan alur.

Cara mendeteksi kurangnya kumpulan alur

Periksa jumlah alur Anda. Jika saat itu tidak ada lonjakan, lakukan langkah-langkah berikut:

  • Jika Anda menggunakan Azure App Service, periksa jumlah alur dalam metrik. Periksa agregasi Max:

    Screenshot of the Max thread count pane in Azure App Service.

  • Jika Anda menggunakan .NET Framework, Anda dapat menemukan metrik di monitor performa di VM server Anda.

  • Jika Anda menggunakan .NET Core dalam kontainer, lihat Mengumpulkan diagnostik dalam kontainer.

Anda juga dapat menggunakan kode untuk mendeteksi kurangnya kumpulan alur:

public class ThreadPoolStarvationDetector : EventListener
{
    private const int EventIdForThreadPoolWorkerThreadAdjustmentAdjustment = 55;
    private const uint ReasonForStarvation = 6;

    private readonly ILogger<ThreadPoolStarvationDetector> _logger;

    public ThreadPoolStarvationDetector(ILogger<ThreadPoolStarvationDetector> logger)
    {
        _logger = logger;
    }

    protected override void OnEventSourceCreated(EventSource eventSource)
    {
        if (eventSource.Name == "Microsoft-Windows-DotNETRuntime")
        {
            EnableEvents(eventSource, EventLevel.Informational, EventKeywords.All);
        }
    }

    protected override void OnEventWritten(EventWrittenEventArgs eventData)
    {
        // See: https://learn.microsoft.com/dotnet/framework/performance/thread-pool-etw-events#threadpoolworkerthreadadjustmentadjustment
        if (eventData.EventId == EventIdForThreadPoolWorkerThreadAdjustmentAdjustment &&
            eventData.Payload[2] as uint? == ReasonForStarvation)
        {
            _logger.LogWarning("Thread pool starvation detected!");
        }
    }
}

Tambahkan ke layanan Anda:

service.AddSingleton<ThreadPoolStarvationDetector>();

Kemudian, periksa log Anda ketika koneksi server terputus karena waktu ping habis.

Cara menemukan akar penyebab kurangnya kumpulan alur

Untuk menemukan akar penyebab kurangnya kumpulan alur:

Panduan pemecahan masalah

  1. Buka log sisi server aplikasi untuk melihat apakah terjadi sesuatu yang tidak normal.
  2. Periksa log peristiwa sisi server aplikasi untuk melihat apakah server aplikasi dimulai ulang.
  3. Buat masalah. Masukkan jangka waktu, dan kirimkan nama sumber daya melalui email kepada kami.

Mengalami masalah atau umpan balik tentang pemecahan masalah? Beri tahu kami.

Tips

Bagaimana cara melihat permintaan keluar dari klien?

Ambil ASP.NET Core sebagai contoh (ASP.NET yang mirip):

  • Dari browser: Ambil Chrome sebagai contoh, Anda dapat menggunakan F12 untuk membuka jendela konsol, dan beralih ke tab Jaringan. Anda mungkin perlu menyegarkan halaman menggunakan F5 untuk menangkap jaringan dari awal.

    Chrome View Network

  • Dari klien C#:

    Anda dapat melihat lalu lintas web lokal menggunakan Fiddler. Lalu lintas WebSocket didukung sejak Fiddler 4.5.

    Fiddler View Network

Bagaimana cara memulai ulang koneksi klien?

Berikut Contoh kode yang berisi logika mulai ulang koneksi dengan strategi SELALU COBA LAGI:

Mengalami masalah atau umpan balik tentang pemecahan masalah? Beri tahu kami.

Langkah berikutnya

Dalam panduan ini, Anda telah mempelajari cara menangani masalah umum. Anda juga dapat mempelajari metode pemecahan masalah umum lainnya.