Как включить сжатие gzip HTTP в динамическом контенте Windows Azure

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

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

Я работаю с 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 OS вы хотите использовать при публикации... но я не знаю, правда ли это, и если да, то я не могу найти, где выбирать. Могу ли я использовать версию с поддержкой до HTTP?

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

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

Ура!

Стивен

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

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

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

Ответ 1

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

Измените файл 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, поэтому обязательно скопируйте код.

Ответ 2

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

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

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

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

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

Update

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

Ответ 3

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

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

Эта статья от MS - это их способ script для JSON http://msdn.microsoft.com/en-us/library/windowsazure/hh974418.aspx.

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

Ответ 5

Просто возникла проблема с этим вопросом об ошибке типа 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

Ответ 6

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

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

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