[FR] Les requêtes HTTP de l'extrême

Preview:

Citation preview

Les requêtes HTTP de l'extrêmeLes requêtes HTTP de l'extrême

Vincent Cassé - @vcasseVincent Cassé - @vcasse

Les requêtes HTTP de l'extrêmeLes requêtes HTTP de l'extrême

Etape 1 :Présenter la problématique

Etape 1 :Présenter la problématique

Problématique de l'épisodeProblématique de l'épisode

● Gérer des fichiers dans le cloud

● Application web

● Utilisation d'un object storagehttps://www.ovh.com/fr/cloud/storage/object-storage.xml

● Gérer des fichiers dans le cloud

● Application web

● Utilisation d'un object storagehttps://www.ovh.com/fr/cloud/storage/object-storage.xml

Architecture de l'applicationArchitecture de l'application

Navigateur web

Serveur applicatif

Object storage

Etape 2 :Étudier chaque problème,

de manière temporelle

Etape 2 :Étudier chaque problème,

de manière temporelle

Télécharger des fichiersTélécharger des fichiers

D'habitudeD'habitude

● Stockage en local temporaire

● Risque 1 : disque pleins

● Risque 2 : timeouts

● Stockage en local temporaire

● Risque 1 : disque pleins

● Risque 2 : timeouts

Timeout ?Timeout ?

Navigateur web

Serveur applicatif

Object storage

Timeout ?Timeout ?

● Connexion HTTP en attente sans traffic

● Passage par des load balancers

● Ressemble à une attaque SYN

● Connexion HTTP en attente sans traffic

● Passage par des load balancers

● Ressemble à une attaque SYN

Le callback de curl est un amiLe callback de curl est un ami

● Exécution à chaque paquet reçu

● Temps curl non décompté

● Permet d'éviter stockage local

● Permet d'envoyer du contenu : pas de timeout

● Exécution à chaque paquet reçu

● Temps curl non décompté

● Permet d'éviter stockage local

● Permet d'envoyer du contenu : pas de timeout

Le callback de curl est un amiLe callback de curl est un ami

