Fonctionnement du pool d'application [Résolu]

cs_wally88 361 Messages postés jeudi 5 février 2004Date d'inscription 1 octobre 2010 Dernière intervention - 4 janv. 2008 à 11:23 - Dernière réponse : jesusonline 6827 Messages postés dimanche 15 décembre 2002Date d'inscription 13 octobre 2010 Dernière intervention
- 7 janv. 2008 à 19:06
Bonjour,

Je suis sur un serveur dédié, et je recois au bout d'un certain temps quand je suis sur mon site une erreur de pool me disant que toutes les connexions sont occupées ou un truc dans le genre.

Toutes mes connexions sont bien fermer en utilisant : sqlcon.Close(); --> sqlcon etant ma connexion.

Je pense donc qu'il faut modifier quelquechose sur le serveur pour permettre de laisser entré plus de connexion que celle par defaut.

Je ne trouve aucune doc sur comment configurer ou comment se passe le pool d'application.

Si quelqu'un peut m'aider a ce sujet.

Par avance merci.
Afficher la suite 

Votre réponse

20 réponses

cs_coq 6366 Messages postés samedi 1 juin 2002Date d'inscription 2 août 2014 Dernière intervention - 5 janv. 2008 à 08:52
+3
Utile
Salut,

D'après la description de départ on dirait plus qu'il parle du pool de connexions ADO.NET que du pool d'application IIS.

/*
coq
MVP Visual C#
CoqBlog
*/
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_coq
jesusonline 6827 Messages postés dimanche 15 décembre 2002Date d'inscription 13 octobre 2010 Dernière intervention - 5 janv. 2008 à 15:22
+3
Utile
Je te conseille de ne JAMAIS exposer un DataReader. Pour plusieurs raisons :

