【问题标题】:How to enable gzip HTTP compression on Windows Azure dynamic content如何在 Windows Azure 动态内容上启用 gzip HTTP 压缩
【发布时间】:2011-02-16 01:03:59
【问题描述】:

我一直在尝试在我的 Windows Azure 托管的 WCF Restful 服务上启用 gzip HTTP 压缩但未成功,该服务仅从 GET 和 POST 请求返回 JSON。

我已经尝试了很多事情,以至于我很难将它们全部列出来,现在我意识到我一直在处理相互矛盾的信息(关于旧版本的 azure 等),所以认为最好从头开始!

我正在使用 Visual Studio 2008,使用 Visual Studio 的 2010 年 2 月工具。

所以,根据下面link..

.. HTTP 压缩现已启用。我使用了下一页的建议(仅限 URL 压缩建议)..

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

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

.. 但我没有压缩。我不知道 urlCompressionhttpCompression 之间有什么区别,这无济于事。我试图找出答案,但无济于事!

Visual Studio 的工具是在支持压缩的 Azure 版本之前发布的,这可能是个问题吗?我在某处读到,使用最新的工具,您可以在发布时选择要使用的 Azure OS 版本……但我不知道这是不是真的,如果是,我找不到在哪里选择。我可以使用支持 http 的版本吗?

我也尝试过bloery http压缩模块,但没有结果。

是否有人对如何实现这一目标有任何最新建议?即与当前版本的 Azure 操作系统相关的建议。

干杯!

史蒂文

更新:我编辑了上面的代码来修复 web.config sn-p 中的一个类型。

更新 2: 使用下面答案中显示的 whatsmyip URL 测试响应表明,我的 service.svc 的 JSON 响应在没有任何压缩的情况下返回,而是静态 HTML 页面 ARE 使用 gzip 压缩返回。我们将不胜感激地收到任何有关如何获取 JSON 响应以进行压缩的建议!

更新 3: 尝试了大于 256KB 的 JSON 响应,以查看问题是否是由于 JSON 响应小于此值,如下面的 cmets 所述。不幸的是,响应仍未压缩。

【问题讨论】:

  • 共享主机应该默认为所有 json web 服务启用 gzip。当然,它会给服务器带来更多的 CPU 负载,但是通过网络传输的较小数据包的好处远远超过了成本 - IMO。并非我们所有人的家中都有光纤。

标签: json gzip azure http-compression


【解决方案1】:

刚刚遇到关于错误类型 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找到解决方案

【讨论】:

    【解决方案2】:

    这篇来自 MS 的文章是他们如何为 JSON http://msdn.microsoft.com/en-us/library/windowsazure/hh974418.aspx 编写脚本。

    它处理提到的许多问题,例如能够处理 Azure 回收等

    【讨论】:

      【解决方案3】:

      好吧,至少我并不孤单 - 差不多一年后它仍然是一个愚蠢的 PITA。

      问题是 MIME 类型不匹配。 WCF 返回带有 Content-Type: application/json; charset=UTF-8 的 JSON 响应。 default IIS configuration,大约在该页面的一半,不包括作为可压缩 MIME 类型。

      现在,将&lt;httpCompression&gt; 部分添加到您的 web.config 中并添加 application/json 可能会很诱人。但这只是浪费一两个小时的好方法——您只能在 applicationHost.config 级别更改&lt;httpCompression&gt; 元素。

      所以有两种可能的解决方案。首先,您可以更改 WCF 响应以使用在默认配置中可压缩的 MIME 类型。 text/json 将起作用,因此将其添加到您的服务方法中将为您提供动态压缩:WebOperationContext.Current.OutgoingResponse.ContentType = "text/json";

      或者,您可以使用 appcmd 和启动任务更改 applicationHost.config 文件。这在this thread 上进行了讨论(除其他事项外)。请注意,如果您添加该启动任务并在开发结构中运行它,它将运行一次。第二次它会失败,因为您已经添加了配置元素。我最终使用单独的 csdef 文件创建了第二个云项目,这样我的 devfabric 就不会运行该启动脚本。不过,可能还有其他解决方案。

      更新

      我在上一段中对单独项目的建议并不是一个好主意。非幂等启动任务是一个非常糟糕的主意,因为有一天 Azure 结构会决定为您重新启动角色,启动任务会失败,并且会进入循环循环。最有可能在半夜。相反,请按照this SO thread 中的讨论使您的启动任务具有幂等性。

      【讨论】:

      • 需要注意的是,必须在 applicationHost.config 级别添加 。我敢打赌,很多人——包括我自己——都浪费时间试图通过修改 web.config 来让它工作。
      【解决方案4】:

      为了处理首次部署后出现问题的本地开发结构,我在 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
      

      【讨论】:

        【解决方案5】:

        好吧,花了 非常 很长时间......但我终于解决了这个问题,我想为其他正在苦苦挣扎的人发布答案。解决方案非常简单,我已经验证它确实有效!

        编辑您的 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
        

        .. 就是这样!完毕!这为 web-role 返回的 json 启用了动态压缩,我想我在某处读到的它有一个相当奇怪的 mime 类型,所以请确保您准确地复制代码。

        【讨论】:

        • 有没有办法只在真正的天蓝色上运行时执行这些语句?
        • 没关系在这里找到答案(需要 SDK 1.5)blog.smarx.com/posts/…
        • 这在当前的 SDK 中是否仍然相关?我想我已经正确配置了,但是在本地运行时出现“无法开始调试”错误,无论 cmd 文件的内容是什么。
        • 我已经按照 Brian 在他的更新中建议的那样实现了 stackoverflow.com/questions/11810724/…,以便可以回收实例。
        • 您将启动任务taskType 设置为taskType="simple",脚本是否必须在simple 模式下运行,或者也可以使用background? (Clarification on the difference can be found here)
        【解决方案6】:

        是的,您可以选择所需的操作系统,但默认情况下,您将获得最新的。

        压缩很棘手。有很多事情可能会出错。您是否偶然在代理服务器后面进行此测试?我相信默认情况下 IIS 不会将压缩内容发送到代理。我找到了一个方便的工具来测试我在玩这个时压缩是否有效:http://www.whatsmyip.org/http_compression/

        看起来你有 doDynamicCompression="false"... 这只是一个错字吗?如果您要对从 Web 服务返回的 JSON 进行压缩,您希望启用它。

        【讨论】:

        • 嘿!感谢您的快速回复!那是一个错字,该行应为: 我使用了您建议的 whatsmyip URL 进行一些测试。我的 JSON 响应(来自我的 service.svc)在没有任何压缩的情况下返回,但静态 HTML 页面正在被压缩。你对我可以从这里去哪里有什么建议吗?再次感谢
        • 尝试生成非常大的 JSON。根据msdn.microsoft.com/en-us/library/ms690689(VS.90).aspx,默认的 minSize 设置为 256 KB。
        • 我创建了一个大小为 280KB 的假响应,并在 whatsmyip 上对其进行了测试……不幸的是,它仍未压缩。
        • 我很确定您可以通过制作自定义 IHTTPModule (west-wind.com/weblog/posts/2007/Jan/23/…) 并将其添加到 Azure (blogs.msdn.com/b/tom/archive/2011/02/18/…) 来启用 GZIP 压缩
        猜你喜欢
        • 2013-06-15
        • 1970-01-01
        • 2015-12-01
        • 1970-01-01
        • 2018-08-20
        • 2020-08-24
        • 1970-01-01
        • 2017-06-17
        • 2021-10-03
        相关资源
        最近更新 更多