Temps de réponse très dégradés depuis le déploiement de la P24

Bonsoir David,
merci beaucoup.
J’ai déployé la nouvelle image en ajoutant dans la définition de stack la variable d’environnement GZIP=true:

services:
  ${SIA}-bcsi:
    image: ${DOCKER_REGISTRY}/${DOCKER_IMAGE_BCSI}:${CI_PIPELINE_ID}
    environment:
      - "URI_CHECK=/${SIA}"
      - "DB_SETUP=true"
      - "DB_VENDOR=mysql"
      - "DB_HOST=${Database0Host}"
      - "DB_PORT=${Database0Port}"
      - "DB_USER=${Database0User}"
      - "DB_PASSWORD=${Database0Password}"
      - "DB_NAME=${Database0ServiceName}"
      - "CATALINA_OPTS= -Dplatform.autoupgrade=true -Dserver.websocket=false -Dhttps.proxyHost=${HTTPS_PROXY_HOST} -Dhttps.proxyPort=${HTTPS_PROXY_PORT} -Dhttp.proxyHost=${HTTPS_PROXY_HOST} -Dhttp.proxyPort=${HTTPS_PROXY_PORT} -Xms1500m -Xmx2500m"
      - "TOMCAT_TIMEZONE=Europe/Paris"
      - "API_EXTRA_PATTERNS=licenses,legal,security-services,data-architecture,functions-architecture,glossary"
      - "GZIP=true"

Est-ce la bonne manière d’activer cette fonctionnalité?

C’est déployé sur nos environnements de dev/tests.
Je ne vois toujours pas de header Content-Encoding…

Par contre, je pense que l’optimisation des métadonnées est effective var j’ai gagné environ 700ko sur la taille de la réponse de mon cas test (1,6Mo->960Ko). Les données ne sont cependant (a priori) toujours pas compressées (en environnement de dev et de tests). Ou alors je ne sais pas comment vérifier cela.

Effectivement il y avait un raté dans la prise en compte du GZIP=true dans les images.

C’est corrigé. Les images sont à jour.

Voilà ce que ça donne sur un test de base:


Le ratio de compression est > 6 pour les JSON d’une taille significative.

PS: la réduction que tu as constaté doit uniquement être lié à tes modifs et aux optims de @Francois, avec le gzip tu derais passer de 700Kb à 100Kb

Bonjour David, François,

merci beaucoup pour votre support.
Je confirme qu’a priori, les réponses aux requêtes POST ne sont pas compressées.
Les réponses aux GET le sont néanmoins:

[Platform]
Status=OK
Version=4.0.P24
BuiltOn=2020-04-24 22:35 (revision 3fe76ae912e69f249470c97013574fce47b7e1d2)

CI/CD lancé ce matin (vers 8h) avec la réference suivante de l’image docker qui a été pull:

Step 1/3 : FROM simplicite/platform:latest

