Les demandes sont en queue dans Azure AppService bien qu’il y ait suffisamment de threads dans le pool de threads.

J’ai écrit une api en utilisant asp.net webapi et je l’ai déployé dans azuree comme Appservice. Le nom de mon contrôleur est TestController et ma méthode d’action est similaire à celle ci-dessous.

[Route("Test/Get")] public ssortingng Get() { Thread.Sleep(10000); return "value"; } 

Donc, pour chaque demande, il devrait attendre 10 secondes avant de renvoyer la chaîne “valeur”. J’ai également écrit un autre sharepoint terminaison pour voir le nombre de threads dans le pool de threads travaillant pour l’exécution de requêtes. Cette action est quelque chose comme ci-dessous.

  [Route("Test/ThreadInfo")] public ThreadPoolInfo Get() { int availableWorker, availableIO; int maxWorker, maxIO; ThreadPool.GetAvailableThreads(out availableWorker, out availableIO); ThreadPool.GetMaxThreads(out maxWorker, out maxIO); return new ThreadPoolInfo { AvailableWorkerThreads = availableWorker, MaxWorkerThreads = maxWorker, OccupiedThreads = maxWorker - availableWorker }; } 

Maintenant, lorsque nous passons 29 appels en même temps pour tester / obtenir un terminal, il faut presque 11 secondes pour que toutes les demandes soient traitées avec succès. Le serveur exécute donc toutes les demandes simultanément dans 11 threads. Pour voir l’état des threads, appelez Test / ThreadInfo juste après l’appel de Test / Get retourne immédiatement (sans attente) {“AvailableWorkerThreads”: 8161, “MaxWorkerThreads”: 8191, “OccupiedThreads”: 30}

Il semble que 29 threads exécutent des requêtes Test / Get et qu’un thread exécute une requête Test / ThreadInfo.

Lorsque je fais 60 appels sur Test / Get, il faut presque 36 secondes pour réussir. Passer un appel à Test / ThreadInfo (prend un certain temps) renvoie {“AvailableWorkerThreads”: 8161, “MaxWorkerThreads”: 8191, “OccupiedThreads”: 30}

Si nous augmentons le nombre de demandes, la valeur de OccupiedThreads augmente. Comme pour 1 000 demandes, cela prend 2 minutes 22 secondes et la valeur de OccupiedThreads est de 129.

Semble la demande et se met en queue après 30 appels simultanés bien qu’un grand nombre de threads soient disponibles dans WorkerThread. Peu à peu, le thread augmente pour l’exécution simultanée mais cela ne suffit pas (129 pour 1000 requêtes).

Comme nos services ont beaucoup d’appels IO (certains d’entre eux sont des appels API externes et d’autres des requêtes de firebase database), le temps de latence est également élevé. Comme nous utilisons tous les appels d’E / S de manière asynchrone, le serveur peut traiter plusieurs demandes simultanément, mais nous avons besoin de plus de simultanéité lorsque les processeurs effectuent un travail réel. Nous utilisons le plan de service S2 avec une instance. L’augmentation d’instance augmentera la concurrence, mais nous avons besoin de plus de concurrence à partir d’une seule instance.

Après avoir lu un blog et de la documentation sur IIS, nous avons constaté qu’il existe un paramètre minFreeThreads . Si le nombre de threads disponibles dans le pool de threads est inférieur à la valeur indiquée pour ce paramètre, IIS commence à mettre la requête en queue. Y at-il quelque chose dans Appservice comme ça? Et est-il vraiment possible d’obtenir plus de simultanéité à partir du service d’application azure ou une configuration nous manque-t-elle?

Enfin obtenu la réponse à ma question. Le problème est que le pool de threads ASP.NET conserve un pool de threads qui ont déjà supporté les coûts d’initialisation des threads et qui sont faciles à réutiliser. Le pool de threads .NET est également à réglage automatique. Il surveille l’utilisation du processeur et d’autres ressources et ajoute de nouveaux threads ou réduit la taille du pool de threads en fonction des besoins. Lorsqu’il y a beaucoup de demandes et qu’il n’y a pas assez de threads dans le pool, le pool de threads commence à append de nouveaux threads dans le pool et avant d’exécuter son propre algorithme pour afficher l’état de la mémoire et de l’utilisation du processeur du système, ce qui prend beaucoup de temps. C’est pourquoi nous constatons une lente augmentation du nombre de threads de travail dans le pool et de nombreuses requêtes en queue. Heureusement, il existe une option permettant de définir le nombre de threads de travail avant que le pool de threads ne bascule vers un algorithme permettant d’append un nouveau thread. Le code est quelque chose comme ci-dessous.

  public ssortingng Settings() { int minWorker, minIOC; ThreadPool.GetMinThreads(out minWorker, out minIOC); if (ThreadPool.SetMinThreads(300, minIOC)){ return "The minimum number of threads was set successfully."; } else { return "The minimum number of threads was not changed."; } } 

ThreadPool.SetMinThreads (300, minIOC) définit ici la valeur du nombre minimal de threads que threadpool créera avant de passer à un algorithme permettant d’append ou de supprimer un thread. J’ai ajouté cette méthode en tant qu’action de mon contrôleur webapi, puis après exécution de cette action en effectuant une demande lorsque j’ai effectué 300 demandes simultanées de test / obtention du sharepoint terminaison, tout était en cours d’exécution et s’est terminé en 11 secondes et aucune demande n’a été mise en queue.

Si je comprends bien, vous devez vérifier MinWorkerThreads via ThreadPool.GetMinThreads qui pourrait récupérer le nombre de threads inactifs gérés par ThreadPool en prévision de nouvelles demandes. Je vous recommanderais de renvoyer les informations du pool de threads en cours après l’exécution de votre action ( Tetst/Get ) au lieu d’effectuer une nouvelle demande à Test/ThreadInfo . En fonction de votre code, je l’ai testée sur mon application Web avec le niveau de tarification B1 comme suit:

1000 demandes simultanées, dormir 15 s pour chaque action, total écoulé 3 min 20 s.

entrez la description de l'image ici

Le pool de threads crée et détruit les threads de travail afin d’optimiser le débit. Si les threads actuels pouvaient gérer les demandes, aucun autre thread ne serait créé. Une fois que ces threads ont terminé l’exécution de leurs activités, ils sont ensuite renvoyés dans le pool de threads.

Ensuite, j’ai utilisé la programmation asynchrone et modifié l’action comme suit:

 public async Task DoJob(int id) { await Task.Delay(TimeSpan.FromSeconds(15)); return ThreadInfo(); } 

Résultat:

entrez la description de l'image ici

Près de 3000 demandes simultanées:

entrez la description de l'image ici

En général, AvailableWorkerThreads signifie simplement que le nombre de threads de travail supplémentaires pouvant être démarrés à la place du nombre de threads de travail a été créé pour vous. Je vous recommanderais d’utiliser la programmation asynchrone et de déployer votre travail réel sur l’application web azuree, puis de vérifier les performances réelles et de rechercher les approches associées, le cas échéant.