curl_setopt($curl, CURLOPT_WRITEFUNCTION, function($a,$b) {echo $b;flush();return strlen($b);

);

curl_setopt($curl, CURLOPT_WRITEFUNCTION, function($a,$b) {echo $b;flush();return strlen($b);

);

Et plusieurs fichiers ?Et plusieurs fichiers ?

Enregistrer le fichier sous...Enregistrer le fichier sous...

// Frontend

Iframe  + formulaire à valider pour charger le fichier sans recharge la page

// Backend

header('Cache­Control: no­cache, no­store, max­age=0, must­revalidate');header("Content­Type: application/jpeg”);header('Content­Length: 1337”);header("Content­Transfer­Encoding: binary");header('Content­Disposition: attachment;filename="picture.jpg"');

// Frontend

Iframe  + formulaire à valider pour charger le fichier sans recharge la page

// Backend

header('Cache­Control: no­cache, no­store, max­age=0, must­revalidate');header("Content­Type: application/jpeg”);header('Content­Length: 1337”);header("Content­Transfer­Encoding: binary");header('Content­Disposition: attachment;filename="picture.jpg"');

Zip obligatoireZip obligatoire

● Un seul fichier par download

● Le format zip permet de faire un seul fichier (même sans compression)

● Stockage local avant de zipper ?

● Un seul fichier par download

● Le format zip permet de faire un seul fichier (même sans compression)

● Stockage local avant de zipper ?

Les streams sont vos amisLes streams sont vos amis

● Stream permet la lecture / écriture d'une ressource

● Stream se comporte comme les fichiers

● Plus d'infos sur les streams http://php.net/manual/en/intro.stream.phphttps://blog.pascal-martin.fr/post/slides-presentation-flux-forum-php-2015.html

● Stream permet la lecture / écriture d'une ressource

● Stream se comporte comme les fichiers

● Plus d'infos sur les streams http://php.net/manual/en/intro.stream.phphttps://blog.pascal-martin.fr/post/slides-presentation-flux-forum-php-2015.html

Les streams sont vos amisLes streams sont vos amis

// Register stream zipstream_wrapper_register("zip", "ZipClassName");

// Use stream zip with curl return$fp = fopen("zip://uniqNameByDownload”, "r+");curl_setopt($curl, CURLOPT_FILE, $fp);fclose( $fp );

// Register stream zipstream_wrapper_register("zip", "ZipClassName");

// Use stream zip with curl return$fp = fopen("zip://uniqNameByDownload”, "r+");curl_setopt($curl, CURLOPT_FILE, $fp);fclose( $fp );

Et les miniatures ?Et les miniatures ?

Imagick ?Imagick ?

● Limité à l'application web

● Prend des ressources CPU

● Comment distribuer le cache ?

● Limité à l'application web

● Prend des ressources CPU

● Comment distribuer le cache ?

Réducteur d'image à la voléeRéducteur d'image à la volée

Navigateur web

Serveur applicatif

Object storage

Miniatures

Houston : on reçoit des erreurs 0Houston : on reçoit des erreurs 0

Des erreurs 0 ?Des erreurs 0 ?

● Pas d'erreur 0 dans les logs

● Sur IE, l'erreur n'appelle même pas le callback d'erreur …

● Mais des 499

● What ?

● Pas d'erreur 0 dans les logs

● Sur IE, l'erreur n'appelle même pas le callback d'erreur …

● Mais des 499

● What ?

Suppression d'un fichierSuppression d'un fichier

● L'erreur arrive sur les suppressions de gros fichiers

● L'action est longue coté Object Storage

● Timeout php ?

● L'erreur arrive sur les suppressions de gros fichiers

● L'action est longue coté Object Storage

● Timeout php ?

Code HTTP 0 ?Code HTTP 0 ?

● Soucis réseau : ça a tranché sur la route

● Timeout du load balancer !

● Solution : faire de l'async ?

● Soucis réseau : ça a tranché sur la route

● Timeout du load balancer !

● Solution : faire de l'async ?

Suppression programméeSuppression programmée

● Object storage permet de programmer une suppression

● Pas d'attente ! C'est juste programmé !

● Et si on programmait dans une seconde ?

● Object storage permet de programmer une suppression

● Pas d'attente ! C'est juste programmé !

● Et si on programmait dans une seconde ?

Heu… y'a encore des erreurs 0 !Heu… y'a encore des erreurs 0 !

Encore des erreurs 0 ?Encore des erreurs 0 ?

● Sur un upload : y'a du traffic -_-

● Seulement sur les gros fichiers

● Sur un upload : y'a du traffic -_-

● Seulement sur les gros fichiers

Firebug ...Firebug ...

● Analyseur de code dans Firefox / Chrome

● Coupe le traffic sur les requêtes > 100 Mo.

● Paf timeout ...

● Analyseur de code dans Firefox / Chrome

● Coupe le traffic sur les requêtes > 100 Mo.

● Paf timeout ...

Et si on parlait d'upload ?Et si on parlait d'upload ?

Comment on upload ?Comment on upload ?

<form enctype="multipart/form­data" action="upload.php” method="POST"><input type="hidden" name="META1" value="file" /><input name="content" type="file" /><br /><input type="submit" value="Upload File" />

</form>

● Recharge la page

● Ne permet pas d'afficher la progression

● AJAX ?

<form enctype="multipart/form­data" action="upload.php” method="POST"><input type="hidden" name="META1" value="file" /><input name="content" type="file" /><br /><input type="submit" value="Upload File" />

</form>

● Recharge la page

● Ne permet pas d'afficher la progression

● AJAX ?

AJAX ?AJAX ?

● Permet de suivre la progression

● Format binairexhr = new XMLHttpRequest();xhr.addEventListener("load", successCallback, false);xhr.addEventListener("error", errorCallback, false);xhr.addEventListener("abort", abortCallback, false);xhr.upload.addEventListener("progress", progressCallback, false);xhr.open('POST', url, true);xhr.send(data);

● Permet de suivre la progression

● Format binairexhr = new XMLHttpRequest();xhr.addEventListener("load", successCallback, false);xhr.addEventListener("error", errorCallback, false);xhr.addEventListener("abort", abortCallback, false);xhr.upload.addEventListener("progress", progressCallback, false);xhr.open('POST', url, true);xhr.send(data);

Et mon formulaire ?Et mon formulaire ?

● L'object storage attend un formulaire

● On crée le formulaire en javascript● http://caniuse.com/#search=formdata

http://caniuse.com/#search=file

formData = new FormData();formData.append('meta1', “file”);formData.append('content', fp);…xhr.send(formData);

● L'object storage attend un formulaire

● On crée le formulaire en javascript● http://caniuse.com/#search=formdata

http://caniuse.com/#search=file

formData = new FormData();formData.append('meta1', “file”);formData.append('content', fp);…xhr.send(formData);

Contraintes des uploadsContraintes des uploads

● Adsl répandu

● Upload de l'adsl : max 128 Ko/s (1Mbps)

● Les uploads durent des heures

● Adsl répandu

● Upload de l'adsl : max 128 Ko/s (1Mbps)

● Les uploads durent des heures

Fiabiliser les uploadsFiabiliser les uploads

Navigateur web

Serveur applicatif Object

storage

Upload

Chef ça a cassé !Chef ça a cassé !

● Same origin policy !

● Aucun appel Ajax sur un autre domaine

● C'était trop beau…

● Same origin policy !

● Aucun appel Ajax sur un autre domaine

● C'était trop beau…

CORSCORS

● Permet de définir les serveurs autorisés

● Configuration sur les serveurs● http://caniuse.com/#search=cors

// Requête de firefoxGET /fileList/ HTTP/1.1Origin: http://mywebapp.ovh

// Réponse du serveur cluster.objectstorage.ovhAccess­Control­Allow­Origin: http://mywebapp.ovh

● Permet de définir les serveurs autorisés

● Configuration sur les serveurs● http://caniuse.com/#search=cors

// Requête de firefoxGET /fileList/ HTTP/1.1Origin: http://mywebapp.ovh

// Réponse du serveur cluster.objectstorage.ovhAccess­Control­Allow­Origin: http://mywebapp.ovh

Au fait, tu dois gérer IE8 !Au fait, tu dois gérer IE8 !

● Dernier IE de Windows XP...

● Gére pas formData (IE10)

● Gére pas CORS (IE10) ...

● Dernier IE de Windows XP...

● Gére pas formData (IE10)

● Gére pas CORS (IE10) ...

Au fait, tu dois gérer IE8 !Au fait, tu dois gérer IE8 !

● On crée une iframe sur cluster.objectstorage.ovh

● Contenant un formulaire

● On simule le clic sur le bouton

● On crée une iframe sur cluster.objectstorage.ovh

● Contenant un formulaire

● On simule le clic sur le bouton

Les autres blagues de IE < 10Les autres blagues de IE < 10

● Upload de .jpeg ?

● Sélection multiple ?

● Windows phone 8 ?

● Upload de .jpeg ?

● Sélection multiple ?

● Windows phone 8 ?

On peut uploader un dossier ?On peut uploader un dossier ?

● Chrome le peut. C'est deprecated

● Firefox bute sur l'ergonomie

● WebAPI ?

● Chrome le peut. C'est deprecated

● Firefox bute sur l'ergonomie

● WebAPI ?

Etape 3 :La réalisation et ses aléas

Etape 3 :La réalisation et ses aléas

Les bugs poilusLes bugs poilus

Remontées des utilisateursRemontées des utilisateurs

● Mon download a crashé au bout de 27h

● Mon zip est corrompu

● Mon download a crashé au bout de 27h

● Mon zip est corrompu

Ce qu'en pense les sysadminsCe qu'en pense les sysadmins

● Non pas de reboot de serveur

● Aucune alerte du monito

● Au fait, pendant que tu es là, tu as vu mon mail sur la conso de RAM ?

● Non pas de reboot de serveur

● Aucune alerte du monito

● Au fait, pendant que tu es là, tu as vu mon mail sur la conso de RAM ?

Conso de RAM ?Conso de RAM ?

● Pas possible : je stream

● Je reproduis pas en dev : c'est le serveur qui est mal configuré

● Monito des process PHP : non c'est pas eux qui mangent la RAM !

● Pas possible : je stream

● Je reproduis pas en dev : c'est le serveur qui est mal configuré

● Monito des process PHP : non c'est pas eux qui mangent la RAM !

Nginx ?Nginx ?

location /webapp $ {proxy_pass       http://localhost:81;proxy_set_header Host      $host;

}

server {listen 81;location ~ \.php$ {

try_files $uri =404;fastcgi_pass unix:/var/run/php5­fpm.sock;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

}}

location /webapp $ {proxy_pass       http://localhost:81;proxy_set_header Host      $host;

}

server {listen 81;location ~ \.php$ {

try_files $uri =404;fastcgi_pass unix:/var/run/php5­fpm.sock;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

}}

Nginx ?Nginx ?

Syntax:  proxy_buffering on | off;Default:  proxy_buffering on;Context:  http, server, location

http://nginx.org/en/docs/http/ngx_http_proxy_module.html

Syntax:  proxy_buffering on | off;Default:  proxy_buffering on;Context:  http, server, location

http://nginx.org/en/docs/http/ngx_http_proxy_module.html

proxy_bufferingproxy_buffering

Listen 80Internet

Object

Storage

Listen 81

PHP-fpm

ProxyF

astcgi

Tout est bien qui finit bienTout est bien qui finit bien

En fait, le dev web c'estEn fait, le dev web c'est

● Multi – navigateur

● Ça doit gérer le réseau

● C'est comme les oignons, ça a des couches

● Multi – navigateur

● Ça doit gérer le réseau

● C'est comme les oignons, ça a des couches

Merci !

Des questions ?

Merci !

Des questions ?

Les requêtes HTTP de l'extrêmeLes requêtes HTTP de l'extrême

Vincent Cassé - @vcasseVincent Cassé - @vcasse

Recommended