Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[ Tomcat && pool JDBC ] Resistance de charge

8 réponses
Avatar
Jim How
Salut,

J'ai une Web Application qui tourne sur Tomcat (5.x) (et Apache 2 via JK) et
qui utilise un pool de connexion JDBC MySQL.

Pour tester la resistance de charge j'utilise OpenSta histoire de simuler
des visteurs "facilement"...

Avec un utilisateur, ou avec plusieurs en décalé, je n'ai aucun problème mes
pages sont niquel (même taille en octets).

Si par contre je multiplie les utilisateurs simultanés (à quelques milliemes
de secondes pres), je me retrouve avec des pages qui partent en vrille, voir
même des pages vierges.

Apparament Tomcat par moment n'ouvre pas la connexion à la base (je
suppose).
(Je suppose aussi que cela se passe quand les connexions du pool sont toutes
occupés).


Bon Tomcat c'est quand même sencé resister à plusieurs centaines de
visiteurs en simultanés, alors est ce que je dois chercher dans le
parametrages de mon Pool ou du coté de ma prog ?


Ci dessous mes paramtères de context :

<ResourceParams name="jdbc/MyDb">
<parameter>
<name>username</name>
<value>xxxxxxxxxx</value>
</parameter>
<parameter>
<name>password</name>
<value>xxxxxxxxxxxx</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost/base</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>50</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>25</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>10</value>
</parameter>
<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>
<parameter>
<name>removeAbandonedTimeout</name>
<value>50</value>
</parameter>
</ResourceParams>

Pour infos, j'utilise uniquement des classes et des servlets.

Voilà merci de votre aide :)

Jim

8 réponses

Avatar
Thibaut
Salut,

as tu bien pensé à mettre des bouts de code en "synchronized" ?

Thibaut


"Jim How" a écrit dans le message de news:
44087e2e$0$21287$
Salut,

J'ai une Web Application qui tourne sur Tomcat (5.x) (et Apache 2 via JK)
et qui utilise un pool de connexion JDBC MySQL.

Pour tester la resistance de charge j'utilise OpenSta histoire de simuler
des visteurs "facilement"...

Avec un utilisateur, ou avec plusieurs en décalé, je n'ai aucun problème
mes pages sont niquel (même taille en octets).

Si par contre je multiplie les utilisateurs simultanés (à quelques
milliemes de secondes pres), je me retrouve avec des pages qui partent en
vrille, voir même des pages vierges.

Apparament Tomcat par moment n'ouvre pas la connexion à la base (je
suppose).
(Je suppose aussi que cela se passe quand les connexions du pool sont
toutes occupés).


Bon Tomcat c'est quand même sencé resister à plusieurs centaines de
visiteurs en simultanés, alors est ce que je dois chercher dans le
parametrages de mon Pool ou du coté de ma prog ?


Ci dessous mes paramtères de context :

<ResourceParams name="jdbc/MyDb">
<parameter>
<name>username</name>
<value>xxxxxxxxxx</value>
</parameter>
<parameter>
<name>password</name>
<value>xxxxxxxxxxxx</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost/base</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>50</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>25</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>10</value>
</parameter>
<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>
<parameter>
<name>removeAbandonedTimeout</name>
<value>50</value>
</parameter>
</ResourceParams>

Pour infos, j'utilise uniquement des classes et des servlets.

Voilà merci de votre aide :)

Jim






Avatar
Jim How
Salut,

Avant tout merci de ta réponse.

Heu, qu'est ce que tu entend par un bout de code en "Synchronised" ?
Visiblement non ...

As-tu une url ? un tuto ? un exemple ?

Merci

Jim


Salut,

as tu bien pensé à mettre des bouts de code en "synchronized" ?

Thibaut


"Jim How" a écrit dans le message de news:
44087e2e$0$21287$
Salut,

J'ai une Web Application qui tourne sur Tomcat (5.x) (et Apache 2 via JK)
et qui utilise un pool de connexion JDBC MySQL.

Pour tester la resistance de charge j'utilise OpenSta histoire de simuler
des visteurs "facilement"...

Avec un utilisateur, ou avec plusieurs en décalé, je n'ai aucun problème
mes pages sont niquel (même taille en octets).

