Archivo de la categoría: Microsoft

¿Cómo ejecutar Apache SOLR en Windows Azure?

Trabajando con una startup en Argentina me plantearon la pregunta sobre cómo ellos podían llevar su solución a Windows Azure y así obtener todas las ventajas de una solución cloud. Ellos utilizaban una aplicación Web con base de datos SQL, nada exótico por lo cual el movimiento era transparente, a excepción de un detalle. Esta compañía utiliza SOLR como motor de búsqueda. SOLR es un buscador empresarial que corre en java http://lucene.apache.org/solr/

Esa pieza es la parte más entretenida de la migración, cómo correr Apache Solr sobre Windows Azure. Bueno, este post explica cómo paso a paso.

Escenario
El escenario a implementar es un Sitio Web (Web Role) que juega el papel de Front End, el cual utiliza el servicio de búsqueda de Solr (Worker Role) que juega el papel de backend. Las llamadas entre el FrontEnd y SOLR son llamadas HTTP a un puerto interno. El escenario se muestra en el siguiente diagrama. La idea de usar un puerto interno es para que sólo nuestro Front End pueda utilizar el motor de Solr.

Prerrequisitos
Los prerrequisitos para desarrollar este tutorial son los siguientes:

  1. Tener instalado Windows Azure SDK for .NET
  2. Tener un archivo ZIP con la java virtual machine y SOLR
  3. Tener la librería ICSharpCode.SharpZipLib.dll para trabajar archivos ZIP

Como parte del código fuente de la solución, ambos archivos vienen incluidos. El SDK lo deben descargar directamente desde http://www.windowsazure.com/en-us/develop/net/#

Los pasos para construir el proyecto son los siguientes:

  1. Crear un proyecto del tipo Cloud
  2. Agregar la librería ICSharpCode.SharpZipLib.dll
  3. Agregar el archivo ZIP que contiene JRE y SOLR
  4. Agregar los Script de configuración
  5. Agregar la tarea de inicio del Worker Role
  6. Comprobar que SOLR se inicia junto con el Worker Role
  7. Configurar el puerto de comunicación entre el Web Role y el worker Role
  8. Crear página de búsqueda en el Web Role
  9. Implementar consulta de versión de Java a SOLR.
  10. Comprobar la consulta de versión de Java a SOLR.
  11. Implementar comando Ping y búsqueda a SOLR
  12. Comprobar el resultado de los comandos Ping y búsqueda

Paso 1: Crear un proyecto del tipo Cloud
En visual Studio 2012 crear un proyecto del tipo Cloud y agregarle dos roles:

  1. Web Role llamado FrontEndDolr
  2. Worker Role llamado SolrService

La siguiente figura muestra los dos roles a crear.

Paso 2: Agregar la librería ICSharpCode.SharpZipLib.dll
Esta biblioteca la utilizaremos para descomprimir el archivo ZIP que contiene JRE y SOLR. Podemos encontrar la librería en

http://www.icsharpcode.net/opensource/sharpziplib/

La agregamos en una carpeta llamada lib en el Worker Role, solo para mantener el orden del proyecto. Un detalle muy importante es que una vez agregada la libraría al proyecto vayamos a sus propiedades y configuremos «Copy to Output Directory» con el valor «Copy Always«

Paso 3: Agregar el archivo ZIP que contiene JRE y SOLR
Como SOLR corre en java es necesario tener la JavaTM Standard Edition Runtime Environment (JRE). La distribución de la JRE es muy simple, es cosa de copiar todo el contenido del directorio en el disco local del Worker Role antes de utilizarlo. JRE se puede descargar desde

http://www.java.com/es/download/index.jsp

De manera similar, SOLR, también puede ser distribuido copiando todo el contenido del directorio en el Worker Role. SOLR puede ser descargado desde

http://www.apache.org/dyn/closer.cgi/lucene/solr/4.0.0

Una vez que obtiene los dos componentes, la idea es copiar los directorios que los contienen y comprimirlos en un archivo ZIP, de nombre javasolr. Una vez hecho esto, debemos agregar el Zip al proyecto dentro de una carpeta que llamaremos java. Una vez agregado el archivo ZIP al worker Role se configura en sus propiedades «Copy to Output Directory» con el valor «Copy Always«.

