Signos vitales de un servidor: Parte III (disco)

Después de unos días de descanso debido a las fiestas ampliamente conocidas, continuamos con la tercera entrega de la serie de monitoreo de signos vitales de un servidor, en la cual presentaremos la información necesaria para detectar problemas de rendimiento en las unidades lógicas de disco de un servidor.


Si bien es posible determinar problemas en unidades físicas, las diferentes configuraciones físicas de arreglos RAID 0, 1, 5, 1+0 y 0+1 y la creación posterior de unidades lógicas en el arreglo, hace muy difícil, si es que no imposible, el determinar si es o no un disco físico específico.


Antes de comenzar, hago un mini corte para recomendar este link de una presentación de David Solomon sobre cómo maneja la memoria Windows y como hacer un troubleshooting básico de los problemas. Además, se da tiempo de romper algunos mitos. Definitivamente un video imperdible. Está en inglés y dura 1 hora y 37 minutos.


http://www.microsoft.com/uk/technet/itsshowtime/sessionh.aspx?videoid=64


Diferentes caminos


Para la verificación de los contadores de disco, existen dos caminos conocidos. Uno de ellos el difícil y otro mucho más simple y agnóstico del hardware.


El primer camino, el cual NO veremos aquí corresponde a obtener información de los IOs de los discos, calcular la cantidad de operaciones de lectura y escritura que se realizan por cada tipo de RAID, la cantidad de discos físicos (ejes) involucrados en el RAID y hacer una cantidad importantes de cálculos y asumir con poca certeza algunas constantes o valores.


El segundo camino, mucho más simple, es agnóstico del tipo de RAID, la cantidad de discos y otras variables. ¿Qué es lo que mide? muy simple y básico:


¿Cuánto tiempo se demora el sistema de discos en realizar una operación de escritura o lectura?


Si se demora “mucho,” hay un problema. Si se demora “poco,” estamos bien. Si tienes picos elevados constantes, podemos estar en presencia de algún inconveniente o escasez de capacidad de procesamiento.


Además de la información relacionada con escrituras y lecturas, se debe complementar con información general del disco como el porcentaje de tiempo disponible y largo de la cola de requerimientos.


Veamos los contadores y contra qué compararlos, es decir, que es “bueno” y “malo.”


Nota: Antes de comenzar aclaro que cuando digo disco “malo,” no estoy mencionando que el disco está malo físicamente o que presenta alguna falla sino que realmente me refiero a que el disco no responde de acuerdo a lo que es espera de él, generalmente producto de una tasa muy elevada de requerimientos.


Contadores


Los contadores a medir del objeto Logical Disk, para la instancia específica (c:, d:, etc.), son los siguientes:




  • Avg Disk Sec/read: milisegundos en que una operación de lectura es llevada a cabo.



  • Avg disk Sec/write: milisegundos en que una operación de escritura es llevada a cabo.



  • % Idle time: porcentaje de tiempo que el disco está desocupado.



  • Avg disk queue length: largo promedio de la cola de requerimientos del disco



  • Current disk queue length: largo actual de la cola de requerimientos del disco


¿Contra que los comparamos?


Los dos primeros contadores se comparan contra la misma tabla de valores, la cual despliego a continuación:















Valor medido Significado
entre 1 milisegundo y 15 milisegundos Perfecto estado
entre 16 milisegundos y 25 milisegundos Se debe monitorear
más de 25 milisegundos Disco degradado

Se deben considerar valores promedios. Es esperable que un disco tenga picos por sobre los 25 milisegundos pero el valor promedio debe ser bajo.


Nota: Si tienes un storage con caché de escritura, deberás ser más estricto en las comparaciones y reducir un poco los valores. Esto se debe a que el caché de escritura mejora sustancialmente el rendimiento. Si antes 15 ms era el tope para considerar el valor como perfecto, entonces si mides 15 ms y tienes caché habilitado, no estarás dentro del grupo de perfecto estado sino que el rendimiento será medio y deberás monitorear la actividad.


Anécdota: El valor más alto que he presenciado en algunos casos ha sido de más de 900 milisegundos. Por supuesto, el servicio que se estaba exponiendo estaba severamente afectado, con tiempos de respuesta muy bajos.


El contador del tiempo porcentaje de tiempo disponible es simple también. Más de 50%, perfecto estado. Entre 20% y 50%, se deberá monitorear y menor a 20%, el disco está degradado.


