Recuperar la configuración de IIS con Microsoft.Web.Administration

En el post de ayer estuve hablando sobre la configuración de la sección Recycling en Windows Azure Web sites, gracias al apartado monitoring que el equipo del servicio ha puesto a nuestra disposición. A raíz de ello, Sergio León preguntaba si sabía cúando se reciclaba el application pool en Windows Azure Web sites, por lo que empecé a trastear :)

Como en Windows Azure Web Sites no tenemos acceso a la máquina virtual que sirve nuestro sitio, podemos optar por el plan B: Utilizar Microsoft.Web.Administration para conseguir la información que necesitamos. Existe documentación oficial al respecto, pero en este caso vamos un poco a ciegas en cuanto a qué nombre podría tener el sitio, los application pools, etcétera.

Para conseguir la información que necesito he implementado lo siguiente:

using System.Web.Mvc;
using Microsoft.Web.Administration;

namespace AutoHealingWAWebSites.Controllers
{
    public class TestController : Controller
    {
        //
        // GET: /Home/
        public ActionResult Index()
        {
            var serverManager = new ServerManager();

            ViewBag.Sites = serverManager.Sites;
            return View(serverManager.ApplicationPools);
        }

    }
}

En el controlador, estoy haciendo uso del objeto ServerManager de Microsoft.Web.Administration para recuperar todos los sitios que están configurados. Por otro lado, utilizaré como modelo de mi vista la propiedad ApplicationPools, lo cual me devuelve un ApplicationPoolCollection con todos los application pools disponibles.

En el lado de la vista, lo único que hago es acceder a las propiedades que me interesan dentro de la configuración:

@using Microsoft.Web.Administration
@model ApplicationPoolCollection
@{
    ViewBag.Title = "Index";
}

<h2>IIS Configuration</h2>
<ul>
    @foreach (Site site in ViewBag.Sites)
    {
        <li>
            <strong>@site.Name application pool</strong>: @site.ApplicationDefaults.ApplicationPoolName
        </li>
    }
</ul>
<h2>Application Pools Recycling configurations</h2>
<ul>
    @foreach (ApplicationPool appPool in Model)
    {
        <li>@appPool.Name Attributes
            <ul>
                <li><strong>LogEventOnRecycle</strong>: @appPool.Recycling.LogEventOnRecycle</li>
                <li><strong>Periodic Restart Time</strong>: @appPool.Recycling.PeriodicRestart.Time.Days days @appPool.Recycling.PeriodicRestart.Time.Hours hours @appPool.Recycling.PeriodicRestart.Time.Minutes minutes @appPool.Recycling.PeriodicRestart.Time.Seconds seconds</li>
                <li><strong>Periodic Restart Request</strong>: @appPool.Recycling.PeriodicRestart.Requests</li>
                <li><strong>Periodic Restart PrivateMemory</strong>: @appPool.Recycling.PeriodicRestart.PrivateMemory</li>
                <li><strong>Periodic Restart Schedules</strong>: @appPool.Recycling.PeriodicRestart.Schedule.Count</li>
                <li><strong>Periodic Restart Memory:</strong>: @appPool.Recycling.PeriodicRestart.Memory</li>
            </ul>
        </li>    
    }
</ul>

Como se puede ver en el código anterior, listo todos los sitios dentro del servidor web de Windows Azure Web sites y el application pool. Como quiero conocer la configuración de todos los application pools existentes, recorro las propiedades relativas a Recycling para toda la colección.

IIS Configuration Windows Azure Web sites

Como podemos ver, el único parámetro configurado es cada cuánto tiempo se reinicia el pool: 1 days 5 hours 0 minutes 0 seconds por defecto en todos ellos.

En este post he utilizado esta librería para descubrir una configuración concreta en este hosting en Windows Azure, pero podemos hacer uso de la misma para cualquier entorno donde no tengamos acceso al servidor IIS web para comprobarlo.

Espero que sea de utilidad.

¡Saludos!

Habilitar la compresión dinámica (GZIP) para JSON en IIS/IIS Express

Una buena práctica cuando configuramos un servidor web es habilitar la compresión para las peticiones HTTP. En este post voy a hablar sobre cómo podemos comprimir las peticiones de tipo JSON a través de GZIP.

Configuración

Lo único que tenemos que hacer es incluir dentro del apartado httpCompression del archivo de configuración del servidor web el apartado dynamicTypes, en el caso de que no existiera, e incluir los mime types de las peticiones que queremos comprimir. Esta operación se puede realizar de varias maneras:

A través de consola con appcmd:

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

Manualmente, modificando el archivo de configuración (applicationHost.config) del IIS de Windows (%windir%\System32\inetsrv\config) o IIS Express (%userprofile%\my documents\iisexpress\config):

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
            <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
            <staticTypes>
                <add mimeType="text/*" enabled="true" />
                <add mimeType="message/*" enabled="true" />
                <add mimeType="application/x-javascript" enabled="true" />
                <add mimeType="application/atom+xml" enabled="true" />
                <add mimeType="application/xaml+xml" enabled="true" />
                <add mimeType="*/*" enabled="false" />
            </staticTypes>
            <dynamicTypes>
                <add mimeType="application/json; charset=utf-8" enabled="true" />
                <add mimeType="application/json" enabled="true" />
            </dynamicTypes>
        </httpCompression>

