Cómo habilitar la compresión HTTP gzip en contenido dinámico de Windows Azure


He estado intentando sin éxito habilitar la compresión HTTP gzip en mi servicio Restful WCF alojado en Windows Azure que devuelve JSON solo desde solicitudes GET y POST.

He intentado tantas cosas que me sería difícil enumerarlas todas, y ahora me doy cuenta de que he estado trabajando con información conflictiva (con respecto a la versión antigua de azure, etc.), ¡así que creo que es mejor comenzar de cero!

Estoy trabajando con Visual Studio 2008, utilizando las herramientas de febrero de 2010 para Visual Studio.

Por lo tanto, de acuerdo con el siguiente enlace..

.. La compresión HTTP ha sido habilitada. He utilizado el consejo en la página siguiente (el consejo de compresión de URL solamente)..

Http://blog.smarx.com/posts/iis-compression-in-windows-azure

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

.. pero no tengo compresión. No ayuda que no sé cuál es la diferencia entre urlCompression y httpCompression. He tratado de averiguarlo pero no ¡avail!

¿Podría ser un problema el hecho de que las herramientas de Visual Studio fueran lanzadas antes de la versión de Azure que soporta compresión? He leído en alguna parte que, con las últimas herramientas, puede elegir qué versión del sistema operativo Azure desea usar cuando publique ... pero no se si eso es verdad, y si lo es, no puedo encontrar donde elegir. ¿Podría estar usando una versión pre-http habilitada?

También he probado blowery módulo de compresión http, pero no hay resultados.

Hace cualquier uno tiene algún consejo actualizado sobre cómo lograr esto? es decir, consejos relacionados con la versión actual del sistema operativo Azure.

Salud!

Steven

Actualización: Edité el código anterior para corregir un tipo en la web.fragmento de configuración.

Actualización 2: Probar las respuestas usando la URL de whatsmyip que se muestra en la respuesta a continuación muestra que mis respuestas JSON de mi servicio.los svc se devuelven sin compresión, pero las páginas HTML estáticas SON se devuelve con compresión gzip. Cualquier consejo sobre cómo obtener las respuestas JSON para comprimir será recibido con gratitud!

Actualización 3: Probó una respuesta JSON mayor que 256KB para ver si el problema se debía a que la respuesta JSON era menor que esta, como se menciona en los comentarios a continuación. Desafortunadamente, la respuesta aún no está comprimida.

Author: WitVault, 2010-05-05

6 answers

Bueno, tomó un muy mucho tiempo ... pero finalmente he resuelto esto, y quiero publicar la respuesta para cualquier otra persona que esté luchando. La solución es muy simple y he verificado que definitivamente funciona!!

Edite su definición de servicio.archivo csdef para contener esto en la etiqueta WebRole:

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

En su rol web, cree un archivo de texto y guárdelo como "EnableCompression.cmd "

EnableCompression.cmd debe contener esto:

%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

.. y eso es todo! Hecho! Esto habilita la compresión dinámica para el json devuelto por el rol web, que creo que leí en algún lugar tiene un tipo mime bastante extraño, así que asegúrese de copiar el código exactamente.

 73
Author: Steven Elliott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-11 00:56:03

Bueno, al menos no estoy solo en esto, y sigue siendo una estúpida PITA casi un año después.

El problema es un desajuste de tipo MIME. WCF devuelve la respuesta JSON con Content-Type: application/json; charset=UTF-8. La configuración predeterminada de IIS , a mitad de camino de esa página, no incluye eso como un tipo MIME compresible.

Ahora, podría ser tentador agregar una sección <httpCompression> a su web.config, y agregue application / json a eso. Pero eso es solo una mala manera de perder una buena hora o dos - sólo se puede cambiar el elemento <httpCompression> en applicationHost.config nivel.

Así que hay dos soluciones posibles. Primero, puede cambiar su respuesta WCF para usar un tipo MIME que sea compresible en la configuración predeterminada. text/json funcionará, por lo que agregar esto a sus métodos de servicio le dará compresión dinámica: WebOperationContext.Current.OutgoingResponse.ContentType = "text/json";

Alternativamente, puede cambiar el applicationHost.archivo de configuración usando appcmd y una tarea de inicio. Esto se discute (entre otras cosas) en este hilo. Tenga en cuenta que si agrega esa tarea de inicio y la ejecuta en la estructura de desarrollo, funcionará una vez. La segunda vez fallará porque ya ha añadido el elemento de configuración. Terminé creando un segundo proyecto en la nube con un archivo csdef separado, para que mi devfabric no ejecutara ese script de inicio. Sin embargo, probablemente haya otras soluciones.

Actualización

Mi sugerencia para proyectos separados en el párrafo anterior no es realmente una buena idea. Las tareas de inicio no idempotentes son una muy mala idea, porque algún día el Azure fabric decidirá reiniciar sus roles por usted, la tarea de inicio fallará y entrará en un ciclo de reciclaje. Probablemente en mitad de la noche. En su lugar, haga que sus tareas de inicio sean idempotentes como se discutió en esto SO thread.

 13
Author: Brian Reischl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:06

Para hacer frente a los problemas de la estructura de desarrollo local después de la primera implementación, agregué los comandos apropiados al archivo CMD para restablecer la configuración. Además, estoy configurando el nivel de compresión aquí específicamente, ya que parece predeterminado a cero en algunos(todos?) caso.

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
Author: scolestock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-09 19:44:13

Este artículo de MS es su cómo escribir un script para JSON http://msdn.microsoft.com/en-us/library/windowsazure/hh974418.aspx .

Se ocupa de muchos de los problemas mencionados, por ejemplo, ser capaz de manejar Azure recycle, etc

 3
Author: GraemeMiller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-21 17:10:39

Acabo de tener un problema con esto con respecto al tipo de error 183, y encontré una solución. Así que si alguien más está experimentando esto aquí va:

Aquí está el error que tengo:

Programa de usuario "F:\approot\bin\EnableCompression.cmd " salió con código de salida distinto de cero 183. Directorio de trabajo es F:\approot\bin.

Y aquí está el código que lo arregló para mí:

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%

Solución encontrada en http://msdn.microsoft.com/en-us/library/azure/hh974418.aspx

 3
Author: Blizwire,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-25 03:15:11

Sí, puede elegir el sistema operativo que desee, pero de forma predeterminada, obtendrá la última.

La compresión es complicada. Hay muchas cosas que pueden salir mal. ¿Por casualidad está haciendo esta prueba detrás de un servidor proxy? Creo que IIS por defecto no envía contenido comprimido a proxies. Encontré una herramienta útil para probar si la compresión funciona cuando estaba jugando con esto: http://www.whatsmyip.org/http_compression/.

Parece que tienes doDynamicCompression = "false"... ¿es sólo un error tipográfico? Quieres que esté encendido si vas a obtener compresión en JSON que regreses de un servicio web.

 0
Author: smarx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-05 20:31:27