Por último, para los contadores de largo de cola de requerimientos promedio y actual, estos dos valores se comparan y calculan de la misma forma. Si la cantidad de discos físicos que componen el arreglo de discos es conocida, se deberá comparar contra el valor medido menos la cantidad de discos y dividirlo por dos.


Por ejemplo: Si el valor medido del largo promedio de la cola de requerimientos es 25 y tengo 10 discos en el arreglo, la formula nos retorna: (25-10)/2 = 7,5.


Este valor es menor a 1, el rendimiento es excelente. Entre 1 y 3, se deberá monitorear. Mayor a 3, crítico o degradado.


Por supuesto, la formula presenta inconvenientes cuando los valores medidos son menores a la cantidad de discos, pero en ese caso el disco claramente no tiene problemas.


¿Qué sucede si no conozco la cantidad de discos? y bueno, en ese caso se recomienda dividir por 2 el valor medido en el contador y aplicar la misma regla de comparación. Entendemos que no es un valor fidedigno, pero tampoco es “tan errado.” Para el mismo ejemplo, 25/2  es 12,5, un valor mayor a 7,5, pero igual de malo de acuerdo a el parámetro de comparación.


Como pueden ver, monitorear un disco es muy simple. Si no responde en tiempos breves, claramente le estamos pidiendo más de lo que puede dar.


Queda pendiente una o dos entregas más de signos vitales, las que llegarán espero durante este mes.


Saludos,
Patrick

Signos vitales de un servidor: Parte II (procesador)

Continuando con los signos vitales de un servidor, hoy día veremos en la segunda parte, el procesador.


El análisis del procesador es bastante más simple que el de la memoria. Hay dos contadores importantes. Uno de ellos corresponde al uso del procesador, con dos matices especiales; uso del procesador en modo usuario y el otro en modo kernel. El otro contador corresponde a la cantidad de requerimientos encolados del procesador.


Como ya hemos visto en otros posts, Windows utiliza dos modos de ejecución. Uno de ellos es el modo usuario, donde corren las aplicaciones que nosotros ejecutamos y el otro es el modo Kernel, en el cual corre el kernel del sistema operativo.


¿Por qué es importante esta explicación?


Si logramos identificar quién está consumiendo el procesador, podremos inferir y tener mejores pistas para encontrar al culpable del consumo de éste.


Si te preguntas ¿para qué necesitas saber el modo (usuario o kernel) que está consumiendo el procesador, si mirando el task manager sabrás fácilmente qué aplicación es responsable?


Bueno. Hay un par de razones. Veamos cada una de ellas.


1.- Task manager te dirá la aplicación que está consumiendo el procesador, pero no te dirá más. Solo la aplicación. Perfmon por otra parte te podrá entregar más información. [procexp] de Sysinternals es una excelente herramienta.
2.- Task manager no muestra siempre el consumo del kernel.


El segundo punto no está tan relacionado con aplicaciones, pero vale la pena aclarar que hay ciertas actividades del kernel que no son cuantificadas por Task Manager, o son cuantificadas pero no desplegadas. Recordemos que el kernel corresponde al proceso llamado System, siempre con el PID 4. Entonces puede parecer que tu sistema tiene bajo uso del procesador, pero el kernel está trabajando activamente. Para mejores resultados en el despliegue de los recursos consumidos, puedes utilizar [procexp].


Resumiendo


Podemos decir que para una aplicación específica:


El porcentaje de consumo en modo kernel corresponde a las actividades que debe realizar el kernel para cumplir con los requerimientos de la aplicación, como por ejemplo, trabajar con archivos, mover memoria, escribir en sockets, pintar ventanas, etc.


El porcentaje de consumo en modo usuario corresponde a la ejecución de código sin interacción con el kernel, es decir, algo así como “el código sin acceso a recursos externos.” Si estuviésemos utilizando un profiler, diríamos entonces que corresponde a lo que se llama “exclusive time.”


Contadores


