Как включить HTTP-сжатие gzip для динамического содержимого Windows Azure - PullRequest
57 голосов
/ 05 мая 2010

Я безуспешно пытался включить HTTP-сжатие gzip на моей службе WCF Restful на Windows Azure, которая возвращает JSON только из запросов GET и POST.

Я перепробовал так много вещей, что мне было бы сложно перечислить их все, и теперь я понимаю, что работаю с противоречивой информацией (касающейся старой версии Azure и т. Д.), Поэтому думаю, что лучше начать с чистого листа. !

Я работаю с Visual Studio 2008, используя инструменты февраля 2010 для Visual Studio.

Итак, согласно следующей ссылке ..

.. Сжатие HTTP теперь включено. Я воспользовался советом на следующей странице (только рекомендации по сжатию URL) ..

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

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

.. но я не получаю сжатие. Не помогает, что я не знаю, в чем разница между urlCompression и httpCompression . Я пытался это выяснить, но безрезультатно!

Может ли быть проблемой тот факт, что инструменты для Visual Studio были выпущены до версии Azure, которая поддерживает сжатие? Я где-то читал, что с помощью новейших инструментов вы можете выбрать, какую версию ОС Azure вы хотите использовать при публикации ... но я не знаю, так ли это, и если это так, я не могу найти, где выбирать. Могу ли я использовать версию с предварительным http?

Я также попробовал модуль сжатия http, но безрезультатно.

Есть ли у кого-нибудь актуальные советы о том, как этого добиться? то есть советы, относящиеся к текущей версии ОС Azure.

Ура!

Стивен

Обновление: Я отредактировал приведенный выше код, чтобы исправить тип во фрагменте web.config.

Обновление 2: Тестирование ответов с использованием URL-адреса whatsmyip, показанного в ответе ниже, показывает, что мои ответы JSON от моего service.svc возвращаются без какого-либо сжатия, но статические HTML-страницы ARE возвращается со сжатием gzip. Любые советы о том, как получить ответы JSON для сжатия, будут с благодарностью приняты!

Обновление 3: Попробовал ответ JSON размером более 256 КБ, чтобы выяснить, не связана ли проблема с тем, что ответ JSON меньше этого значения, как указано в комментариях ниже. К сожалению, ответ по-прежнему не сжат.

Ответы [ 6 ]

73 голосов
/ 11 сентября 2011

Ну, это заняло очень много времени ... но я наконец-то решил это, и я хочу опубликовать ответ для всех, кто борется. Решение очень простое, и я убедился, что оно определенно работает !!

Отредактируйте файл ServiceDefinition.csdef, чтобы он содержался в теге WebRole:

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

В вашей веб-роли создайте текстовый файл и сохраните его как «EnableCompression.cmd»

EnableCompression.cmd должен содержать это:

%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

.. и все! Готово! Это включает динамическое сжатие для json, возвращаемого веб-ролью, которая, как мне кажется, я где-то читал, имеет довольно странный тип mime, поэтому убедитесь, что вы точно скопировали код.

13 голосов
/ 15 апреля 2011

Ну, по крайней мере, я не одинок в этом - и это все еще глупая PITA почти год спустя.

Проблема в несоответствии типов MIME. WCF возвращает ответ JSON с Content-Type: application/json; charset=UTF-8. Конфигурация IIS по умолчанию , расположенная примерно посередине этой страницы, не включает ее в качестве сжимаемого типа MIME.

Теперь может быть заманчиво добавить раздел <httpCompression> в ваш web.config и добавить к нему application / json. Но это просто плохой способ тратить добрый час или два - вы можете изменить только элемент <httpCompression> на уровне applicationHost.config.

Так что есть два возможных решения. Во-первых, вы можете изменить свой ответ WCF, чтобы использовать тип MIME, сжимаемый в конфигурации по умолчанию. text/json будет работать, поэтому добавление этого в ваши методы обслуживания даст вам динамическое сжатие: WebOperationContext.Current.OutgoingResponse.ContentType = "text/json";

Кроме того, вы можете изменить файл applicationHost.config, используя appcmd и задачу запуска. Это обсуждается (среди прочего) на этой теме . Обратите внимание, что если вы добавите эту задачу запуска и запустите ее в структуре разработки, она будет работать один раз. Во второй раз это не удастся, потому что вы уже добавили элемент конфигурации. В итоге я создал второй облачный проект с отдельным файлом csdef, чтобы мой devfabric не запускал этот скрипт запуска. Хотя, возможно, есть и другие решения.

Обновление

Мое предложение для отдельных проектов в предыдущем абзаце не очень хорошая идея. Неидемпотентные задачи запуска - очень плохая идея, потому что однажды структура Azure решит перезапустить ваши роли для вас, задача запуска завершится неудачей и перейдет в цикл рециркуляции. Скорее всего, среди ночи. Вместо этого сделайте ваши задачи запуска идемпотентными, как обсуждалось в этой SO-теме .

4 голосов
/ 15 февраля 2012

Чтобы справиться с локальной структурой разработки, имеющей проблемы после первого развертывания, я добавил соответствующие команды в файл CMD для сброса конфигурации. Кроме того, здесь я специально устанавливаю уровень сжатия, поскольку в некоторых (всех?) Случаях он по умолчанию равен нулю.

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
3 голосов
/ 25 ноября 2014

Только что возникла проблема с типом ошибки 183, и я нашел решение. Так что, если кто-то еще испытывает это здесь:

Вот ошибка, которую я получил:

Программа пользователя "F: \ Approot \ bin \ EnableCompression.cmd" завершена с ненулевым кодом завершения 183. Рабочий каталог - F: \ Approot \ bin.

А вот код, который исправил это для меня:

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%

Решение найдено в http://msdn.microsoft.com/en-us/library/azure/hh974418.aspx

3 голосов
/ 21 января 2014

Эта статья от MS рассказывает, как написать скрипт для JSON http://msdn.microsoft.com/en-us/library/windowsazure/hh974418.aspx.

В нем рассматриваются многие из упомянутых проблем, например, возможность обработки корзины Azure и т. д.

0 голосов
/ 06 мая 2010

Да, вы можете выбрать желаемую ОС, но по умолчанию вы получите самую последнюю версию.

Сжатие сложно. Есть много вещей, которые могут пойти не так. Вы случайно проводите это тестирование за прокси-сервером? Я считаю, что IIS по умолчанию не отправляет сжатый контент на прокси. Я нашел удобный инструмент, чтобы проверить, работает ли сжатие, когда я играл с этим: http://www.whatsmyip.org/http_compression/.

Похоже, у вас есть doDynamicCompression = "false" ... это просто опечатка? Вы хотите, чтобы это было включено, если вы собираетесь получить сжатие в JSON, которое вы возвращаете из веб-службы.

...