Fonctionnement du pool d'application

Résolu
cs_wally88 Messages postés 361 Date d'inscription jeudi 5 février 2004 Statut Membre Dernière intervention 1 octobre 2010 - 4 janv. 2008 à 11:23
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 - 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.
A voir également:

20 réponses

cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
5 janv. 2008 à 08:52
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
*/
3
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 29
5 janv. 2008 à 15:22
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
3
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
5 janv. 2008 à 16:27
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
*/
3
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 29
5 janv. 2008 à 01:16
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_wally88 Messages postés 361 Date d'inscription jeudi 5 février 2004 Statut Membre Dernière intervention 1 octobre 2010
5 janv. 2008 à 01:23
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 :)
0
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 29
5 janv. 2008 à 01:39
Quel pool ? t'as un message d'erreur ? un stack trace ?

<hr />Cyril - MSP - MCPD ASP.net & MCTS SQL - Consultant indépendant
0
cs_wally88 Messages postés 361 Date d'inscription jeudi 5 février 2004 Statut Membre Dernière intervention 1 octobre 2010
5 janv. 2008 à 01:43
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
0
cs_wally88 Messages postés 361 Date d'inscription jeudi 5 février 2004 Statut Membre Dernière intervention 1 octobre 2010
5 janv. 2008 à 14:18
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
0
cs_wally88 Messages postés 361 Date d'inscription jeudi 5 février 2004 Statut Membre Dernière intervention 1 octobre 2010
5 janv. 2008 à 14:27
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

0
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 29
5 janv. 2008 à 14:38
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
0
cs_wally88 Messages postés 361 Date d'inscription jeudi 5 février 2004 Statut Membre Dernière intervention 1 octobre 2010
5 janv. 2008 à 14:47
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..
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
5 janv. 2008 à 14:51
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
*/
0
cs_wally88 Messages postés 361 Date d'inscription jeudi 5 février 2004 Statut Membre Dernière intervention 1 octobre 2010
5 janv. 2008 à 14:58
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
0
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 29
5 janv. 2008 à 15:09
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
0
cs_wally88 Messages postés 361 Date d'inscription jeudi 5 février 2004 Statut Membre Dernière intervention 1 octobre 2010
5 janv. 2008 à 15:15
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.
0
cs_wally88 Messages postés 361 Date d'inscription jeudi 5 février 2004 Statut Membre Dernière intervention 1 octobre 2010
5 janv. 2008 à 15:29
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.
0
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 29
5 janv. 2008 à 15:32
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
0
cs_wally88 Messages postés 361 Date d'inscription jeudi 5 février 2004 Statut Membre Dernière intervention 1 octobre 2010
7 janv. 2008 à 17:20
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.
0
cs_wally88 Messages postés 361 Date d'inscription jeudi 5 février 2004 Statut Membre Dernière intervention 1 octobre 2010
7 janv. 2008 à 18:37
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.
0
jesusonline Messages postés 6814 Date d'inscription dimanche 15 décembre 2002 Statut Membre Dernière intervention 13 octobre 2010 29
7 janv. 2008 à 19:06
" 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
0
Rejoignez-nous