La siguiente es la lista de contadores de perfmon a utilizar, que como podrán notar, es muy breve, repetitiva y casi no requiere mayor explicación.




  • Objeto System, contador Processor Queue Length: muestra la cantidad de requerimientos encolados para el procesador.



  • Objeto Processor, contador % Privileged Time: muestra el porcentaje de tiempo utilizado por el kernel, para todo el procesador



  • Objeto Processor, contador % User Time: similar al anterior, pero para modo usuario



  • Objeto Process, contador % Privileged Time, instancia específica. muestra el porcentaje de tiempo utilizado por el kernel, para la aplicación seleccionada en el campo instancia



  • Objeto Process, contador % User Time, instancia específica: similar al anterior, pero para modo usuario



  • Objeto Thread, contador % Privileged Time, instancia específica: muestra el porcentaje de tiempo utilizado por el kernel, para un thread especifico de la aplicación seleccionada



  • Objeto Thread, contador % User Time, instancia especifica: similar al anterior, pero para modo usuario


Probablemente te podrás estar preguntando la utilidad de la información de los últimos 2 contadores. ¿de que te serviría saber cuál es el thread responsable si no se puede hacer mucho con esa información?


Si se puede hacer bastante. Puedes determinar si es un único thread que está ocupando mucho el procesador o es un conjunto de ellos en que todos aportan. Te sirve para obtener pistas.


Podría ser el thread o los threads del GC, el thread del Finalizador, un thread que se quedó pegado en un ciclo, etc. [procexp] entrega mucha información referente a tipos de procesos e informacón de los threads.


Ok, ya tengo todos los datos…


¿Contra qué comparar la información?


Salvo para el primer contador, no hay punto de comparación. Si el uso del procesador llega a 80% o más, probablemente sea hora de proveer alivio al servidor, ya sea corrigiendo el código o haciendo un upgrade del hardware.


El primer contador no debe ser mayor a 2 multiplicado por la cantidad de procesadores (cores) de tu servidor. Para el caso de HT (Hyper Threading), no estoy seguro, pero creo que no se deben contabilizar.


Ya vendrá una tercera entrega relacionada con el disco duro.


Saludos,
Patrick

Signos vitales de un servidor: Parte I (memoria)

¿Qué sucede si uno no se siente bien?; en condiciones normales, uno visita al doctor para saber qué sucede y éste hace una revisión general. Si el doctor encuentra algo interesante, te pide hacer unos exámenes para saber con mayor detalle qué está sucediendo.


Llevando este mismo ejemplo al área de la informática, si tienes un servidor y presientes (o tienes total certeza) que algo no funciona como debiera, un buen punto de partida es determinar si los signos vitales de éste están bien.


El objetivo de este post es dar una pauta general para determinar cuando un servidor Windows 2003, cualquier versión, puede tener algún problema que afecte sus signos vitales. Hoy veremos los signos vitales de la memoria. Los siguientes posts abordarán otras áreas.


Un poco de contexto


Si has escuchado muchas veces la palabra contadores, y no tienes claro a que se refieren cuando lo escuchas, esta sección debiera aclararte un poco. Si tienes claro a que se refiere, puedes saltarte  esta sección.


Los contadores son entidades u objetos que mantienen información del funcionamiento de algún programa o sistema operativo (SO de ahora en adelante). Cada programa que utilizas —todos debieran, pero no siempre lo hacen— genera información con estadística y en tiempo real del funcionamiento de éste, la cual se le informa al SO. A su vez, el SO también genera información que almacena para que nosotros podamos consultarla y saber cómo está funcionando.


Los contadores se categorizan por objetos (por ejemplo, memoria, sistema, sql server, iis) y se pueden o no aplicar a instancias (procesos, sitios web, bases de datos, etc.)


Por ejemplo, un contador de importante SO es la cantidad de memoria disponible que le queda. Este se categoriza en el objeto Memory, y el contador se llama Available MBytes, que nos dice la cantidad de megabytes de memoria disponible. Los nombres de los contadores dependen del idioma del programa o SO. Si estás ejecutando un SO en español, el objeto podría llamarse Memoria y el contador, cantidad de MB disponibles.


La siguiente es una imagen de cómo se agrega este contador utilizando performance monitor (perfmon).



Luego, después de habar agregado los contadores, podrás ver una pantalla como ésta, donde la primera es la representación gráfica y la otra la textual, para la misma información.


 


 


Suponiendo que ya se entiende la idea, vamos entonces a ver la primera parte de cómo chequear la salud de un sistema operativo.


Grupos de contadores