Paso 4: Agregar los Script de configuración
Ahora debemos agregar los script que se ejecutaran al momento de iniciar el Worker Role. La idea es que al inicio del mismo, se realicen las siguientes tareas:

  1. Descomprimir JRE y SOLR
  2. Ejecutar SOLR

Para esto usaremos el siguiente script de PowerShell.

function unzip ($zip, $destination) {

Add-Type -Path ((Get-Location).Path + ‘\lib\ICSharpCode.SharpZipLib.dll’)

$fs = New-Object ICSharpCode.SharpZipLib.Zip.FastZip

$fs.ExtractZip($zip, $destination, »)

}

#Paso 1: descomprimier JRE y SOLR

unzip ((Get-Location).Path + «\java\javasolr.zip») (Get-Location).Path

#Paso 2: ejecutar SOLR

cd «.\javasolr\Solr»

..\..\jre7\bin\java.exe -jar start.jar

Este script lo agregamos al Worker Role en un archivo llamado Launch.PS1. Una vez agregado script al worker Role se configura en sus propiedades «Copy to Output Directory» con el valor «Copy Always«. Es importante grabar este archivo con la codificación para Windows y no UTF-8 que utiliza Visual Studio por defecto para archivos de texto. Esto se hace en el menú File, Advance Save Options y seleccionar una codificación para Windows como la siguiente.

Ahora, vamos a agregar el archivo Run.cmd que será el que ejecutará el script de PowerShell. Run.cmd contiene la siguiente línea de código

powershell -executionpolicy unrestricted -file .\Launch.ps1

Esta línea de comandos, está ejecutando el script de PowerShell sin restricciones. Una vez agregado el archivo Run.cmd al worker Role no olvidar configurar en sus propiedades «Copy to Output Directory» con el valor «Copy Always«. Si esto no se realiza, entonces no se copia el script por lo cual la tarea de inicio fallará. Por último, grabar este archivo con la codificación para Windows y no UTF-8, de la misma forma como se hizo para el Script de PowerShell.

Paso 5: Agregar la tarea de inicio del Worker Role

El archivo llamado ServiceDefinition.csdef es el que contiene todas las definiciones del servicio que estamos creando. En él está definido el Web Role y el Worker Role. Es aquí donde vamos a agregar la tarea de inicio del Worker Role, para que descomprima el archivo ZIP que contienen la JRE y SOLR, para luego levantar el servicio de SOLR en el puerto 8983.

Para ellos debemos modificar la definición del Worker Role de la siguiente manera

<WorkerRole name="SolrServicevmsize="Small">
    <Startup>
      <Task commandLine="Run.cmdexecutionContext="limitedtaskType="background" />
    </Startup>
    <Imports>
      <Import moduleName="Diagnostics" />
    </Imports>
    <Endpoints>
      <InternalEndpoint name="httpSolrprotocol="tcpport="8983" />
    </Endpoints>
  </WorkerRole>

El tag Startup que contiene TASK define que al momento de iniciar el Worker Role, se ejecute el comando Run.cmd

Paso 6: Comprobar que SOLR se inicia junto con el Worker Role
Ahora vamos a comprobar que todo está funcionado correctamente con nuestro proyecto. Paro esto vamos a ejecutar en modo debug. Obtenemos la siguiente página Web en nuestro Browser.

Ahora, vamos a ver si SOLR está funcionando. Hay que tener en cuenta que el Worker Role al iniciarse, descomprime el archivo ZIP y eso toma un tiempo. SOLR funciona por defecto en el puerto 8983, entonces cargamos la siguiente URL http://localhost:8983/solr/admin/ y vemos

Ahora, si ejecuto la búsqueda siguiente obtengo http://localhost:8983/solr/select/?q=usb&version=2.2&start=0&rows=10&indent=on

Nota aclaratoria: el paquete de SOLR que estoy utilizando ya está indexado para efecto de pruebas, si ustedes usan el paquete por defecto, no podrán buscar hasta realizar el indexado. Un tutorial de SOLR muy rápido de leer, donde pueden ver como indexar, está en http://www.solrtutorial.com/solr-in-5-minutes.html

Paso 7: Configurar el puerto de comunicación entre el Web Role y el Worker Role
Para establecer la comunicación entre el Web Role, que será nuestro Front End, y el Worker Role, donde está corriendo el servicio SOLR vamos a declarar un EndPoint en el Worker Role. Este Endpoint será del tipo interno ya que su objetivo es solo permitir que el Web Role haga consultas a SOLR. Para ellos vamos a las propiedades del Worker Role, en la sección de EndPoint agregamos uno como se muestra en la siguiente figura.