- Es tu sur de toujours fermer ton DataReader ? en utilisant un dispose ou close ? ou alors en utilisant un using ?
- Si tu changes ta requête pour rajouter une colonne, alors il te faudra modifier (et donc rechercher) toutes les méthodes qui utilise ce DataReader. Cela peut entrainer des bugs cachés pour plus tard car tu ne le sauras pas à la compilation et faudra bien passer à tout tester après la modification de ta requête.
- Je trouve pas ca propre :D (sauf si tu as qu'une seule méthode qui te retourne un DataReader dans un SqlHelper)

<hr />Cyril - MSP - MCPD ASP.net & MCTS SQL - Consultant indépendant
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de jesusonline
cs_coq 6366 Messages postés samedi 1 juin 2002Date d'inscription 2 août 2014 Dernière intervention - 5 janv. 2008 à 16:27
+3
Utile
La doc en premier lieu, et Reflector pour approfondir, plus une forte veille techno... bref, comme le dit Cyril, ça vient aussi beaucoup avec la pratique.
Par exemple avec le DataReader, beaucoup croient que le fait de spécifier CommandBehavior.CloseConnection sur ExecuteReader permet de fermer la connexion quoiqu'il arrive, hors ce n'est à ma connaissance pas le cas : il faut bien penser à fermer le DataReader, que ce soit pas Close ou Dispose (explicitement par appel direct de Dispose de façon certaine (finally) ou par la construction using auquel cas c'est le compilateur qui génèrera la logique).

Après une source intéressante pour les bonnes pratiques sont les docs de la section patterns & pratices, mais il faut les avaler.
Concernant le bouquin de Brad Abrams & Krzysztof Cwalina, je ne l'ai pas lu (oui, j'ai honte :p), pour maintenant je crois que je vais attendre la seconde édition.

/*
coq
MVP Visual C#
CoqBlog
*/
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de cs_coq
jesusonline 6827 Messages postés dimanche 15 décembre 2002Date d'inscription 13 octobre 2010 Dernière intervention - 5 janv. 2008 à 01:16
0
Utile
Bonsoir,

c'est un message noir qui dit "Server is to busy" ? si c'est le cas c'est au niveau de IIS qu'est la limite (5000 par défaut sur IIS6) c'est le nombre de requête maximum dans la queue de IIS. Par défaut il me semble que ASP.net à un pool de 20 requêtes. On est très loin de cette limite sur CodeS-SourceS et ca m'étonne que tu as ce problème (sauf s'il y a plusieurs milliers de connexions à la minutes ?)

Je pense que tu as un problème dans ton code, tes pages sont très longue à s'executer ... Mais avant de te donner des conseils sur comment trouver ces pages, c'est bien le message "server is to busy" ?

<hr />Cyril - MSP - MCPD ASP.net & MCTS SQL - Consultant indépendant
Commenter la réponse de jesusonline
cs_wally88 361 Messages postés jeudi 5 février 2004Date d'inscription 1 octobre 2010 Dernière intervention - 5 janv. 2008 à 01:23
0
Utile
Non sa ne me met pas "server is too busy" jsuis en mode debug donc il me met que le pool a atteint le maximum de connexion.

Dans mon code je ferme bien toutes mes connexion c'est sa que je ne comprend pas.

Et au maxi on est deux pour le moment :)
Commenter la réponse de cs_wally88
jesusonline 6827 Messages postés dimanche 15 décembre 2002Date d'inscription 13 octobre 2010 Dernière intervention - 5 janv. 2008 à 01:39
0
Utile
Quel pool ? t'as un message d'erreur ? un stack trace ?

<hr />Cyril - MSP - MCPD ASP.net & MCTS SQL - Consultant indépendant
Commenter la réponse de jesusonline
cs_wally88 361 Messages postés jeudi 5 février 2004Date d'inscription 1 octobre 2010 Dernière intervention - 5 janv. 2008 à 01:43
0
Utile
Euh la comme sa je peux pas te dire. je n'ai pas fais de copie d'ecran. et faut un certain avant d'avoir l'erreur que je ne sais pas trop quand elle peut se declencher.

Je ressaierais demain d'avoir l'erreur et je te posterais ce que j'ai.

Merci
Commenter la réponse de cs_wally88
cs_wally88 361 Messages postés jeudi 5 février 2004Date d'inscription 1 octobre 2010 Dernière intervention - 5 janv. 2008 à 14:18
0
Utile
Je ne savais meme pas qu'il y avait un pool special ADO.NET. Notement pour ça que je cherchais à en savoir un peu sur le pool.
Dans mes bouquin il ne parle pas de sa.

Apres une recheche google, je suis tombé sur ceci :

connection lifetime=5;
min pool size=1;
max pool size=50

Et l'article explique que meme avec sqcon.close(); la connexion n'est pas réellement détruite d'ou le lifetime ?

Je suppose que je dois au moin rajouter sa dans ma chaine de connexion mais quels sont les chiffres à mettre ? Pourquoi 5 ? pourquoi 1? pourquoi 50 ?

Merci
Commenter la réponse de cs_wally88
cs_wally88 361 Messages postés jeudi 5 février 2004Date d'inscription 1 octobre 2010 Dernière intervention - 5 janv. 2008 à 14:27
0
Utile
Voila j'ai récupérer l'erreur :

 
Server Error in '/' Application.
<hr width="100%" color="silver" size="1" />
Problème dans la méthode ChargerAnnonce3 Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Exception: Problème dans la méthode ChargerAnnonce3 Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.

Source Error:

Line 2053:        catch (Exception ex)
Line 2054:        {
Line 2055:            throw new Exception("Problème dans la méthode ChargerAnnonce3 " + ex.Message.ToString());
Line 2056:        }
Line 2057:        finally



Source File: c:\Inetpub\Www_root\App_Code\ClsAnnonce.cs    Line: 2055

Stack Trace:

[Exception: Problème dans la méthode ChargerAnnonce3 Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.]
ClsAnnonce.ChargerAnnonce8() in c:\Inetpub\Www_root\App_Code\ClsAnnonce.cs:2055
_Default.Page_Load(Object sender, EventArgs e) in c:\Inetpub\Www_root\Default.aspx.cs:18
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +25
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +58
System.Web.UI.Control.OnLoad(EventArgs e) +127
System.Web.UI.Control.LoadRecursive() +101
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2588

Commenter la réponse de cs_wally88
jesusonline 6827 Messages postés dimanche 15 décembre 2002Date d'inscription 13 octobre 2010 Dernière intervention - 5 janv. 2008 à 14:38
0
Utile
Oui quand tu fais un Conn.close la connection n'est pas fermé c'est le principe d'un Pool. ASP.net gère un pool de connection quand tu fais un new, il te retourne une instance de SqlConnection qui provient des n instances présente dans le pool et quand tu fais un close, ta connection retourne dans le pool.

Le problème que tu as et que tu ouvres trop de connection simultannées. Regarde quand ouvres tu une connection SQL, à chaque requête ? Si oui alors regarde avec sql profiler tu verras toutes les requêtes que tu fais. Il se peut que tu as une méthode récursive qui charge qui ouvre une connection par passage.

Si possible essaye d'identifier et isoler la méthode qui pose problème et ensuite regarde en pas à pas ce qui se passe. Si tu utilises qu'une seule méthode qui gère la création et ouverture de connexion. Tu peux aussi rajouter un point d'arret ici et regarde ce qui se passe.

En tout cas le problème est simple : tu ouvres trop de connection simultannement. Modifier la taille du pool de connection n'est pas une solution (au contraire) il faut impérativement savoir pourquoi tu as tant de connexion simultannées (surtout avec si peu d'user) avant de modifier ce paramètre. 