Aunque los contadores ya están agrupados de acuerdo a los objetos a los cuales pertenecen, los volveremos a agrupar en clasificaciones más grandes, más generales. Tendremos entonces un grupo para colocar los contadores de memoria, uno para los del procesador, otro para el disco duro, otro para la tarjeta de red y otro para el sistema operativo. En otra oportunidad veremos los asociados a productos específicos como SQL, IIS o .NET.


Contadores de memoria


Los contadores de memoria son variados. Podemos encontrar desde la memoria utilizada por una aplicación, la memoria libre del servidor y la memoria utilizada por los componentes del Kernel del SO. Todas estas son importantes y están de alguna forma relacionadas.


Veamos cada uno de los contadores mencionados y contra qué compararlos (cuando aplica).


Memoria del sistema (incluido kernel)


La memoria libre del sistema la entrega el contador Available MBytes, del objeto Memory. El mismo contador existe retornando el valor en otras unidades como KBytes y Bytes. De acuerdo a la cantidad de memoria que hoy en día tiene un servidor, medir en bytes o kilobytes puede no ser necesario.


Diversa documentación podrán encontrar referente a este contador. Algunos dirán que con 10 MB disponibles, es momento de preocuparse. Otros dirán que 25 MB es una señal de preocupación. En general, menos del 10% de la memoria total instalada ya es reflejo de que al sistema le falta memoria. Por ejemplo, si mi servidor tiene 2GB instalados y le quedan 150 MB disponibles, significa que estoy consumiendo el 92,5% de la memoria. Sin embargo, otros contadores te ayudarán a determinar si esto es cierto o no (si hay o no un problema). Puede ser que tengas mucha memoria ocupada, pero el sistema funcione bien.


Otro contador importante es Pages/sec del objeto Memory. Este refleja la tasa de lecturas y escrituras a disco para resolver problemas de páginas no encontradas (hard faults) en la memoria física, y por ende, tiene que ir al archivo de paginación a buscarla (y guardar otra para hacer espacio).


La información disponible públicamente es muy variada. Desde sitios que dicen que valores de más de 100 son preocupantes. Otros dicen que más de 5 de forma constante es preocupante. Lamentablemente ninguna de esas medidas es agnóstica y depende de otros factores (como el disco). Una medida agnóstica se obtiene al multiplicar este contador por Avg. Disk sec/Transfer del objeto Physical Disk, en la instancia (disco) donde está el archivo de paginación. El resultado de multiplicar ambos corresponde al porcentaje de tiempo de acceso a disco. Si es mayor a 10%, está paginando mucho, lo que puede ser producto de falta de memoria.


Los contadores de memoria del kernel se deben comparar contra valores en unas tablas específicas. Estos son Pool Paged Bytes y Pool Nonpaged Bytes del objeto Memory. Las tablas se encuentran a continuación, tanto para Windows 2000 como Windows 2003 (clic para agrandar).







Windows 2003

Windows 2000 SP4

Los valores obtenidos para cada unos de los contadores, tanto para paged como nonpaged, corresponden a la cantidad de bytes de cada pool que ha sido utilizado. Si es menor al 50% del pool, todo está bien. Mayor a 50% y menor a 80%, es hora de preocuparse. Si es mayor a 80%, hay problemas.


¿Cómo se mide?


Si obtuviste un valor de 56 MB en el contador de paged pool bytes y tu sistema es Windows 2003 con 4 GB y estás usando /3GB, el tamaño total del paged pool bytes es de 258 MB (revisa la tabla). La tasa de uso (56/258) es cercana al 21%, lo que nos dice que nuestro sistema está bien. Lo mismo para nonpaged pool bytes, pero considerando el otro valor en la tabla.


El último contador relacionado con la memoria en el kernel corresponde a Free System Page Table Entries (PTEs), del objeto Memory. Los PTEs son estructuras internas utilizadas por el componente del kernel llamado Memory Manager y que tiene como objetivo administrar la memoria.


Si este contador se reduce mucho (menos de 15 mil o 10 mil), habrá problemas. Usualmente este contador se ve afectado por la utilización de la opción /3GB sin utilizar la opción /userva. Esta anécdota ocurrió en un caso donde no se utilizó /userva.


Después de haber visto las opciones para el sistema y kernel, podemos ver las opciones de memoria disponibles para las aplicaciones.


Memoria de aplicaciones


Para medir la memoria de una aplicación específica, tengo que agregar los siguientes contadores, y asociarlos con el proceso que quiero medir (instancia en la parte derecha de la ventana):




  • Objeto Process, contador Private Bytes



  • Objeto Process, contador Virtual Bytes



  • Objeto Process, contador Working Set