Si par contre je multiplie les utilisateurs simultanés (à quelques
milliemes de secondes pres), je me retrouve avec des pages qui partent en
vrille, voir même des pages vierges.

Apparament Tomcat par moment n'ouvre pas la connexion à la base (je
suppose).
(Je suppose aussi que cela se passe quand les connexions du pool sont
toutes occupés).


Bon Tomcat c'est quand même sencé resister à plusieurs centaines de
visiteurs en simultanés, alors est ce que je dois chercher dans le
parametrages de mon Pool ou du coté de ma prog ?


Ci dessous mes paramtères de context :

<ResourceParams name="jdbc/MyDb">
<parameter>
<name>username</name>
<value>xxxxxxxxxx</value>
</parameter>
<parameter>
<name>password</name>
<value>xxxxxxxxxxxx</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost/base</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>50</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>25</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>10</value>
</parameter>
<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>
<parameter>
<name>removeAbandonedTimeout</name>
<value>50</value>
</parameter>
</ResourceParams>

Pour infos, j'utilise uniquement des classes et des servlets.

Voilà merci de votre aide :)

Jim










Avatar
Jim How
Salut,

as tu bien pensé à mettre des bouts de code en "synchronized" ?


Bon effectivement j'ai cherché un peu sur le net et après avoir passé les
doGet() et doPost() en Synchronized ça marche plutôt mieux.

J'ai quelques pages encore à 0 et des temps de réponse plutôt longs mais
avec 50 utilisateurs simultanés sur les même urls.

Est-ce que je dois passer d'autres objets en synchronized où non.
Si oui, comment savoir quand le faire ou non ?

Merci en tout cas encore une fois, de ce coup de pousse.

Thibaut


Jim

Avatar
Simon OUALID

Bon effectivement j'ai cherché un peu sur le net et après avoir passé les
doGet() et doPost() en Synchronized ça marche plutôt mieux.



Ahhhhh ! Hérésie ! Erk ! :

En mettant l'attribut synchronized sur ces méthodes, ton servlet devient
incapable de traiter deux requêtes en même temps ! Bonjour les
performances ! Tu ne peux traiter qu'une requête à la fois... et tu fous
en l'air une bonne partie de j2ee (un servlet, instancié qu'une fois,
peux traiter plusieurs requêtes en même temps, ce qui permet de bien
monter en charge).

Tu dois mettre du synchronized dans tes DAO si tu n'utilises pas de
DataSource mais directement une connexion physique (tu te
synchroniserais alors sur l'objet Connection).

Mais vu ton message, tu utilises déja une DataSource, qui est *déja*
thread safe (cf. doc).

Regarde plutôt dans la conf de ton pool, tu as un maxWait à 10, tu
autorises donc dbcp à attendre 10 secondes si aucune connexion n'est
disponible dans le pool. Passe cette valeur à -1 pour n'autoriser aucune
attente (attention à bien dimensionner le pool, maxActive/Idle, dans ce
cas).

Mais par pitié, retire ce lock (synchronized) des méthodes do*** de ton
servlet.

Avatar
TestMan
Cou²,

En premier, vérifie le nombre de connexion du coté du mySQL !

J'ai souvenir, que par défaut c'est pas énnorme (ça a certainement du
évoluer depuis).

Mais, j'ai pas de souvenir de problèmes, pour un scénario d'injection
que j'avait fait avec opensta on avait injecté avec succès plus de 250
transaction simmultanées ... ce qui était suffisant car notre "pic"
était souhaité à 50.

Et 250 était la limité aprés analyse ....de notre réseau ;-)

Fait test tests sans apache en frontal car il fausse pas mal les choses,
je te conseille aussi d'essayer avec le connecteur coyote du 5.5 en direct !

Et si vraiment tu veux "mettre à feu" ton réseau ;-)
http://weblogs.java.net/blog/jfarcand/archive/2005/06/grizzly_an_http.html

A+

TM

Salut,

J'ai une Web Application qui tourne sur Tomcat (5.x) (et Apache 2 via JK) et
qui utilise un pool de connexion JDBC MySQL.

Pour tester la resistance de charge j'utilise OpenSta histoire de simuler
des visteurs "facilement"...

