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 membuat token akses JWT ke ASRS(Azure SignalR Service), sehingga klaim dicadangkan dan dapat diteruskan dari ASRS ke Hub
saat klien terhubung ke Hub
.
Dalam beberapa kasus, context.User.Claims
digunakan untuk menyimpan banyak informasi untuk server aplikasi, yang sebagian besar tidak digunakan oleh Hub
tetapi 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
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
Hilangkan pengecualian CLR
Lihat penghilangan pengecualian saat menelusuri masalah kode sisi server aplikasi:
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 klienSkipNegotiation
true
. 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 bersamaan per 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.
NegosiasiThrottled
Ketika ada terlalu banyak permintaan negosiasi klien pada saat yang sama , itu mungkin dibatasi. Batas berkaitan dengan jumlah unit bahwa lebih banyak unit memiliki batas yang lebih tinggi. Selain itu, kami sarankan memiliki penundaan acak sebelum menyambungkan kembali, periksa di sini untuk sampel 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 ILogger
pengelogan 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
- Buka log sisi server aplikasi untuk melihat apakah terjadi sesuatu yang tidak normal
- Periksa log peristiwa sisi server aplikasi untuk melihat apakah server aplikasi dimulai ulang
- 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.
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
- Jangan lupa untuk menutup koneksi klien jika Anda menggunakan klien SignalR dalam fungsi Azure atau gunakan klien SignalR sebagai singleton.
- Alih-alih menggunakan klien SignalR dalam fungsi Azure, Anda dapat membuat klien SignalR di tempat lain dan gunakan Pengikatan Fungsi Azure untuk Azure SignalR Service untuk menegosiasikan klien ke Azure SignalR. Selain itu, Anda juga dapat memanfaatkan pengikatan untuk mengirim pesan. Sampel untuk menegosiasikan klien dan mengirim pesan dapat ditemukan di sini. Informasi selengkapnya dapat ditemukan di sini.
- Ketika Anda menggunakan klien SignalR dalam fungsi Azure, mungkin ada arsitektur yang lebih baik untuk skenario Anda. Periksa apakah Anda mendesain arsitektur tanpa server yang tepat. Anda dapat melihat aplikasi tanpa server real-time dengan pengikatan SignalR Service di Azure Functions.
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 server-layanan ditutup oleh ASRS(Azure SignalR Service).
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
: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:
- Buang memori, lalu analisis tumpukan panggilan. Untuk informasi selengkapnya, lihat Mengumpulkan dan menganalisis file cadangan memori.
- Gunakan clrmd untuk membuang memori saat kurangnya kumpulan alur terdeteksi. Kemudian, catat tumpukan panggilan.
Panduan pemecahan masalah
- Buka log sisi server aplikasi untuk melihat apakah terjadi sesuatu yang tidak normal.
- Periksa log peristiwa sisi server aplikasi untuk melihat apakah server aplikasi dimulai ulang.
- 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.
Dari klien C#:
Anda dapat melihat lalu lintas web lokal menggunakan Fiddler. Lalu lintas WebSocket didukung sejak Fiddler 4.5.
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.