El primer contador corresponde a la memoria privada el proceso. El segundo contador, a la memoria virtual del proceso. Para un mejor entendimiento de los tipos de memoria que miden, te recomiendo la lectura de estos posts:



El working set corresponde a la cantidad de memoria privada (sumada a la memoria usada por dlls y otras estructuras) que está cargada en memoria real (física). A grosso modo, la suma de los working set de todos los procesos no podrá superar la memora física de tu máquina.


Lamentablemente no hay valores contra qué compararlos, pero de acuerdo a lo que vimos en el segundo post de la lista de más arriba, la memoria virtual no podrá superar los 2 GB en un sistema de 32 bits.


Si virtual bytes es muy elevado en comparación con private bytes, podría haber un problema de fragmentación de memoria. ¿Qué significa muy elevado?; tampoco hay una respuesta, pero unas 10 veces debiera ser preocupante, como también es preocupante acercarse a los 2 GB. Claro que las 10 veces dependerá de la memoria que use nuestro proceso. Si un proceso utiliza 10 MB de memoria privada, es normal que utilice 100 MB de memoria virtual.


Hay muchas cosas relativas, pero lo importante es monitorearlos en el tiempo.


Si virtual bytes sube y sube sin descender (o descendiendo menos de lo que aumenta), habrá un problema de fragmentación de memoria, aunque dependerá de cómo aumente private bytes también.


Si private bytes sube y sube sin descender (o descendiendo menos de lo que aumenta), tendrás un problema de pérdida de memoria o memory leak. Private bytes no podrá ser superior al máximo de memoria virtual de un proceso (2GB).


Otros contadores


Sin duda, hay muchos más contadores, pero para determinar signos vitales, con éstos basta.


Desde Santiago de Chile,
Patrick

Contadores de rendimiento de aplicaciones de 32 bits en sistemas de 64 bits

Durante el análisis de Microsoft.VisualBasic.dll tuve problemas para poder ver los contadores de rendimiento de la aplicación desarrollada con Visual Studio 2003 y que se ejecutaba sobre el Framework 1.1, en un sistema XP 64 bits.


En ese momento inferí que podría deberse a que la aplicación estaba compilada para 32 bits y se estaba ejecutando en un sistema de 64 bits. Es conveniente recalcar que el Framework 1.1 compila ensamblados sólo para 32 bits.


Hoy, después de un tiempo, me tope con el KB 922775. Para mi sorpresa, tiene un punto dedicado al problema que se me presentó (You cannot monitor 32-bit managed programs in the 64-bit version of Perfmon). En éste, se presenta un workaround para poder monitorear contadores de rendimiento de aplicaciones de 32 bits corriendo en sistemas de 64 bits.


Además tiene información relevante para reconstruir los contadores si alguna vez se corrompen.


Saludos,
Patrick

Predicando con el ejemplo

Predicar con el ejemplo. Hemos escuchado eso desde chicos. A veces es difícil lograrlo, pero el hacerlo trae beneficios de diferente índole.


El tema de esta oportunidad está relacionado con los mensajes de error. Uno de los tantos posibles problemas de seguridad de las aplicaciones es la revelación de más información de la necesaria cuando se produce un error.


Lo anterior significa que si la aplicación se cae, le informe al usuario pero no le dé mayor información al respecto, información que además es inútil para el usuario ordinario, pero útil para quien te quiera atacar.


Más información de esta vulnerabilidad podrán encontrar en el sitio del proyecto OWASP, en el siguiente link.


Hace un par de días estaba utilizando OWA de la empresa donde trabajo y de pronto, me topo con esta ventana. Haz clic en ella para verla completa.



Mal, mal. A predicar con el ejemplo. OWA no debiera mostrar este tipo de ventanas de error.


Buenos ejemplos 


Veamos algunas pantallas de error donde sí se han tomado las precauciones.


Esta es la de la aplicación que utilizamos en el blog de msmvps.com. Muy divertida, aunque el administrador podría sentirse ofendido.



Google también cumple con las buenas prácticas.



 


Malos ejemplos 


El típico error de asp.net, cuando el desarrollador y administrador no han tomado las medidas necesarias para que no le llegue al usuario final.


 