O bien través de la interfaz de administración de IIS, donde sería necesario activar el módulo Dynamic Content Compression. En este punto serían necesarios más pasos y creo que es más tedioso.

Resultados

Para que veamos claro cuál es el beneficio de la configuración anterior, en la siguiente imagen se muestra una petición donde el contenido no ha sido comprimido:

JSON sin comprimir

Esto significa que la respuesta de esa petición tiene un tamaño de 2.2 MB, lo cual es una penalización demasiado importante para nuestro sitio. Una vez aplicados los cambios y reiniciado el pool del IIS, podemos ver que se ha mejorado considerablemente el tamaño de las peticiones:

JSON comprimido

Si nos fijamos bien en la imagen anterior, en el apartado Size tenemos dos valores: el primero de ellos nos indica cuál es tamaño que se ha descargado del servidor remoto y el segundo cuál es el peso real del recurso. Otro dato importante, con el fin de detectar que nuestras peticiones se están comprimiendo, es el valor de la columna Content-Encoding (esta columna no está visible por defecto en Chrome), donde en la segunda imagen podemos comprobar que está utilizando gzip.

Espero que sea de utilidad.

¡Saludos!

Herramienta appcmd para configurar nuestro IIS de las máquinas de Windows Azure

Desde que tenemos acceso total al servidor IIS instalado en nuestras instancias de Windows Azure podemos personalizar el mismo para poder ajustarlo a nuestras necesidades. Lo que si que es cierto es que, desde hace algunos años, estamos tan acostumbrado a trabajar desde la interfaz que nos proporciona Microsoft para manejar nuestros roles de Windows Server que muchas veces hacemos caso omiso de las herramientas igualmente útiles de las que disponemos desde la línea de comandos.
Para poder llevar a cabo las modificaciones pertinentes, es necesario el uso de  startups, por lo que nos “obliga” a conocer estas herramientas.

En este post en concreto voy a mostrar cómo podemos lanzar una configuración específica para modificar el valor por defecto de una de las secciones IIS. Obviamente no podré mostrar todas :) pero, al final, con un ejemplo prácticamente es similar para el resto de ellos.

Nota: Para conocer el detalle sobre cómo hacer uso de los startups podéis ver un ejemplo en el siguiente post. En este solamente comentaré comandos relacionados con IIS que podemos usar dentro de los startups.

Localización del comando appcmd

En primer lugar, es importante saber que la herramienta appcmd no está incluida dentro de la variable path del sistema, por lo que tenemos la opción de añadir la ruta del comando dentro de dicha variable o bien, de una forma más rápida, utilizar el comando desde la ruta completa de su localización:

%systemroot%system32inetsrvappcmd

Una vez que tenemos localizada la ruta de la herramienta podemos invocar la misma utilizando el siguiente conjunto de comandos:

  • List: Nos mostraría todos los objetos disponibles dentro de la máquina.
  • Add: Se utilizaría para la creación de nuevos objetos.
  • Delete: Elimina el objeto especificado por el ID del mismo.
  • Set: Configura parámetros dentro del servidor IIS.

En realidad, no me quiero centrar en cada uno de ellos. Para conseguir más información al respecto podéis hacerlo a través del siguiente enlace. Por el momento, el top de estos comandos suele ser Set ya que nos permite modificar valores que ya existen dentro de IIS y que, por algún motivo, necesitamos modificar su valor por defecto.

Para verlo con un ejemplo, un caso muy común sería habilitar los Parent Paths cuando trabajamos con ASP clásico. Para ello podemos lanzar el siguiente startup junto con nuestra solución:


start /w pkgmgr /iu:IIS-ASP

%systemroot%system32inetsrvappcmd set config -section:asp -enableParentPaths:true

En este ejecutable lo único que hacemos es, en primer lugar habilitar ASP clásico en el servidor IIS de la máquina virtual, ya que por defecto no está habilitado, y en segundo lugar utilizando la herramienta appcmd modificamos la configuración de la sección ASP que acabamos de habilitar indicándole que el valor del parámetro enableParentPaths debe ser igual a true.

Lo único que debemos tener en cuenta es la estructura de la llamada, siguiendo siempre el mismo patrón:

appcmd.exe set config [ConfigurationPath] /section:name /parameter_name:value

Por último me gustaría dejar un par de enlaces que creo que pueden ser de utilidad al respecto para alguna de las secciones más utilizadas/personalizadas de nuestro IIS :)

Configuración de HTTP Logging, HTTP Redirection, HTTP response headers and HTTP Compression.

Espero que sea de utilidad :D

¡Saludos!