[128](https://gitlabee.dt.renault.com/irn-68521/bca/-/jobs/18093980#L128) latest: Pulling from simplicite/platform
...
[165](https://gitlabee.dt.renault.com/irn-68521/bca/-/jobs/18093980#L165) Digest: sha256:6530c40c7fb1c9b59c427145c38d20e9976f90013ad0374336fc79770c8b0605

[166](https://gitlabee.dt.renault.com/irn-68521/bca/-/jobs/18093980#L166) Status: Downloaded newer image for simplicite/platform:latest

Sur mon environnement de test les POST sont bien compressées:

Mais mon image n’est à priori pas celle que tu indique, la mienne est celle qui a été poussée hier soir sur DockerHub:

Je crois que vous tapez pas directement sur DockerHub mais sur un repo privé qui pulle depuis DockerHub selon une logique et à une fréquence que je ne connais pas…

Le hash de l’image à jour c’est celle indiquée dans le post précédent:

simplicite/platform:latest
DIGEST:sha256:6530c40c7fb1c9b59c427145c38d20e9976f90013ad0374336fc79770c8b0605

OK, du coup, c’est le bon hash (cf. mon post précédent).
Donc nous sommes bien à jour (indépendamment du --no-cache).

Je confirme néanmoins qu’aucune réponse aux requêtes POST n’est compressée mais que les réponses aux GET le sont (en tenant compte de la taille de la réponse car si c’est en dessous d’une taille mini, la compression peut être désactivée).

Sur Tomcat par défaut le seuil de déclenchement compression est 2Kb, cf. Apache Tomcat 9 Configuration Reference (9.0.76) - The HTTP Connector (cherche “compressionMinSize”)

Dans notre cas on laisse les valeurs par défaut des attributs relatifs à la compression on met juste compression="on". Je ne vois rien qui laisserait entendre que la compression ne concerne pas le POST.

J’ai refais mon test en tapant ici directement sur le port 8080 du container (la dernière fois ça passait via un Traefik) la compression concerne bien ici aussi les requêtes POST:

As tu moyen de tester “au cul du container” comme je le fais ci-dessus ?

A priori, non…
le endpoint serait celui indiqué dans le health (port 8080) mais celui-ci n’est pas public.

[Platform]
Status=OK
Version=4.0.P24
BuiltOn=2020-04-24 22:35 (revision 3fe76ae912e69f249470c97013574fce47b7e1d2)
Encoding=UTF-8
EndpointIP=21.1.49.5
EndpointURL=http://2d7ef2fca232:8080

un curl sur le endpoint avec l’adress (form hexadécimale) se solde par un ‘Your requested host “2d7ef2fca232” could not be resolved by DNS’ et un call en utilisant l’adresse IP se solde par un ‘operation timeout’.

Le endpoint indiqué ici c’est le hostname interne au réseau Docker, quand on est pas sur Docker on a du localhost à cet endroit. C’est le endpoint “de service” qui n’est pas accessible de l’extérieur (et qui d’ailleurs en 4.0 ne sert plus à rien).

Dans ton cas j’imagine que les ports exposés par les containers (8080, 8443, …) sont encapsulé à plusieurs niveaux par votre infra, peut être que ces couches de reverse proxying décompressent les réponses de Tomcat et ne les recompressent pas, en tout cas pas les POST.

Tout ce que je peux dire c’est qu’ “au cul du container” avec GZIP=true tout sort bien gzippé (GET et POST). Ce qui se passe ensuite je ne sais pas.

A noter qu’en plus du “au cul du container” on a testé avec GZIP=true sur 2 serveurs de test avec du reverse proxying (qui gère le SSL):

  • un Traefik (qui ne gère pas le gzip)
  • un NGINX (qui gère le gzip)

Dans les deux cas ça marche bien, dans le cas NGINX je ne sais pas s’il décompresse/recompresse au passage mais à l’arrivé tout est toujours compressé GET et POST.
Le seul test qu’on a pas fait c’est avec un NGINX qui ne gère pas le gzip… peut être est tu dans ce cas là…

Merci beaucoup pour ton aide.
j’ai remonté le problème à nos équipes d’expertise technique devops.

Bon, du fait de l’activité partielle, je n’ai aucun support des équipes Renault…
J’ai pu déterminer que la couche traefik (sur laquelle je n’ai apparemment la main que via les labels dans le docker-compose) serait une version 1.7 et que dans cette version, la configuration de la compression est statique et ne peut être modifiée que par des commandes CLI. En traefik v2, il semble que tout soit beaucoup plus paramétrable en passant par les concepts de routers et middlewares.
Je laisse donc ce sujet en attente d’infos par nos équipes d’experts (pour confirmer le diagnostic) et envisager un scénario d’upgrade vers traefik v2.

Dans l’immédiat, les optimisations sur les métadonnées améliorent grandement les temps de réponse.
Le next step sera peut-être pour dans longtemps…

Merci beaucoup à nouveau pour votre support et votre expertise.

Oui l’idéal reste selon moi que la compression gzip (comme le SSL) ne soit pas géré au niveau de Tomcat mais au niveau des reverse proxies.

Ça aura été quand même l’occasion de faire évoluer nos images Docker vers plus de souplesse sur ce point.

Ok c’est déjà pas mal.

Il faut poursuivre l’optim des données envoyées, GZIP n’est pas forcement l’idéal car rajoute une latence de calcul peu rentable si les données sont déjà compressées (un pdf) ou que les couches réseaux plus basses le font de toute façon.

Ca devient rentable si 50% des données sont les mêmes pour être factorisées = donc qu’on peut optimiser à la source…

Par exemple, pour encore optimiser 50% de la taille des data du “search”, il faudrait “juste” retirer le tableau d’objets json qui rappelle les noms des champs pour chaque ligne, et juste envoyer un tableau de valeurs (string, bool, number, object document…) dans l’ordre des colonnes de l’objet envoyées dans les metadata une seule fois. Les API devront être malines pour s’adapter au type de réponse pour compatibilité ascendante.

A suivre…

NB: Sur Tomcat (et sur nos reverse proxies) la compression gzip n’est effectuée que sur les contenus “texte” (HTML, JS, CSS, JSON, …) d’une taille où ça se justifie (> 2kb) donc PDF et images ne sont pas concernées.

Bonjour David, François,
J’ai mis à niveau l’environnement de production et sur cet environnement, l’ensemble des réponses (GET+POST) sont bien compressées. La compression des réponses POST n’est donc annulée que sur les environnements de dev et de tests. Je n’ai toujours pas de retour de nos équipes d’experts mais il semble qu’ils aient intégré une règle “particulière” sur ces environnements.
Vos optimisations (metadata et compression tomcat) sont donc déployées et parfaitement opérationnelles.
Merci beaucoup pour l’aide et l’expertise apportée.
Bruno

OK super.
L’effet ressenti de la compression est il significatif en prod?
Autrement dit, était-ce le réseau qui posait pb ou surtout le parsing de 1Mb+ de metadonnées ?

Oh que oui, l’amélioration est très significative.
C’était bien lié en premier lieu à la capacité du réseau (comme indiqué en début de post, c’était beaucoup moins sensible en intranet).
L’optimisation des métadonnées a permis de réduire le volume transmis de l’ordre de 20%.
L’activation de la compression a enfoncé le clou en divisant les volumes transmis par 5.

Cool. Reste à comprendre ce qui a été fait sur dev et test pour que les POST soient decompressés…

Bonjour @david, @Francois,
Nous avons la compression à la volée est “retombée en panne” à la rentrée et l’analyse réalisée avec nos experts techniques a démontré que c’était lié à l’activation de headers liés à la mise en oeuvre de Dynatrace (X-Oneagent-Js-Injection: true). Si ce header est présent, la compression est inopérante. Les services liés à ce header sont gérés par d’autres équipes et peuvent être démarrés (ou pas) de manière variable entre les environnements (production/tests/dev) voire même entre plusieurs hosts d’un même noeud (Dockerswarm).
Est-il possible que l’ajout de ce header (et peut-être d’autres choses qui vont avec et dont je ne soupçonne pas l’existence) puisse ne pas être bien supportée par Simplicité ?
Est-il possible de retrouver dans une log du conteneur la trace des requêtes traitées par le tomcat avec les headers des requêtes et des réponses ?

Le header “X-Oneagent-Js-Injection” est inconnu de Simplicité, il n’en tient donc pas compte au niveau applicatif.

Au niveau Tomcat je ne sais pas dire si ça peut avoir un effet, il faut chercher sur le web…

Pour mémoire la compression GZip peut être gérée par Tomcat (sur nos images Docker via le -e GZIP=true) mais aussi par le reverse proxy (comme on le fait sur nos serveur SIM au niveau nginx). Dans tous les cas ce n’est pas applicatif.

Pour regarder les header, vu du navigateur, il faut aller dans l’onglet “network” (ou équivalent) sur la console (F12). Ex:

Pour regarder les headers reçus coté serveur il est possible d’écrire un objet externe ad hoc:

Le code de cet objet externe:

package com.simplicite.extobjects.MyModule;

import com.simplicite.util.AppLog;
import com.simplicite.util.tools.Parameters;

public class MyHTTPTracer extends com.simplicite.util.ExternalObject {
	private static final long serialVersionUID = 1L;

	@Override
	public Object display(Parameters params) {
		try {
			setHTML("<pre class=\"mono\">" + params.toJSONObject().toString(2) + "</pre>");
		} catch (Exception e) {
			setHTML(e.getMessage());
		}
		return javascript("void(0);");
	}
}
1 Like