y para el final, el peor de todos, cuando se cae leyendo el archivo de configuración y se muestra el contenido de éste.



Corrección


¿Cómo corregirlo? Muy fácil.


Para que no se muestre el error en ASP.NET se puede utilizar el elemento Error en la configuración. Más información en este link: http://msdn2.microsoft.com/en-us/library/s2f4e3e7.aspx.


Para modificar IIS para que no muestre el contenido en los errores no controlados se pueden seguir los pasos detallados en este KB: http://support.microsoft.com/kb/302570/en-us


Saludos,
Patrick

¿Expresiones regulares?…¿una ayuda por favor?

Si hoy tuviese que dar una lista de las funcionalidades más poderosas de cualquier lenguaje y que son menos usadas, sin duda incluiría en esta lista las expresiones regulares.


Hay que ser honestos y reconocer que existen un par de barreras de entrada importantes para su uso.




  1. Documentación. No existen muchos sitios dedicados a explicarlas. Hay unos muy buenos, pero son pocos.



  2. Dificultad de aprendizaje. No son triviales.


Si tienes conocimientos básicos de estas y siempre has tenido problemas probando y probando, te recomiendo este sitio. Tiene un probador que usa colores y te muestra si tu información cumple con la expresión definida, y si no lo hace, hasta dónde llega.


La URL es regexpal.com y ésta es una imagen de su utilización. Muy útil.


Minimizar el impacto de subidas a producción (waitChangeNotification, maxWaitChangeNotification)

A pesar de que no es recomendado, muchas veces nos hemos visto forzados a subir cambios a producción “en caliente.”


Estos cambios en caliente generalmente se deben por cambios en machine.config, web.config o el copiado de nuevos assemblies a la carpeta bin, y estos cambios obligan a que se reinicie el dominio  de la aplicación asp.net.


Como dominio de aplicación entendemos una estructura interna en memoria, dentro de un proceso, donde están cargados los assemblies, las páginas compiladas y toda la memoria utilizada en el funcionamiento de nuestra aplicación. Esta explicación es muy pobre, pero contiene lo necesario para entender el costo de los cambios.


Cada vez que se inicia o carga un dominio, previamente se debe descargar, esto es, suponiendo que no es la primera vez que se inicia. Y antes de poder descargarse, debe terminar de procesar todos los requerimientos que tiene activos.


Debido a lo anterior, cada vez que copiamos assemblies a la carpeta bin, disparamos una descarga del dominio. Si en ese momento entra un nuevo requerimiento, se crea un nuevo dominio para atender el requerimiento (con el o los nuevos assemblies que hayan disponibles producto de la copia). Sucesivas copias en el mismo período de tiempo hará que la situación se repita. Esto último puede llevar a nuestro servidor y aplicación a quedar en un estado inestable.


Personalmente lo he vivido varias veces, cuando se sube en caliente para corregir bugs críticos que no pueden esperar. Dentro de los errores recibidos producto de estas subidas extremas, estaba un extraño error de compilación de las páginas. Generalmente, la única manera de resolver la inestabilidad era haciendo un iisreset.


Si hacemos un resumen de cuánto tiempo perdíamos en esas subidas, generalmente era entre 30 y 45 segundos. No vamos a hablar ahora de las molestias a los clientes. Primero por una aplicación que respondía inestablemente y luego por que definitivamente no prestábamos servicio.


Para minimizar este problema y “garantizar” que el impacto de una subida a producción sea mínimo, existen un par de opciones disponibles para configurar en el archivo web.config. Por favor, notar que utilicé comillas en garantizar. Esto debido a que si se configuran mal las opciones, el resultado no es el mejor (aunque mejor que el escenario anterior sin la configuración).


Estas opciones son waitChangeNotification y maxWaitChangeNotification. La documentación oficial de estos contadores está en http://msdn2.microsoft.com/es-es/library/e1f13641(VS.80).aspx, pero la calidad de la explicación es bastante pobre.

Vamos a hacer un mejor esfuerzo.

Aclaremos primero que ambas almacenan valores en segundos y a pesar de que la documentación dice que es un atributo sólo de aspnet 2.0, en la versión 1.1 también funciona (al menos en mi XP Pro con IIS 5.1, y la aplicación web configurada en 1.1)


La primera opción de configuración (waitChangeNotification) instruye al IIS y aspnet cuanto tiempo debe esperar a que un nuevo requerimiento genere un nuevo dominio una vez que ha detectado un cambio.


Esto nos ayuda a darnos un rango de tiempo para poder copiar todos los archivos necesarios. Este rango de tiempo es desplazable, lo que significa que son X segundos después de la última notificación de cambio (último archivo subido/modificado/agregado), descartando todas las notificaciones anteriores.


La segunda opción (maxWaitChangeNotification) establece el tiempo máximo en que se reiniciará el dominio. Esta opción existe ya que como la anterior es desplazable, sucesivos cambios en un breve tiempo podrían demorar el reinicio del dominio más de lo esperable.


Veamos un ejemplo para aclarar esto.

Ejemplo

Configurando el primer atributo en 5 segundos, si realizo 10 modificaciones en total, cada una separada 4 segundos de la modificación anterior, el reinicio se realizaría a los 41 segundos, sólo 5 segundos después de la última modificación. Esta última ocurre a los 36 segundos ya que la primera ocurre a los 0 segundos (0-4-8-12-16-20-24-28-32-36).


La segunda opción de configuración, si se define en 30 segundos, implicaría que el escenario anterior nunca ocurra ya que habría forzado el reinicio a los 30 segundos, entre la 8va y 9na modificación.


Con esta segunda opción, el segundo reinicio sería a los 11 segundos después, suponiendo que el reinicio es instantáneo.

De vuelta a la realidad

A pesar de que el ejemplo anterior puede parecer complejo, no dejes que éste te confunda. Lo importante es darle un tiempo a tu aplicación para que se reinicie limpiamente sin afectar demasiado a los clientes. Elije un tiempo acorde a las necesidades de tu aplicación y configura las dos opciones, no sólo la primera, y la segunda debe ser mayor a la primera.


¿Cómo se modifica en el web.config?
<system.web>
<
httpRuntime waitChangeNotification=X maxWaitChangeNotification=Y/>
</system.web>


Saludos,
Patrick

Page Load se ejecuta 2 veces …

Hoy me he topado con un hecho muy curioso, y de explicación no muy clara. Por lo menos para mi.


Revisando una página web por que tenia un funcionamiento extraño, noté que el evento Page.Load se estaba ejecutando dos veces. Lo que primero revisé fue que no estuviese en true la opción AutoEventWireup. Con ésta opción en true, es común que los eventos se disparen dos veces.


Pero no era así. Estaba en false. Revisando el code behind de la página, encuentro el siguiente código, que no posee ninguna instrucción extraña o desconocida.


    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If User.Identity.IsAuthenticated Then Response.Redirect(“redireccionar.aspx”, True)
        ……….
    End Sub


Luego, al revisar el código escrito en la página misma (archivo aspx), noté que también estaba definido un page load, de la siguiente forma, definido dentro de una etiqueta script language=”VB” runat=”server”:


    Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        MyBase.Page_Load(Sender, e)
        …..
    end sub


Tampoco se ve nada extraño, salvo que la funcion Page_Load llama explícitamente a MyBase.Page_Load. Esto no es extraño si recordamos algo de OOP y herencia. Una clase especializada, llamando al constructor de una de mayor generalización. Dicho de otra forma, una clase heredada llamando al constructor de la clase de la cual heredó.


Para mi sorpresa, era éste llamado a MyBase.Page_Load(Sender, e) el que estaba ejecutando por segunda vez la funcion Page_Load definida en el code behind.


¿Por que sucede así, si se está llamando a una clase base?


La explicación me llega ahora mientras escribo ésto. Muy simple. En la directiva de página de la página en cuestión, aparece el siguiente código.


Page CodeBehind=”inicio.aspx.vb” Language=”vb” AutoEventWireup=”false” Inherits=”Web.Paginas.inicio”


La pagina aspx hereda de la clase code behind, y por lo tanro, el llamado es válido. Es funcionamiento es normal, pero también pasa muy desapercibido.


Patrick.
Febrero 2005.

Enviar archivos al navegador del cliente

Para mandar el contenido de un archivo al browser o navegador del cliente, y presentarle el cuado de diálogo si desea abrir, guardar o cancelar este archivo, se debe cumplir lo siguiente:


Construir una página sin código html. Esto es muy importante ya que cuando se envíe el contenido del archivo, no debe haberse enviado código html ya que la mezcla de estos (el código y el archivo) hará que el navegador del usuario no entienda bien el contenido.