Paso 8: Crear página de búsqueda en el Web Role
Ahora vamos a trabajar en el Front End, es decir en el Web Role donde crearemos una página para poder realizar las búsquedas. En el proyecto FrontEndSolr agregar un nuevo Web Form que se llame busqueda.aspx. Marcar está nueva página como la página de inicio, para ello con el botón derecho sobre la misma seleccionar Set as Start Page.

A la página de búsqueda le agregamos 5 controles. Una caja de texto para las búsquedas, 3 botones para buscar, consultar la versión de java y hacer un ping respectivamente. Por último, el control literal para poder ver las respuestas de SOLR. Estos son los controles a agregar.

<strong>Buscador SOLR</strong><br />
        <asp:TextBox ID="TextBox1" runat="server" Width="303px"></asp:TextBox>
        <br />
        <asp:Button ID="btBuscar" runat="server" Text="Buscar" OnClick="btBuscar_Click" />
        <asp:Button ID="btJava" runat="server"  Text="Java Version" OnClick="btJava_Click" />
        <asp:Button ID="btPing" runat="server"  Text="Ping" OnClick="btPing_Click" />
        <br />
        <br />
        <asp:Literal ID="Literal1" runat="server" EnableViewState="False" Mode="PassThrough"></asp:Literal>

Paso 9: Implementar consulta de versión de Java a SOLR.
Vamos a partir con una consulta sencilla a SOLR, le vamos a preguntar desde el FrontEnd qué versión de Java está corriendo. Para ellos debemos enviar la siguiente petición a SOLR

http://localhost:8983/solr/admin/get-properties.jsp

Ahora la dirección 127.0.0.1 puerto 8983 no podemos utilizarla ya que cuando hagamos deploy de nuestra solución Web Role y Worker Role corren en VM diferentes por lo que tienen direcciones diferentes. Ahora, nosotros no sabemos las direcciones que nos van asignar por lo cual debemos implementar un método que nos permita obtener la dirección de SOLR de manera dinámica. Este método lo implementaremos en WebRole.cs ya que utiliza RoleEnviroment para acceder a la información de los roles e instancias que se están ejecutando.

public static string getSolServiceAddress()
{
    return RoleEnvironment.Roles["SolrService"].Instances[0].InstanceEndpoints["httpSolr"].IPEndpoint.ToString();
}

Ahora podemos implementar la consulta de la versión de java de esta manera

protected void btJava_Click(object senderEventArgs e)
{
    //Dirección de SolrService
    string urlTarget = WebRole.getSolServiceAddress();
    string solrURL = string.Format("http://{0}/solr/admin/get-properties.jsp"urlTarget);
    //Ejecuta la llamada HTTP
    string respuesta = this.CommandSolr(solrURL);
    Literal1.Text = string.Format("<H3>{0}</h3><PRE>{1}"urlTargetServer.HtmlEncode(respuesta));
}

Donde CoomandSolr es un método auxiliar que realiza la llamada a SOLR, utilizando la clase WebRequest. El método es el siguiente y se utilizará para todas las consultas