Avec un utilisateur, ou avec plusieurs en décalé, je n'ai aucun problème mes
pages sont niquel (même taille en octets).

Si par contre je multiplie les utilisateurs simultanés (à quelques milliemes
de secondes pres), je me retrouve avec des pages qui partent en vrille, voir
même des pages vierges.

Apparament Tomcat par moment n'ouvre pas la connexion à la base (je
suppose).
(Je suppose aussi que cela se passe quand les connexions du pool sont toutes
occupés).


Bon Tomcat c'est quand même sencé resister à plusieurs centaines de
visiteurs en simultanés, alors est ce que je dois chercher dans le
parametrages de mon Pool ou du coté de ma prog ?


Ci dessous mes paramtères de context :

<ResourceParams name="jdbc/MyDb">
<parameter>
<name>username</name>
<value>xxxxxxxxxx</value>
</parameter>
<parameter>
<name>password</name>
<value>xxxxxxxxxxxx</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost/base</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>50</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>25</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>10</value>
</parameter>
<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>
<parameter>
<name>removeAbandonedTimeout</name>
<value>50</value>
</parameter>
</ResourceParams>

Pour infos, j'utilise uniquement des classes et des servlets.

Voilà merci de votre aide :)

Jim






Avatar
Jim How

Bon effectivement j'ai cherché un peu sur le net et après avoir passé les
doGet() et doPost() en Synchronized ça marche plutôt mieux.



Ahhhhh ! Hérésie ! Erk ! :


Oups pardon... :(

En mettant l'attribut synchronized sur ces méthodes, ton servlet devient
incapable de traiter deux requêtes en même temps ! Bonjour les
performances ! Tu ne peux traiter qu'une requête à la fois... et tu fous
en l'air une bonne partie de j2ee (un servlet, instancié qu'une fois, peux
traiter plusieurs requêtes en même temps, ce qui permet de bien monter en
charge).



Ok, oui expliquer comme ça ça parait con de l'avoir fait...


Tu dois mettre du synchronized dans tes DAO si tu n'utilises pas de
DataSource mais directement une connexion physique (tu te synchroniserais
alors sur l'objet Connection).



Bon je deploy un war pour des questions de facilité mais je n'utilise pas
vraiment l'archie J2EE.
J'ai un ou plusieurs servlets qui font appelent à des class/objets qui
interagissent plus ou moins avez la BDD via le pool.

J'ai appris java sur le tas, et le peu de fois ou j'ai tenté de m'interesser
à du J2EE,
ou des Bean Entreprise j'ai épuisé les stocks du pharamacien en Aspro.

J'ai commencé Java avec mon projet, et donc du coup j'ai pas forcément 15
ans de bagages sur comment fonctionne le pourquoi du comment de la chose.
(J'ai du regarder sur Google ce qu'etait un DAO).


Mais vu ton message, tu utilises déja une DataSource, qui est *déja*
thread safe (cf. doc).



J'utilise le Pool de Tomcat si c'est ce que tu veux dire...


Regarde plutôt dans la conf de ton pool, tu as un maxWait à 10, tu
autorises donc dbcp à attendre 10 secondes si aucune connexion n'est
disponible dans le pool. Passe cette valeur à -1 pour n'autoriser aucune
attente (attention à bien dimensionner le pool, maxActive/Idle, dans ce
cas).

Mais par pitié, retire ce lock (synchronized) des méthodes do*** de ton
servlet.



Ok j'ai mis à -1, viré tout les synchronized, et avec 4 connexions en
simultanées je retourne à un appli instable et aléatoire.

Quelqu'un aurait un exemple genre "Web Application pour les nuls" (ce que je
me considère de plus en plus) ?
Je pensais avoir résolu mon problème, et pouvoir avancer sur autre chose
mais la je retourne à la case départ...


Merci de votre aide.


Avatar
Jim How
Cou²,

En premier, vérifie le nombre de connexion du coté du mySQL !

J'ai souvenir, que par défaut c'est pas énnorme (ça a certainement du
évoluer depuis).



100 par défaut mais mon problème ne viens pas de là...


Mais, j'ai pas de souvenir de problèmes, pour un scénario d'injection que
j'avait fait avec opensta on avait injecté avec succès plus de 250
transaction simmultanées ... ce qui était suffisant car notre "pic" était
souhaité à 50.



Le problème vient certainement de mon code, j'ai codé mes servlets comme je
code en Php, Perl ou Python..
J'apelle des classes et basta.

J'arive pas à trouvé un exemple concret de code, clair, précis et didactique
sur comment procédé en java/servlet pour voir la différence entre ce que je
fais et ce qu'il faut faire...



Et 250 était la limité aprés analyse ....de notre réseau ;-)

Fait test tests sans apache en frontal car il fausse pas mal les choses,
je te conseille aussi d'essayer avec le connecteur coyote du 5.5 en direct
!

Et si vraiment tu veux "mettre à feu" ton réseau ;-)
http://weblogs.java.net/blog/jfarcand/archive/2005/06/grizzly_an_http.html




Heu si j'ai bien tout compris tu me propose de virer apache ?
Le problème c'est que je voudrais garder une archi classique genre
Apache/Php étant plus facile à administrer et pour ajouter quelques trucs
par ci par la, plutot que de tout passer en full java...



A+

TM



A+ Merci

Jim

Avatar
Simon OUALID
Jim How wrote:
J'ai appris java sur le tas, et le peu de fois ou j'ai tenté de m'interesser
à du J2EE,
ou des Bean Entreprise j'ai épuisé les stocks du pharamacien en Aspro.

J'ai commencé Java avec mon projet, et donc du coup j'ai pas forcément 15
ans de bagages sur comment fonctionne le pourquoi du comment de la chose.
(J'ai du regarder sur Google ce qu'etait un DAO).



Dans ce cas la il fallait peut être choisir un autre langage sur ce
projet, mais j'ai l'impression qu'il y avait une contrainte forte dans
le choix du langage utilisé. Mais la n'est pas le débat.


J'utilise le Pool de Tomcat si c'est ce que tu veux dire...



Tu utilises donc DBCP qui implémente l'interface DataSource définie par
Sun dans JDBC, et qui dit explicitement que l'implémentation de cette
objet doit être "thread safe". C'est du blabla pour dire que tu peux y
aller et ne pas avoir à "trop" faire attention aux problèmes de
synchronisations (que tu traitais *très* violemment avec l'attribut
synchronized).

Ok j'ai mis à -1, viré tout les synchronized, et avec 4 connexions en
simultanées je retourne à un appli instable et aléatoire.


Configure ton pool en verbose et regarde les logs tomcat pour voir si tu
n'as pas des connexions ou des curseurs abandonnés ou tout autre
problème provenant de ton code... Tes "fermetures" de connexions se font
bien dans le bloc finally qui suit le try/catch ?


Quelqu'un aurait un exemple genre "Web Application pour les nuls" (ce que je
me considère de plus en plus) ?
Je pensais avoir résolu mon problème, et pouvoir avancer sur autre chose
mais la je retourne à la case départ...




Les blueprints de Sun sont verbeux et peuvent faire peur à premièr vue
mais ils sont bien foutus... Faut savoir dépioter et prendre ce qui est
"réellement" utilisé (perso je n'ai jamais croisé dans la vrai vie
certains des patterns que j'ai pu étudier dans des bouquins ou en
formation).

Déja si tu t'éfforces à organiser ton développement en couche (cf plus
haut), pour un développement web on utilises dans 99.9% des cas le
pattern "Service to Worker", cette doc est bien pour comprendre cette
archi :
http://java.sun.com/blueprints/corej2eepatterns/Patterns/ServiceToWorker.html

Pour les DAO qui se branchent juste derrière, il y a une bonne doc ici :
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

Mais il faut que bosses de manière plus générale le développement en
"couches applicatives" : controlleur (actions), métier (modèle +
service), dao ...

Et sur ton problème plus particulièrement, vérifie la conf de ta base,
colle ton serveur en verbose pour avoir une trace de ce qui se passe sur
ces requêtes non traitées. Ce genre de problème vient le plus souvent du
code.

Merci de votre aide.



De rien. J'espère n'avoir pas été trop lourd. :)