<hr />Cyril - MSP - MCPD ASP.net & MCTS SQL - Consultant indépendant
Commenter la réponse de jesusonline
cs_wally88 361 Messages postés jeudi 5 février 2004Date d'inscription 1 octobre 2010 Dernière intervention - 5 janv. 2008 à 14:47
0
Utile
Oui il est sur que j'ouvre pas mal de connexion, car ne serait que sur la masterpage, je charge des marques de voitures.
Je charge ces marques dans une premiere dropdown et dans une deuxieme. je charge les modele aussi fois deux.

Je fais pas mal  d'autres requetes.

Donc si c'est sur la masterpage et elle se charge quasi a chaque fois.

Mais comment puis-je faire pour ne par relancer les requetes disons qui ne servent qu'un fois. Du genre les marque et modele une fois qu'elle sont charger ne vont pas changer pour le restant du site, idem pour les informations sur le compte utilisateur etc..
Commenter la réponse de cs_wally88
cs_coq 6366 Messages postés samedi 1 juin 2002Date d'inscription 2 août 2014 Dernière intervention - 5 janv. 2008 à 14:51
0
Utile
Salut,

Déjà, tu devrais préciser de quel serveur SQL on parle.

Si nous parlons bien de SQL Server, toucher à Connection Lifetime n'est à ma connaissance utile que dans un environnement cluster, ça permet de faire une réparition de charge plus efficace (théorie, je n'ai jamais eu l'occasion de pratique sur une telle configuration).
Concernant le fait que les connexions ne soient pas réellement fermées, c'est justement le but du pool : éviter le cout de l'ouverture de la connexion.
Quand tu fermes une connexion poolée, elle retourne au pool (sauf si elle a dépasser son connection lifetime, qu'il soit par défaut (valeur aléatoire de maxi 8 minutes si mes souvenirs sonr bon) ou spécifié, auquel cas elle est réellement fermée et laissera place à une autre quand nécessaire), prête à être réutilisée par la prochaine ouverture demandée par l'application.

En spécifiant un max pool size de 50, tu réduis sa taille : celui par défaut est de 100 connexions normalement (ça doit dépendre du provider, mais celui intégré pour SQL Server c'est ça logiquement).

Spécifier Min Pool Size à 1 forcera la conservation d'une connexion ouverte dans le pool, à toi de voir si tu as réellement besoin de ça.

Mais dans tous les cas si tu arrives à un pool dont toutes les connexions sont utilisées de façon anormale (la charge n'étant pas logiquement suffisante pour une telle consommation), la solution n'est pas forcément d'augmenter démesurément la taille du pool : il faut avant tout chercher la cause de ce nombre de connexion ouvertes.

/*
coq
MVP Visual C#
CoqBlog
*/
Commenter la réponse de cs_coq
cs_wally88 361 Messages postés jeudi 5 février 2004Date d'inscription 1 octobre 2010 Dernière intervention - 5 janv. 2008 à 14:58
0
Utile
Merci pour toutes ses infos sur le pool j'y vois déjà plus clair sur son utilité.

Oui je suis bien sous sql serveur avec c#.net v2 pour le code.

Oui donc c'est bel et bine parce qsue j'ouvre trop de connexion. Maintenant je ne sais comment garder des données qui n'ont besoin d'etre charger en gros qu'une seul fois.  Mettre les dataset en variable de session ? :s
Commenter la réponse de cs_wally88
jesusonline 6827 Messages postés dimanche 15 décembre 2002Date d'inscription 13 octobre 2010 Dernière intervention - 5 janv. 2008 à 15:09
0
Utile
Même si tu fais pleins de requêtes par page, tu ne devrais pas avoir autant de requête en parallèle. Je te conseille d'ouvrir et fermer ta connexion pour chaque requête. Tu peux avoir des requêtes parallèles si tu fais un truc du genre

using(DataReader dr = SqlHelper.GetReader(command, conn)){
    while(dr.Read()){

        command2.parameters.Add(dr["truc"]);
        using (DataReader dr2 = SqlHelper.GetReader(command2, conn)){
              while(dr.Read()){
                     blabla
              }
        }
    }
}

c'est la seule raison d'avoir des connexion parallèles. Bien sur ce cas est simple mais c'est possible d'avoir des méthodes qui prenne en paramètre des DataReader (ce que je déconseille fortement) et ainsi avoir des problèmes du genre.
Vérifie que toutes tes connexions/DataReader sont bien close (le plus simple est de déclarer sa connexion/DataReader avec un Using)

<hr />Cyril - MSP - MCPD ASP.net & MCTS SQL - Consultant indépendant
Commenter la réponse de jesusonline
cs_wally88 361 Messages postés jeudi 5 février 2004Date d'inscription 1 octobre 2010 Dernière intervention - 5 janv. 2008 à 15:15
0
Utile
Oui j'utilise pas mal de datareader.
du genre : 

  public SqlDataReader chargerMarque()
    {
        string ConnnectionStr = ConfigurationManager.AppSettings["connexion"].ToString();
        SqlConnection sqlCon = new SqlConnection();
        sqlCon.ConnectionString = ConnnectionStr;
        string req = "select distinct * from marque order by marq_nom";
        SqlCommand sqlCom = new SqlCommand(req, sqlCon);
      
        sqlCon.Open();
        SqlDataReader result = sqlCom.ExecuteReader(CommandBehavior.CloseConnection);
     
        return result;
 
    }

Je n'utilise pas de using, je vais regarder tout sa de plus pres.

Merci.
Commenter la réponse de cs_wally88
cs_wally88 361 Messages postés jeudi 5 février 2004Date d'inscription 1 octobre 2010 Dernière intervention - 5 janv. 2008 à 15:29
0
Utile
Oki, et bien moi j'ai vue sa dans un livre ou je ne sais ou j'ai continué comme ça.
Donc je vais revoir toutes mes méthodes. en me basant sur ce que tu m'a montrer au dessus.
Donc peut etre bine sa mon probleme de pool :).

Je m'occupe de tout sa dans le weekend, on verra ce que ça donne :)

Ps: y a t il une endroit ou apprendre à coder propre ? :D

Merci beaucoup.
Commenter la réponse de cs_wally88
jesusonline 6827 Messages postés dimanche 15 décembre 2002Date d'inscription 13 octobre 2010 Dernière intervention - 5 janv. 2008 à 15:32
0
Utile
Reflector ?

concrétement c'est la pratique qui donne ces informations. J'ai également vu ce bouquin récemment : http://blogs.msdn.com/kcwalina/archive/2008/01/03/FrameworkDesignGuidelines2ndEdition.aspx mais pas testé.

Coq une idée ?

<hr />Cyril - MSP - MCPD ASP.net & MCTS SQL - Consultant indépendant
Commenter la réponse de jesusonline
cs_wally88 361 Messages postés jeudi 5 février 2004Date d'inscription 1 octobre 2010 Dernière intervention - 7 janv. 2008 à 17:20
0
Utile
Bonjour, voila j'ai fermer toutes les connexions apparement mais j'ai du en oublier car j'ai toujours l'erreur de pool.

J'ai utiliser close et dispose pour les dataset et les datareader.

Maintenant j'aimerais savoir si on ne peut pas voir quand sql serveur s'emballe ? dans windows serveur 2003  il y a les performances ou l'on peut voir l'état du processeur. J'aimerais savoir si il y aurait la meme chose pour sql serveur afin de voir a quel moment il s'emballe.

Merci.
Commenter la réponse de cs_wally88
cs_wally88 361 Messages postés jeudi 5 février 2004Date d'inscription 1 octobre 2010 Dernière intervention - 7 janv. 2008 à 18:37
0
Utile
voila, en faite j'ai trouver dans le sql server management, il y a un moniteur d'activité qui  permet de voir les requete en cours. une requete = un processus ou pas loin.

Lorsque j'ai testé la premiere fois, je voyais des processus s'ajouter pour la meme requete quand je naviguais sur le site. Alors qu'apperement si la requete à deja ete faite au lieu de recreer un processus, sa reprend celui d'avant. C'est pas bien clair si desfois les admins peuvent dire sa en clair pour aider.

Bref maintenant au lieu de me retrouver avec des processus qui n'arrete pas de se creer, j'en ai que 5.

Car je n'avais pas fermé les datareader et dataset mais grace au moniteur c'est plus simple de savoir ou.

Un petit lien qui explique les soucis avec les datareader et les dataset comme expliqué par cyril :
lien
Merci pour l'aide et pour les renseignement sur le pool et les fermeture biensur.
Commenter la réponse de cs_wally88
jesusonline 6827 Messages postés dimanche 15 décembre 2002Date d'inscription 13 octobre 2010 Dernière intervention - 7 janv. 2008 à 19:06
0
Utile
" une requete = un processus ou pas loin. " ==> euh ??? Je connais pas beaucoup sql server mais je peux te garantir que non ... ou alors on parle pas des memes processus.


Le moniteur d'activité est certes sympa mais sql profiler est bien plus sympa ! regarde ce coté là tu trouveras bien des choses interessante.


Au niveau des fermetures, il faut fermer/disposer les DataReader, les DataAdapter et les SqlConnection, les DataSet "on s'en fout", bien sur faut le faire mais  cela joue pas avec la connection sql puisque par définition un dataset est déconnecté





<hr />
- MSP - MCPD ASP.net & MCTS SQL - Consultant indépendant
Commenter la réponse de jesusonline

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.