web-dev-qa-db-fra.com

Comment activer la compression HTTP gzip sur le contenu dynamique Windows Azure

J'ai essayé sans succès d'activer la compression HTTP gzip sur mon service WCF Restful hébergé Windows Azure qui renvoie JSON uniquement à partir de GET et de demandes POST.

J'ai essayé tellement de choses que j'aurais du mal à les énumérer toutes, et je me rends compte maintenant que je travaille avec des informations contradictoires (concernant l'ancienne version d'Azure, etc.) alors pensez qu'il vaut mieux commencer avec une table rase!

Je travaille avec Visual Studio 2008, en utilisant les outils de février 2010 pour Visual Studio.

Donc, selon ce qui suit lien ..

.. La compression HTTP est désormais activée. J'ai utilisé les conseils de la page suivante (les conseils de compression d'URL uniquement).

http://blog.smarx.com/posts/iis-compression-in-windows-Azure

<urlCompression doStaticCompression="true" 
         doDynamicCompression="true"
         dynamicCompressionBeforeCache="true" 
/>

.. mais je n'obtiens aucune compression. Cela n'aide pas que je ne sache pas quelle est la différence entre urlCompression et httpCompression . J'ai essayé de le découvrir mais en vain!

Le fait que les outils pour Visual Studio aient été publiés avant la version d'Azure qui prend en charge la compression pourrait-il être un problème? J'ai lu quelque part que, avec les derniers outils, vous pouvez choisir la version d'Azure OS que vous souhaitez utiliser lorsque vous publiez ... mais je ne sais pas si c'est vrai, et si c'est le cas, je ne trouve pas où choisir. Puis-je utiliser une version compatible pré-http?

J'ai également essayé le module de compression http de Blowery, mais aucun résultat.

Quelqu'un at-il des conseils à jour sur la façon d'y parvenir? c'est-à-dire des conseils concernant la version actuelle du système d'exploitation Azure.

À votre santé!

Steven

Mettre à jour: J'ai modifié le code ci-dessus pour corriger un type dans l'extrait web.config.

Mise à jour 2: Tester les réponses à l'aide de l'URL Whatsmyip indiquée dans la réponse ci-dessous montre que mes réponses JSON de mon service.svc sont retournées sans aucune compression, mais des pages HTML statiques SONT étant retourné avec la compression gzip. Tous les conseils sur la façon d'obtenir les réponses JSON à compresser seront reçus avec gratitude!

Mise à jour 3: J'ai essayé une réponse JSON supérieure à 256 Ko pour voir si le problème était dû à une réponse JSON plus petite que celle mentionnée dans les commentaires ci-dessous. Malheureusement, la réponse n'est toujours pas compressée.

58
Steven Elliott

Eh bien, cela a pris très longtemps ... mais j'ai finalement résolu cela, et je veux publier la réponse pour toute autre personne qui se débat. La solution est très simple et j'ai vérifié que ça marche vraiment !!

Modifiez votre fichier ServiceDefinition.csdef pour le contenir dans la balise WebRole:

    <Startup>
      <Task commandLine="EnableCompression.cmd" executionContext="elevated" taskType="simple"></Task>
    </Startup>

Dans votre rôle Web, créez un fichier texte et enregistrez-le sous "EnableCompression.cmd"

EnableCompression.cmd devrait contenir ceci:

%windir%\system32\inetsrv\appcmd set config /section:urlCompression /doDynamicCompression:True /commit:apphost
%windir%\system32\inetsrv\appcmd set config  -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json; charset=utf-8',enabled='True']" /commit:apphost

.. et c'est tout! Terminé! Cela permet une compression dynamique pour le json retourné par le rôle web, que je pense avoir lu quelque part a un type mime assez étrange, alors assurez-vous de copier le code exactement.

73
Steven Elliott

Eh bien, au moins, je ne suis pas seul sur celui-ci - et c'est toujours un stupide PITA presque un an plus tard.

Le problème est une incompatibilité de type MIME. WCF renvoie une réponse JSON avec Content-Type: application/json; charset=UTF-8. par défaut IIS , à mi-chemin de cette page, ne l'inclut pas comme type MIME compressible.

Maintenant, il pourrait être tentant d'ajouter un <httpCompression> section à votre web.config, et ajoutez application/json à cela. Mais c'est juste une mauvaise façon de perdre une bonne heure ou deux - vous ne pouvez que changer le <httpCompression> élément au niveau applicationHost.config.

Il y a donc deux solutions possibles. Tout d'abord, vous pouvez modifier votre réponse WCF pour utiliser un type MIME compressible dans la configuration par défaut. text/json fonctionnera donc l'ajout de ceci à vos méthodes de service vous donnera une compression dynamique: WebOperationContext.Current.OutgoingResponse.ContentType = "text/json";

Vous pouvez également modifier le fichier applicationHost.config à l'aide de appcmd et d'une tâche de démarrage. Ceci est discuté (entre autres) sur ce fil . Notez que si vous ajoutez cette tâche de démarrage et l'exécutez dans la structure de développement, cela fonctionnera une fois. La deuxième fois, il échouera car vous avez déjà ajouté l'élément de configuration. J'ai fini par créer un deuxième projet cloud avec un fichier csdef distinct, afin que mon devfabric ne puisse pas exécuter ce script de démarrage. Il existe cependant probablement d'autres solutions.

Mettre à jour

Ma suggestion de projets séparés dans le paragraphe précédent n'est pas vraiment une bonne idée. Les tâches de démarrage non idempotentes sont une très mauvaise idée, car un jour, la structure Azure décidera de redémarrer vos rôles pour vous, la tâche de démarrage échouera et elle entrera dans une boucle de recyclage. Très probablement au milieu de la nuit. Au lieu de cela, rendez vos tâches de démarrage idempotentes comme indiqué sur this SO thread .

