58 votes

Que se passe-t-il dans BeginProcessRequest ()?

Nous sommes à l'aide de NewRelic à côté serveur de l'application des traces.

Nous avons remarqué que certaines de nos applications de manière cohérente dépenser environ 100ms dans la méthode System.Web.Mvc.MvcHandler.BeginProcessRequest().

Ce qui se passe avant tout personnalisé contrôleur de code est appelé (ce qui est enregistré séparément, et non pas de façon cumulative) - il n'est pas évident pourquoi il serait tant de temps passé dans cette méthode.

Quels sont les types de choses qui va MVC faire dans cette méthode? Cela pourrait-il être simplement demande de files d'attente?

[EDIT:] Comme suspect - Scalayer la réponse ci-dessous a été localisé. Nous avons enlevé et optimisé toutes nos session dépendances, et a vu une augmentation massive de la demande de l'évolutivité et de la stabilité

86voto

Scalayer Points 889

Ce que vous pouvez voir est communément appelé fil d'agilité .NET.

Ce que vous êtes probablement en voyant autant que les résultats en dessous de la topique de l'étiquette (c'est à dire le code de l'Application (dans le Système.Web.HttpApplication.BeginRequest()) est un fil d'agilité problème; dans la plupart des cas, le temps que vous voyez ici n'est pas nécessairement l'exécution d'un code, mais le contexte web d'attente pour les threads pour être libérée à partir d'un lecteur-écrivain de verrouillage.

Le Application_BeginRequest "pause" en est un qui est assez répandue dans un ASP .NET web de la pile. En général, quand vous voyez à long temps de chargement dans BeginRequest, vous avez affaire à ASP.NET fil agilité et / ou le thread verrouillage des portes - en particulier lorsque vous traitez avec IO et de la session. Non pas que c'est une mauvaise chose, c'est juste comment .net permet de s'assurer de votre threads restent simultanées.

L'intervalle de temps se produit généralement entre BeginRequest et PreRequestHandlerExecute. Si la demande est écrit à plusieurs choses à la session, puis ASP .NET sera question d'un lecteur-verrou en écriture sur HttpContext.Actuel.Session.

Une bonne façon de voir si c'est une question que vous pourriez être confronté à vérifier l'Id de thread pour voir si l'agilité est un problème - l'Id sera différent pour une requête donnée.

Par exemple. pendant le débogage, vous pourriez peut-être ajouter les éléments suivants à votre global.asax.cs:

protected void Application_BeginRequest(Object sender, EventArgs e) { 
      Debug.WriteLine("BeginRequest_" + Thread.CurrentThread.ManagedThreadId.ToString()); 
   }

Ouvrir la fenêtre de sortie de débogage (à Partir de Visual Studio: Affichage >> de Sortie, puis sélectionnez "Debug" dans le "spectacle de la sortie de" liste déroulante).

Pendant le débogage, appuyez sur une page où vous avez vu le temps long. Puis afficher le fichier journal de sortie - si vous voyez plusieurs id alors vous pourriez souffrir de cette situation.

C'est pourquoi vous pouvez constater que le retard, parfois, mais pas d'autres fois, le code de l'application peut-être à l'aide de session un peu différemment ou d'une session ou d'opérations d'e / s peuvent être supérieures ou inférieures de la page à page.

Si c'est le cas de certaines choses que vous pouvez faire pour aider à accélérer les choses en fonction de la façon dont la session est utilisé sur le site ou à chaque page.

Pour les pages qui ne modifient pas de session:

   <% @Page EnableSessionState="ReadOnly" %>

Pour les pages qui n'utilisent pas l'état de la session:

<% @Page EnableSessionState="False" %>

Si l'application n'utilise pas de session (le web.config):

<configuration>
    <system.web>
      <sessionState mode="Off" />
    </system.web>
</configuration>

Prenons l'exemple suivant:

L'utilisateur charge une page, puis décide d'aller à une autre page avant de la première demande est fait, le chargement d'ASP .NET force une session de verrouillage provoquant la nouvelle page de demande de chargement d'attendre jusqu'à ce que la première page de demande de finitions. Avec l'ASP .NET MVC chaque action permet de verrouiller la session de l'utilisateur pour la synchronisation; à l'origine du même problème.

Tout le temps il a fallu pour que le verrou de presse seront signalés par le biais des nouvelles relique, sans parler de ceux où l'utilisateur abandonné la session et le fil de retour est à la recherche pour un utilisateur qui n'existe plus.

D'ailleurs le contrôle UpdatePanel fait le même comportement -

http://msdn.microsoft.com/en-us/magazine/cc163413.aspx

Ce qui peut être fait:

Ce problème de verrouillage est l'une des raisons de Microsoft a la SessionStateUtility classe

http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstateutility.aspx

De sorte que vous pouvez remplacer le comportement par défaut si vous faites face à ce problème, comme on le voit ici, dans cette Redis mise en œuvre:https://github.com/angieslist/AL-Redis

Il existe de nombreuses options à l'état par défaut du fournisseur utilisé par .net sites web. Mais sais généralement ce temps de transaction indique que les threads sont verrouillées et l'attente des requêtes au serveur pour être complété.

6voto

Andrey Zhminka Points 98

Si vous souhaitez activer un certain contrôleur de traiter les demandes en parallèle à partir d'un seul utilisateur, vous pouvez utiliser un attribut nommé SessionState qui a été introduit dans MVC depuis la version 3. Il n'est pas nécessaire d'utiliser une session contrôleur afin de réaliser le parallélisme, la seule option de la SessionStateBehavior vous permettra de passer les contrôles de sécurité, vous pourriez avoir mis en œuvre en fonction des données de Session.

[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public class ParallelController : Controller
{
    ...
}

J'ai également eu des retards dans le Système.Web.Mvc.MvcHandler.BeginProcessRequest(), lorsque vous essayez de faire un peu long actions en cours d'exécution et je l'ai vu dans NewRelic. Ces attributs ont résolu le problème et a donné la capacité à gérer le actions parallèles pour ce contrôleur.

0voto

Ami Points 725

pour tous ceux qui lisent cette expérience IIS utilisation élevée du PROCESSEUR qui est inexpliquée, jetez un oeil à ce fil de NewRelic forum de support, j'ai ouvert.

J'ai eu affaire à ce problème depuis plus d'une semaine, jusqu'à ce que j'ai réalisé que c'était leur agent qui a été la cause racine du problème.

.NET agent causant utilisation élevée de l'UC sur IIS

donc, la première chose que je vous suggère d'essayer de retirer le .NET de l'agent et de voir si il ya un changement, avant de vous plonger dans plus d'expériences complexes.

Je poste cette réponse sur cette question en particulier, depuis que je suis ici d'abord en travaillant sur la question, et le fil de l'agilité m'ont mis un long parcours qui n'était pas correct...(bien que très intéressant par lui-même).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X