private string CommandSolr(string url)
{
    string responseFromServer;
    WebRequest request = WebRequest.Create(url);
    // If required by the server, set the credentials.
    request.Credentials = CredentialCache.DefaultCredentials;
    try
    {
        // Get the response.
        WebResponse response = request.GetResponse();
        // Display the status.
        Console.WriteLine(((HttpWebResponse)response).StatusDescription);
        // Get the stream containing content returned by the server.
        Stream dataStream = response.GetResponseStream();
        // Open the stream using a StreamReader for easy access.
        StreamReader reader = new StreamReader(dataStream);
        // Read the content.
        responseFromServer = reader.ReadToEnd();
        // Clean up the streams and the response.
        reader.Close();
        response.Close();
    }
    catch (Exception X)
    {

        responseFromServer = X.Message.ToString();
    }
    return responseFromServer;

Paso 10: Comprobar la consulta de versión de Java a SOLR. Para comprobar que nuestra implementación está correcta, vamos a ejecutar el proyecto en modo Debug y validar que podemos consultar la versión de Java. Al presionar el botón «Java Versión» de la página busqueda.aspx obtendremos una respuesta como la que se muestra en la siguiente imagen. La dirección que aparece al principio de la respuesta, es la dirección asignada dinámicamente del EndPoint interno que definimos. En este caso 127.255.0.1:8983

Paso 11: Implementar comando Ping y búsqueda a SOLR

La implementación del comando Ping es simplemente llamar a la URL siguiente, por lo que implementaremos un método similar al anterior.

http://localhost:8983/solr/admin/ping

El método que utilizaremos es

protected void btPing_Click(object senderEventArgs e)
{
    //URL de Consulta 
    string urlTarget = WebRole.getSolServiceAddress();
    string solrURL = string.Format("http://{0}/solr/admin/ping"urlTarget);
    string respuesta = this.CommandSolr(solrURL);
    Literal1.Text = string.Format("<H3>{0}</h3><PRE>{1}"urlTargetServer.HtmlEncode(respuesta));
}

Ahora de manera equivalente, para la búsqueda tenemos que insertar el texto a buscar en la URL que se llama.

protected void btBuscar_Click(object senderEventArgs e)
{
    if (TextBox1.Text == "")
    {
        Literal1.Text  = "no puede ser en blanco";
    }
    else
    {
        string urlTarget = WebRole.getSolServiceAddress();
        string solrURL = "http://{0}/solr/select/?q={1}&version=2.2&start=0&rows=10&indent=on";
        string q = Server.HtmlEncode(TextBox1.Text);
        string respuesta = this.CommandSolr(string.Format(solrURL,urlTargetq));
        Literal1.Text = string.Format("<H3>{0}</h3><PRE>{1}"urlTargetServer.HtmlEncode(respuesta));
    }
}

Paso 12: Comprobar el resultado de los comandos Ping y búsqueda
Ejecutamos el proyecto en modo debug, y comprobamos los dos nuevos comandos. La respuesta a Ping es la siguiente.

Por último, la respuesta a la búsqueda de la palabra USB es la siguiente.

Al cierre
La ejecución de servicios como SOLR es perfectamente posible en Windows Azure, utilizando Worker Role. Existen varias consideraciones que tener en cuenta en este tipo de soluciones, por ejemplo como podemos hacer escalar esto. Cómo podemos tener múltiples Worker Role ejecutando Soler y desde el Front End implementar alguna suerte de balanceo de carga para la llamadas. Ese será el próximo post!

Otro ejemplo de servicio Java corriendo en Azure es Deploying Java Applications in Azure de Mario Kosmiskas, donde explican cómo correr JETTY en Azure y que yo leí para resolver la pregunta del post.

El código del proyecto pueden bajarlo desde el siguiente link, este es un ejemplo que tiene el propósito de ilustrar el ejemplo y no es para ser puesto en producción.

Nube Privada

Esta es la presentación de nube privada con tecnologías de Microsoft, la que hicimos con Wilson en el evento Microsoft Now.

Otros post sobre cloud y  Azure:

Curso introductorio a Nube Privada con System Center 2012

La semana pasada participé de un curso introductorio de Nube Privada con System Center 2012.

 Es un curso introductorio que pasa por los tópicos más importantes al momento de diseñar e implementar una nueve privada. Muy recomendado!

 El temario del curso fue

  • Introduction to the Microsoft Private Cloud with System Center 2012
  • Configure & Deploy Infrastructure Components
  • Configure & Deploy the Private Cloud Infrastructure
  • Configure & Deploy Service Delivery & Automation
  • Configure & Deploy Application Management
  • Monitor & Operate Infrastructure Components
  • Monitor & Operate the Private Cloud Infrastructure
  • Monitor & Operate Service Delivery & Automation
  • Monitor & Operate Application Management

 Los videos de las sesiones están disponibles en el siguiente link:

 Private Cloud Jump Start

 Otros post relacionas con Cloud

Estudio de rendimiento de Microsoft Dynamics CRM 2011

Microsoft Dynamics CRM 2011 está diseñado para ayudar a las organizaciones empresariales a alcanzar una visión de 360 grados de los clientes, lograr una adopción de usuarios confiable, adaptarse rápidamente a los cambios del negocio y acelerar la ejecución de proyectos , todo en una plataforma que proporciona niveles de escalabilidad y rendimiento adecuados para la empresa.

En la dimensión del rendimiento aquí hay una buena prueba de desempeño sobre servidores DELL. El escenario de pruebas es exigente, con 150 mil usuarios concurrentes y unas 700 mil transacciones por hora. La siguiente tabla muestra los detalles

Concurrent Users* Average Response Time Web Requests Business Transactions Average SQL Server Utilization Average CRM Server Utilization
150,000 .4 seconds 5.5 M/hr 703,080/hr 39.6% 42%

El entorno de hardware utilizado para esta prueba de rendimiento se ilustra en el siguiente  diagrama.

El estudio complete pueden descargarlos desde el siguiente Link:

 Microsoft Dynamics CRM 2011 Performance and Scalability on Intel Xeon Processor-based Dell Servers with Solid-State Drives

Otros Post sobre Performance Test

Internet Explorer 6 en Windows 7, walkaround

La semana pasada estuve en un banco gigante comparado con los de mi pueblo, quienes me plantearon un problema con sus aplicaciones legadas. 

Desarrollaron hace algunos años muchas aplicaciones de intranet utilizando ASP y JavaScript. Son extensas aplicaciones, las cuales no funcionan bien en las nuevas versiones de IE. Ellos no quieren actualizar las aplicaciones, por lo que buscan alguna solución alternativa para poder migrar sus estaciones de trabajo desde XP a Windows 7 sin afectar este grupo de aplicaciones.  

Con ese problema en mente, busqué una solución de plataforma y llegué a la virtualización de aplicaciones. La idea es virtualizar IE6 para que corra de manera desacoplada del sistema operativo, y así dar la libertas de migrar desde Windows Xp a Windows vista (j aja) o Windows 7 sin problemas.

 Este es el resultado de la virtualización, Internet Explorer 8 e Internet Explorer 6 side by side en Windows 7.

Para está virtualización de aplicaciones utilicé VMware Thinapp y un Windows XP, sistema operativo que trae Internet Explorer 6.

El procedimiento a seguir es

1. En una máquina virtual con XP iniciar el preScan de Thinapp
2. En las opciones de instalación de aplicaciones, la opción “internet explorer”, seleccionar la opción Full.

3. Ejecutar el Post Scan
4. Dejar el entry point por defecto

5. No incluí Mange with Horizon
6. Permisos para todos, solo es una prueba. En producción debería ser administrado esto

7. Acceso restringido, para evitar escritura fura del sandbox

8. En la definición de Sandbox utilizaré el mismo directorio de la aplicación para así poder distribuirla en un pendrive o un medio compartido. Esto es notable de la virtualización de aplicaciones

9. Siguiente, en las estadísticas de calidad de Thinapp. Eso depende de cada uno 😉
10. No agregue URL para redirección nativa del Browser.
11. Nombres por defecto del paquete de software

12. Nombre de la aplicación virtualizada y su carpeta de almacenamiento

13. Listo, grabar el proyecto
14. Hacer el Build y finish
15. El resultado final

Otros post relacionados:

Reingeniería en Windows 8 para redes móviles

En este post se explican en profundidad las mejoras realizadas en Windows 8 en redes inalámbricas para optimizarlas tanto en redes wifi como en broadband. En esta última, por supuesto soporta conectividad 3G y 4G.

Algunos tips de las mejoras, como introducción a la lectura del articulo

Modo Airplane

 

Reucción en el tiempo de conexión

 

Datos de información de consumo de red  en el Administrador de tareas de Windows

Pueden leer el articulo en el siguiente link:

Engineering Windows 8 for mobile networks

Otros Post relacionados:

1. Windows 8: nueva caracteristica Storage Spaces

Windows 8: nueva caracteristica Storage Spaces

Una nueva característica de Windows 8 es Storage Space, que permite crear un disco virtual con un poll de discos físicos. Esto quiere decir que uno puede crear una unidad lógica, que está formada por uno o más discos físicos que estén en la red del Hogar u oficina.

 

Storage Space tiene dos caracteristicas, muy conocida en los Storage de clase mundial como Equalogic, que lo hacen muy interesante.

 Primero thin provisioning que permite crear discos lógicos de capacidades superiores al almacenamiento fisico de los discos del pool.

 Segundo resiliency para la seguridad de los datos, todos los datos almacenados son copiados al menos una vez en discos diferentes del pool para evitar perdida de datos aunque un disco físico del pool  se malogre.

Para conocer en detalle como funciona Storage Space pueden leer este post:

Virtualizing storage for scale, resiliency, and efficiency