13
Brian Reischl

Pour gérer les problèmes de structure de développement local après le premier déploiement, j'ai ajouté les commandes appropriées au fichier CMD pour réinitialiser la configuration. De plus, je règle le niveau de compression ici spécifiquement, car il semble être réglé par défaut à zéro dans certains (tous?) Cas.

REM Remove old settings - keeps local deploys working (since you get errors otherwise)
%windir%\system32\inetsrv\appcmd reset config -section:urlCompression
%windir%\system32\inetsrv\appcmd reset config -section:system.webServer/httpCompression 

REM urlCompression - is this needed?
%windir%\system32\inetsrv\appcmd set config -section:urlCompression /doDynamicCompression:True /commit:apphost
REM Enable json mime type
%windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json; charset=utf-8',enabled='True']" /commit:apphost

REM IIS Defaults
%windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='text/*',enabled='True']" /commit:apphost
%windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='message/*',enabled='True']" /commit:apphost
%windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/x-javascript',enabled='True']" /commit:apphost
%windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='*/*',enabled='False']" /commit:apphost
%windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"staticTypes.[mimeType='text/*',enabled='True']" /commit:apphost
%windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"staticTypes.[mimeType='message/*',enabled='True']" /commit:apphost
%windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"staticTypes.[mimeType='application/javascript',enabled='True']" /commit:apphost
%windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"staticTypes.[mimeType='*/*',enabled='False']" /commit:apphost

REM Set dynamic compression level to appropriate level.  Note gzip will already be present because of reset above, but compression level will be zero after reset.
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"[name='deflate',doStaticCompression='True',doDynamicCompression='True',dynamicCompressionLevel='7',dll='%%Windir%%\system32\inetsrv\gzip.dll']" /commit:apphost
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression -[name='gzip'].dynamicCompressionLevel:7 /commit:apphost
4
scolestock

Cet article de MS explique comment créer un script pour JSON http://msdn.Microsoft.com/en-us/library/windowsazure/hh974418.aspx .

Il traite de nombreux problèmes mentionnés, par exemple être capable de gérer le recyclage Azure, etc.

3
GraemeMiller

Je viens de rencontrer un problème avec le type d'erreur 183 et j'ai trouvé une solution. Donc, si quelqu'un d'autre vit cela, voici:

Voici l'erreur que j'ai eue:

Le programme utilisateur "F:\approot\bin\EnableCompression.cmd" est sorti avec le code de sortie non nul 183. Le répertoire de travail est F:\approot\bin.

Et voici le code qui l'a corrigé pour moi:

REM   *** Add a compression section to the Web.config file. ***
%windir%\system32\inetsrv\appcmd set config /section:urlCompression /doDynamicCompression:True /commit:apphost >> "%TEMP%\StartupLog.txt" 2>&1

REM   ERRORLEVEL 183 occurs when trying to add a section that already exists. This error is expected if this
REM   batch file were executed twice. This can occur and must be accounted for in a Windows Azure startup
REM   task. To handle this situation, set the ERRORLEVEL to zero by using the Verify command. The Verify
REM   command will safely set the ERRORLEVEL to zero.
IF %ERRORLEVEL% EQU 183 DO VERIFY > NUL

REM   If the ERRORLEVEL is not zero at this point, some other error occurred.
IF %ERRORLEVEL% NEQ 0 (
   ECHO Error adding a compression section to the Web.config file. >> "%TEMP%\StartupLog.txt" 2>&1
   GOTO ErrorExit
)

REM   *** Add compression for json. ***
%windir%\system32\inetsrv\appcmd set config  -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json; charset=utf-8',enabled='True']" /commit:apphost >> "%TEMP%\StartupLog.txt" 2>&1
IF %ERRORLEVEL% EQU 183 VERIFY > NUL
IF %ERRORLEVEL% NEQ 0 (
   ECHO Error adding the JSON compression type to the Web.config file. >> "%TEMP%\StartupLog.txt" 2>&1
   GOTO ErrorExit
)

REM   *** Exit batch file. ***
EXIT /b 0

REM   *** Log error and exit ***
:ErrorExit
REM   Report the date, time, and ERRORLEVEL of the error.
DATE /T >> "%TEMP%\StartupLog.txt" 2>&1
TIME /T >> "%TEMP%\StartupLog.txt" 2>&1
ECHO An error occurred during startup. ERRORLEVEL = %ERRORLEVEL% >> "%TEMP%\StartupLog.txt" 2>&1
EXIT %ERRORLEVEL%

Solution trouvée sur http://msdn.Microsoft.com/en-us/library/Azure/hh974418.aspx

3
Martin

Oui, vous pouvez choisir le système d'exploitation que vous souhaitez, mais par défaut, vous obtiendrez la dernière version.

La compression est délicate. Il y a beaucoup de choses qui peuvent mal tourner. Êtes-vous par hasard en train de faire ce test derrière un serveur proxy? Je crois que IIS par défaut n'envoie pas de contenu compressé aux mandataires. J'ai trouvé un outil pratique pour tester si la compression fonctionne lorsque je jouais avec ceci: http: // www .whatsmyip.org/http_compression / .

Il semble que vous ayez doDynamicCompression = "false" ... est-ce juste une faute de frappe? Vous souhaitez que cela soit activé si vous souhaitez obtenir une compression sur JSON que vous revenez d'un service Web.

0
smarx