ZEP-17 : Elaboration de l'API des membres

a marqué ce sujet comme résolu.

Sinon, dans ma série de tests, j'aimerais vérifier que le cache des Etag fonctionne bien sur les GET. Pour cela il se peut que je frappe la preprod a grand coup de requêtes http.

Je me demandais donc si la version déployée en préprod actuellement marche pour le cache des Etag en GET. Si oui, est-ce que je peux faire ces tests sur la préprod qui ressembleront plutôt à des tests de charges.

Je ne vois pas le point commun entre des vérifications de Etag et des tests de charge personnellement.

SpaceFox

Pour tester le cache Etag au niveau 1, je pense laisser tourner une requête en boucle qui me renvoi la liste des membres par exemple, et pendant ce temps je fais une nouvelle inscription et j'observe le résultat de mon premier thread pour vérifier que le tag a changé au bon moment.

Si le premier test est concluant, je vais donc simuler la même boucle mais sur 8 thread en parallèle. 8 n'est pas un nombre choisi au hasard, car je sais que la preprod utilise 7 workers gunicorn. Je vais juste m'assurer qu'il n'y a pas de rapport entre le cache et les workers.

Bref, ça risque de frapper un peu fort et si le cache n'est pas bien configuré, le serveur pourra peut être tomber.

La boucle est complètement inutile : un appel avant et un appel après suffisent. Ou alors il y a quelque chose que je ne comprends vraiment pas.

Idem avec les threads : je ne vois pas l'intérêt de ce test. Si c'était un problème avec les threads, on aurait un comportement aléatoire typique : "des fois ça marche, des fois ça marche pas, selon le thread sur lequel tu tapes". A ma connaissance ce n'est pas le cas ici.

Comment tu peux établir le lien de façon certaine entre des requêtes HTTP exécutées par un client et le thread côté serveur qui va gérer la requête.

J'ai sans doute raté un truc mais je comprends pas la corrélation.

+0 -0

Ah oui, je confirme : on a aucun moyen de savoir quel worker va vraiment être utilisé.

Ma remarque ne fonctionne que dans un sens en fait : quand tu constates qu'il y a un comportement du style "ça marche, ça marche pas, au hasard" et que la proportion de ça marche et ça marche pas est corrélée avec un nombre de threads, ça vient sans doute de là.

Par contre prouver que "ça marche tout le temps / jamais depuis mon injecteur X" ne prouve rien tant que tu n'as pas aussi la règle d'attribution des threads arrivant : on trouve du round robin, du hasard pur, du chaque IP utilise toujours le même thread, de l'utilisation de cookies pour fixer un thread, etc.

La boucle est complètement inutile : un appel avant et un appel après suffisent. Ou alors il y a quelque chose que je ne comprends vraiment pas.

SpaceFox

Dans l'absolu oui, mais imagine qu'il y'ait un bug qui fait qu'au bout de 10/20/30/…/100 appels GET ton Etag bascule ? Tu ne peux pas le savoir en faisant un seul appel avant et après.

A firm1. Javier veux dire que "si ca se trouve tes 8 threads clients vont taper sur toujours les 2 memes threads serveur, tu n'as aucun moyen de le savoir".

Eskimon

Si c'est bien ça le sens de la question, je dirais que justement je n'ai aucune idée de la ou il va taper, mais dans le doute je teste quand même que ça se comporte bien. Car 8 clients qui tapent sur l'API en parallèle est un use case qui va surement arriver.

Dans l'absolu oui, mais imagine qu'il y'ait un bug qui fait qu'au bout de 10/20/30/…/100 appels GET ton Etag bascule ? Tu ne peux pas le savoir en faisant un seul appel avant et après.

Donc, tu vas taper disons 1000 appels. Imagine qu'il y ait un bug qui fait qu'au bout de 1001 appels GET ton Etag bascule ? Tu ne peux pas le savoir en faisant que 1000 appels après.

Sérieusement, c'est un vrai cas déjà rencontré avec un vrai bout de code et un vrai use case qui te font penser que c'est possible ; ou bien tu spécules dans le vide et tu as surtout envie de taper comme un bourrin sur le serveur pour t'amuser ?

Si c'est bien ça le sens de la question, je dirais que justement je n'ai aucune idée de la ou il va taper, mais dans le doute je teste quand même que ça se comporte bien. Car 8 clients qui tapent sur l'API en parallèle est un use case qui va surement arriver.

Un use case qui pour l'instant est rarissme (cf les graphes Munin : c'est très exceptionnel qu'on utilise les 7 workers en même temps).

En fait ce que tu veux faire c'est un test de charge. Là, j'ai pas de problème, à condition que ce soit un test de charge un minimum valable :

  • Scénario d'utilisation crédible
  • Charge crédible
  • Métriques complètes
  • Analyse des résultats

tu spécules dans le vide et tu as surtout envie de taper comme un bourrin sur le serveur pour t'amuser ?

J'ai un trajet de 2h de prévu, je pense que ça va m'occuper :)

Un use case qui pour l'instant est rarissme