En el código fuente de esta página, agregar las siguientes líneas (los números son sólo de referencia)


1.- Response.ClearHeaders();


2.- Response.ClearContent();


3.- Response.AddHeader(“Content-Disposition”, “attachment;filename=NOMBRE_DEL_ARCHIVO“);


4.- Response.ContentType = “application/pdf“;


5.- Response.BinaryWrite(ARREGLO_DE_BYTES_CON_EL_CONTENIDO_DEL_ARCHIVO);


6.- Response.Flush();


7.- Response.Close();


En este caso, las líneas 1 y 2 limpian el buffer que se haya llenado con información que no corresponde al archivo. Esto es necesario si en algún momento antes de haber llegado a estas líneas, se hizo algún response.write.


Las líneas 3 y 4 le dicen al navegador del cliente las instrucciones correspondientes al envío de un archivo llamado NOMBRE_DEL_ARCHIVO y del tipo que es. En este caso, se le especifica que es un pdf. Más abajo se desplegarán los tipos más comunes, y un link a una página muy completa con los tipos existentes.


La línea 5 escribe el arreglo de bytes del archivo en el cliente. Posteriormente entregaré una función para sacar un arreglo del bytes de un archivo.


Por último, las líneas 6 y 7 vacían el buffer y cierran el envío al cliente.


Un listado con algunos de los tipos MIME más comunes:


























Texto Plano


text/plain


Imagen gif / jpg


image/gif o image/jpeg


Video Mpeg


video/mpeg


Postscript


application/postscript


Pdf


application/pdf


MS Powerpoint


application/mspowerpoint


MS Excel


application/vnd.ms-excel o application/ms-excel


La URL con muchos de los tipos MIME disponibles es:
http://www.utoronto.ca/webdocs/HTMLdocs/Book/Book-3ed/appb/mimetype.html


Patrick
Publicado, Noviembre 2004.
Revisado, Enero 2007.

Cómo instalar Crystal Reports en un servidor web en 6 pasos.


Por favor, no instalar Visual studio en servidores sólo para tener acceso a crystal reports. Esto ya lo he visto hacer muchas veces y no es el camino correcto.[N]


Para instalar Crystal Reports (CR) en un servidor de producción deben se seguir los siguientes pasos. Además, es necesario tener una licencia comprada para que cuando se les solicite el Key, lo ingresen.


La forma de hacer requiere un pequeño truco. Éste consiste en hacer una aplicación web pequeña, que no haga nada en especial, pero que incluya una página con un formulario, y que este formulario incluya un objeto de CR.


Veamos entonces los pasos para lograr la instalación.


1.- Generar la aplicación web simple con una pagina, que haga referencia a los assembies de CR y que tenga un formulario con un objeto.


2.- Crear un proyecto de instalación web dentro de la misma solución donde está el proyecto web simple.


3.- Con el botón derecho del mouse sobre el nuevo proyecto de instalación, seleccionar àAgregar àResultados del proyecto (o en ingles àAdd àWeb Output). En el popup que se les presente, seleccionar el proyecto web en el combobox y de las lista elijan Resultado Principal y Archivos de contenido (en ingles Primary Output y Content Files).


4.- Nuevamente boton derecho del Mouse sobre el proyecto de instalación seleccionar àAgregar àMódulo de combinación (en ingles Merge Module), y seleccionar de la lista de módulos (depende de la versión)


    a.- database_access.msm o Crystal_Database_Access2003.msm (puede haber otro idioma)


    b.- regwiz.msm o Crystal_regwiz2003.msm


    c.- manager.msm o Crystal_Managed2003.msm


5.- Se debe seleccionar ahora el archive regwiz.msm o Crystal_regwiz2003.msm y con el botón derecho llamar a propiedades. En propiedades, expandir el símbolo [+] y donde dice License Key se debe agregar el número de licencia para instalarlo en el servidor. El numero de licencia se puede obtener desde el IDE de Visual Studio, en Ayuda à Acerca de Microsoft Development Environment, seleccionando CR y copiando el texto de la derecha de la línea seleccionada. Es necesario registrar el key en Crystal decisions antes de proseguir. Si han comprado un CR para servidor, el numero de licencia es válido y se puede usar aquí.


6.- Continuar con el proceso de generación del instalador e instalar en el servidor.


Patrick Mac Kay
Octubre 2004.