Tout l'intérêt d'un test c'est de tester le plus possible le maximum de cas. Si jamais on tombe sur un bug, on jugera par la suite si le scénario est crédible ou pas. D'autant plus que le test est facile à faire.

@firm1 du coup le chiffre 8 est pris au hasard finalement, parce que ça n'a strictement aucun lien, j'aurais tendance à taper bien plus fort que ça si tu veux avoir la certitude que tous les workers côté serveur soient employés.

+2 -0

Écoute, je ne vais pas me battre pour t'empêcher de perdre du temps, alors je vais la faire simple : si tu veux t'amuser avec le serveur, je ne vais pas t'en empêcher, tant que tu respectes toutes ces conditions :

  1. Tu ne pètes rien, ou tout est rétabli nickel une fois le test fini.
  2. Tu surveilles ton test pour que si quelque chose parte en vrille on ne mette pas 8h à s'en rendre compte.
  3. Tu laisses le serveur disponible si quelqu'un a un test réel à faire. Par exemple, moi sur la préprod ce soir.
  4. Ça reste 100% invisible pour tout le monde (utilisateurs de ZdS en prod ou autres).

@firm1 du coup le chiffre 8 est pris au hasard finalement, parce que ça n'a strictement aucun lien, j'aurais tendance à taper bien plus fort que ça si tu veux avoir la certitude que tous les workers côté serveur soient employés.

Javier

Je peux taper encore plus fort, mais je ne vois pas d'autres métriques qui pourront causer un bug. On est sur du 4 cores, avec 7 workers, donc si je balance en continue 500 GET sur 8 thread en parallèle, je crois que j'ai fais le plus gros quand même. Et au moins on saura que le cache Etag fonctionne bien :)

  1. Tu ne pètes rien, ou tout est rétabli nickel une fois le test fini.
  2. Tu surveilles ton test pour que si quelque chose parte en vrille on ne mette pas 8h à s'en rendre compte.

SpaceFox

Difficile de peter des trucs avec des GET.

  1. Tu laisses le serveur disponible si quelqu'un a un test réel à faire. Par exemple, moi sur la préprod ce soir.
  2. Ça reste 100% invisible pour tout le monde (utilisateurs de ZdS en prod ou autres).

SpaceFox

ça devrait se faire entre 03h et 05h sur la preprod quand j'aurai fait le script qui va bien (donc pas ce soir).

Difficile de peter des trucs avec des GET.

Les dénis de service avec GET, c'est très faisable. Après ça dépend de la techno du serveur (hors de toute protection spécifique) et de l'application : y'en a qui vont ramer uniquement pendant l'attaque, d'autres qui vont crasher à trop haute charge et vont demander un redémarrage, d'autres encore qui ne vont pas planter mais se retrouver dans un état bizarre.

ça devrait se faire entre 03h et 05h sur la preprod quand j'aurai fait le script qui va bien (donc pas ce soir).

Si tu vérifies le lendemain première heure que la préprod est encore debout, c'est OK.

je balance en continue 500 GET sur 8 thread en parallèle

Je comprends définitivement pas.

Quand je fais un test de charge, j'essaie d'instancier un thread par client, justement pour qu'ils vivent leur vie indépendamment les uns des autres.

Si possible, pas complètement synchrones histoire de m'approcher de la réalité.

Après je regarde combien de threads sont utilisés côté serveur en fonction du nombre de clients que j'ai instanciés.

Et c'est très rarement du 1 pour 1.

Là ça me paraît très théorique comme approche, ou alors encore une fois j'ai raté un truc.

Si j'ai bien compris :

  • tes requêtes sont synchrones : j'envoie, quand j'ai le résultat j'en envoie une seconde. Et ce, 500 fois d'affilée

  • tu utilises 8 threads en parallèle, donc 8 requêtes partent au même moment (à t0) et tu supposes que 8 workers seront utilisés côté serveur pour les traiter

  • les temps de réception de chaque réponse sont évidemment différents pour chaque requête (rien que du fait de la gigue/latence réseau)

  • dès la deuxième requête http, tes requêtes sont désynchronisées. Dès lors, difficile de savoir sur combien de workers tu tapes

Ce que je ne comprends pas, vraiment, c'est le coup des 8 threads. C'est pas parce que t'as 8 threads côté clients que tu t'assures que t'as tapé sur les 7 workers. Y'a vraiment un truc qui me dépasse là.

Mais bon c'est ptetre que je connais mal WSGI.

+1 -0

Là ça me paraît très théorique comme approche, ou alors encore une fois j'ai raté un truc.

Non, je confirme, la réalité colle à ta théorie (je suis encore dessus au boulot aujourd'hui).

En fait, tu n'as même pas garantie que tes 8 requêtes à t0 arrivent en même temps, puisque elles aussi sont soumises au réseau.

Le seul moyen d'avoir la garantie que les 7 workers sont utilisés en même temps, c'est de balancer des requêtes de plus en plus vite, et de monitorer le nombre de workers utilisés, et ce jusqu'à atteindre les 7 workers réellement utilisés.

Ah et au fait, on a trois cœurs en prod et en préprod. Et donc 7 workers gunicorn, qui conseille "2 x nombre de cœurs + 1".

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte