Desarrollo de Java 2.0: Confirmar en Git sus aplicaciones de Java con PaaS de Heroku

Heroku extiende sus raíces de Ruby para escalabilidad de aplicaciones de Java

Heroku es una opción de PaaS que realmente ofrece algo nuevo al panorama de desarrollo de Java™— en parte porque su lenguaje nativo (y su pensamiento) es Ruby. Heroku combina el enfoque flexible y que prioriza la diversión de Ruby para el desarrollo de aplicaciones con el modelo de implementación inteligente y distribuido de Git, haciendo a ambos accesibles para los desarrolladores de Java mediante bibliotecas conocidas de Java. En esta instalación de desarrollo de Java 2.0, Andrew Glover construye una nueva encarnación de esta aplicación móvil y basada en la ubicación, usando Apache Wink, Jetty y Maven; después la despliega en Heroku usando la infraestructura escalable y de alta eficiencia de Git.

Andrew Glover, CTO, App47

Andrew Glover es un desarrollador, autor, ponente y emprendedor apasionado por el desarrollo impulsado por el comportamiento, la Integración Continua y el desarrollo de software de Agile. Es el fundador de la infraestructura de Desarrollo Impulsado por el Comportamiento (BDD) easyb y es el co-autor de tres libros: Continuous Integration, Groovy in Action y Java Testing Patterns. Puede estar al tanto de su trabajo en su blog y siguiéndolo en Twitter.



30-04-2012

IBM en la nube

Para aprender más sobre la presencia de IBM en la nube, sólo tiene que ver IBM SmartCloud Application Services, una plataforma de aplicación entregada como un servicio. Encontrará detalles sobre lo siguiente:

  • Servicios de Aplicación: Servicios listos para ejecutarse y de nivel empresarial para colaboración, analítica y gestión de procesos empresariales
  • Ciclo de Vida de la Aplicación: Tecnologías que permiten la colaboración y automatización del desarrollo de aplicaciones, mientras proporcionan visibilidad mediante el ciclo de vida de la aplicación
  • Servicios de Integración: Integración de datos, aplicaciones y servicios simple y con seguridad enriquecida en los entornos de la nube, entregada con una capa unificada de gestión de servicio
  • Servicios de Carga de Trabajo: Servicios de optimización de rendimiento, desde aplicaciones hasta patrones de carga de trabajo, que ayudan a asegurar la calidad del servicio y la disponibilidad, mientras soportan movilidad de la carga de trabajo y tenencia múltiple a través de las nubes

Y no se pierda las rutas de conocimiento de la nube de developerWorks para una verdadera construcción de habilidades.

Los artículos recientes en la serie de desarrollo de Java 2.0 se han enfocado en opciones de PaaS (Plataforma como un Servicio) para el desarrollo de Java. Esta vez lo invito a ver Heroku, otro sistema popular de PaaS recientemente extendido para soportar aplicaciones de Java.

Con raíces en Ruby, el enfoque de Heroku para el desarrollo y implementación de aplicaciones de Java es decididamente distinto de lo que pudo haber experimentado con otras opciones de PaaS de Java, notablemente con Elastic Beanstalk de Amazon y Google App Engine (GAE). Antes de pasar a una introducción práctica de Heroku, creo que puede ser útil observar lo que tiene en común con estas dos plataformas, así como en qué es distinto.

GAE y Beanstalk: dos tipos de objetos pesados

Como aprendimos en artículos anteriores de esta serie, Google App Engine y Elastic Beanstalk de Amazon son polos opuestos en términos de flexibilidad. Mientras que GAE es un recinto de seguridad bastante estrecho que le obliga a jugar con sus reglas, Elastic Beanstalk es completamente personalizable: si se ejecuta en la JVM, PaaS de Amazon le permite usarlo. GAE restringe sus opciones de bibliotecas de Java y también controla en su mayoría la forma en la que se escala su aplicación. De hecho, desplegar aplicaciones en GAE es un ejercicio que cada vez se usa menos: no sabrá dónde reside su aplicación web o incluso cuántas instancias de aplicación están vivas. En el lado positivo, Google hace todo el escalamiento por usted, y no hace falta decir que las aplicaciones de GAE se escalan bastante bien. Liberar el control significa que no tiene mucho de qué preocuparse, además de escribir un código sólido, por supuesto.

Sobre esta serie

El panorama de desarrollo de Java ha cambiado radicalmente desde que la tecnología de Java surgió por primera vez. Gracias a infraestructuras maduras de código abierto y de infraestructuras de implementación confiables en renta, ahora es posible ensamblar, probar, ejecutar y mantener aplicaciones de Java rápidamente y a bajo costo. En esta serie, Andrew Glover explora el espectro de tecnologías y herramientas que hacen que este nuevo paradigma de desarrollo de Java sea posible.

Amazon's Elastic Beanstalk está en el otro lado del ring. Además de darle su selección de herramientas, permite un increíble control sobre la forma en que se escala la aplicación. La desventaja de esto es obvia: si participación práctica, Amazon hace muy poco por usted. Aún así, si desea afinar su implementación de aplicaciones y desea una infraestructura altamente escalable, Elastic Beanstalk de Amazon es una apuesta segura.

Dada una escala de facilidad de uso que abarque la codificación y la implementación, con un rango de 10 a 0 (10 siendo lo más difícil y 0 lo más sencillo), yo le daría a GAE un 4 y a Elastic Beanstalk un 6. GAE me permite ejecutar un script y subir archivos sin problemas, pero la gama limitada de herramientas de desarrollo compatibles algunas veces no va con mi estilo. Por el contrario, Elastic Beanstalk me permite usar cualquier biblioteca que quiera, pero el camino para el desarrollo es más largo y algunas veces tedioso; yo prefiero un poco de complejidad a cambio de tener más control.

Heroku el retador

Igual que GAE y Elastic Beanstalk, Heroku está construido para escalarse en forma horizontal. Usted despliega su código en lo que Heroku llama dynos, los cuales básicamente son contenedores web. Si desea escalar su sistema, simplemente añada más dynos, permitiendo así a Heroku manejar más solicitudes web simultáneas. Es un concepto simple que proporciona más control que GAE sin los requisitos configuración de Elastic Beanstalk.

Ruby y Heroku

Aunque Heroku comenzó dirigiéndose hacia la comunidad de Ruby, — ¡su compañía padre incluso emplea al creador de Ruby! — Heroku ha sido recientemente extendido para soportar Clojure, Node.js y el lenguaje de Java. Aunque el primer enfoque en Ruby (y la línea de comandos de Ruby) de Heroku puede ser poco atractivo para algunos desarrolladores de Java, creo que tiene algunas diferencias positivas. En particular, el modelo de implementación basado en Git de Heroku hace que compilar y escalar aplicaciones web basadas en la nube sea simple y divertido.

En Heroku, Git — no Ant o Maven — es su interconexión de implementación. Cuando esté listo para desplegar su aplicación, hágalo mediante un empuje de Git, algo que discutiré a profundidad más adelante en este artículo.

Como en la comparación de GAE y Elastic Beanstalk en la facilidad de uso, Heroku es un 2, lo que significa que es bastante sencillo. Heroku me da una gran flexibilidad en términos de herramientas, así que puedo elegir las herramientas más productivas para cualquier trabajo dado. En términos de configuración, Heroku permite más control que GAE, pero menos que Elastic Beanstalk — lo que algunas veces es justo lo necesario. También es fácil llevar una compilación de aplicación de Heroku a Elastic Beanstalk: si alguna vez necesito un control de grano más fino sobre la escalabilidad de una aplicación, ¡yo sé que simplemente puedo moverla!


Iniciándose con Heroku

Para iniciarse con Heroku, necesitará instalar y configurar lo siguiente:

Tome en cuenta que Maven no es requerido para Heroku; sólo la estoy usando como mi herramienta de compilación. La documentación de Java de Heroku también está basada en Maven.

Compilar y ejecutar la aplicación

Una vez que tenga todo instalado, elija el directorio en el que estará trabajando y ejecute el siguiente comando de Maven (código roto para acomodar el ancho de página):

mvn archetype:generate -DarchetypeGroupId=org.mortbay.jetty.archetype 
  -DarchetypeArtifactId=jetty-archetype-assembler -DarchetypeVersion=7.5.0.RC0

Creando puntos finales de REST

Wink resulta ser una de las pocas bibliotecas disponibles para la creación de aplicaciones de RESTful. En artículos anteriores, he creado dichas aplicaciones usando Play y Gretty, los cuales hacen más que Wink para facilitar el proceso de crear puntos finales de RESTful. Elijo Wink porque Play es una infraestructura de pila completa, que en este caso es más de lo que necesito. Y Gretty es demasiado ligero y puede no ser suficiente para lo que quiero. Wink no hace paquete con un contenedor de Servlets ni contiene una infraestructura de ORM — todo lo que hace es compilar recursos de RESTful. En este caso, decidió que la especialización era algo bueno.

Maven le solicitará proporcionar un groupId y un artifactId. Normalmente yo uso el nombre de mi paquete para groupId y el nombre de mi proyecto para artifactId. Maven entonces generará una estructura de proyecto capaz de compilar y ejecutar una aplicación web sobre Jetty. Así, en una etapa, tiene el esqueleto de una aplicación web lista para ser desplegada en la infraestructura de la nube de Heroku. Aunque Jetty es el arquetipo de Maven usado, Heroku no sólo soporta Jetty en el lado del servidor web. De hecho, Heroku ni siquiera sabe sobre Jetty — ni le interesa.

La aplicación predeterminada generada por el comando de Maven anterior es su típica aplicación "hello world". De hecho, si va hacia el directorio src de la aplicación, seguido por main—>webapp, verá un archivo index.html . Ejecute la aplicación y el archivo imprimirá (como probablemente ya ha adivinado) el texto "hello world."

Ejecutar la aplicación también es fácil. Si escribe el comando mvn install en su directorio de proyecto recién generado (que tiene el nombre que dio para artifactId), un script de shell será generado para su sistema operativo deseado (el mío es OSX). Simplemente escriba $>sh target/bin/webapp, después vaya a http://localhost:8080 en su navegador preferido y prepárese para ser recibido.


Heroku en el mundo real

Con Heroku, puede desplegar cualquier biblioteca que desee. En aras de este ejemplo y la familiaridad — al menos para aquellos de ustedes que han estado leyendo durante un tiempo ya — voy a compilar otra encarnación de mi servicio web móvil de recolección de ubicaciones, Magnus, el cual debutó en mi introducción a Elastic Beanstalk de Amazon (vea Recursos). Para mi biblioteca de RESTful, voy a usar Apache Wink, que es una implementación de la especificación JAX-RS. Mi implementación de servicio web proporcionará un punto final PUT que acepte JSON e inserte datos relevantes obtenidos del documento en una instancia de MongoDB. Eso, aso vfez, será alojado en MongoHQ, mediante Morphia (vea Recursos).

Lo primero que tengo que hacer es actualizar el archivo pom.xml de Maven de Magnus con las nuevas dependencias de Wink y Morphia, como se muestra en el Listado 1:

Listado 1. Añadiendo Wink y Morphia a un POM de Maven
<dependency>
 <groupId>org.apache.wink</groupId>
 <artifactId>wink-server</artifactId>
 <version>1.1.3-incubating</version>
</dependency>

<dependency>
 <groupId>org.apache.wink</groupId>
 <artifactId>wink-json-provider</artifactId>
 <version>1.1.3-incubating</version>
</dependency>

<dependency>
 <groupId>com.google.code.morphia</groupId>
 <artifactId>morphia</artifactId>
 <version>0.99</version>
</dependency>

Note que también actualizo mi archivo de POM para observar dentro del repositorio de Maven de Morphia y obtener la versión 0.99:

Listado 2. Añadiendo un nuevo repositorio a un POM de Maven
<repositories>
 <repository>
  <id>morphia repository</id>
  <url>http://morphia.googlecode.com/svn/mavenrepo/</url>
 </repository>
</repositories>

Después, creo un recurso de ubicación — un punto final de Wind que representará las ubicaciones del usuario:

Listado 3. Creando un LocationResource de Wink
@Path("/location")
public class LocationResource {

 @PUT
 @Consumes(MediaType.APPLICATION_JSON)
 @Path("{id}")
 public String updateAccountLocation(@PathParam("id") int accountId, JSONObject 
  requestJSON) {
  try{

   double latitude = Double.parseDouble(requestJSON.get("latitude").toString());
   double longitude = Double.parseDouble(requestJSON.get("longitude").toString());

   SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm");
   Date dt = formatter.parse(requestJSON.get("timestamp").toString());

   new Location(accountId, dt, latitude, longitude).save();
   return new JSONObject().put("status", "success").toString();
  }catch(Exception e){
   return "failure with " + requestJSON;
  }
 } 
}

Wink me hace describir mi servicio de RESTful mediante tres anotaciones: una para mi método de HTTP (PUT), otra para mi tipo de contenido de solicitud esperado (JSON) y la última para indicar que el punto final acepta un parámetro (en este caso location/:accountId).

Esta clase Location es el mismo objeto respaldado por Morphia presentado en mi introducción a Elastic Beanstalk. Simplemente crea un documento en MongoHQ que representa una ubicación para una cuenta dada. La ubicación (teóricamente recibida de un dispositivo móvil) es representada por el parámetro del punto final de RESTful.

Wink y Jetty

A continuación, quiero unir a Wink con Jetty, así que necesito hacer dos cosas: crear una clase Application y configurar algunas cosas en mi archivo web.xml .

El propósito de la clase Application de Wink (mostrado en el Listado 4) es cargar las clases de recurso correspondientes:

Listado 4. Una clase Application de Wink
public class MarmarisApplication extends Application {
 @Override
 public Set<Class<?>> getClasses() {
  Set<Class<?>> classes = new HashSet<Class<?>>();
  classes.add(LocationResource.class);
  return classes;
 }
}

En el Listado 5, actualizo el archivo web.xml de mi aplicación, añadiendo atributos específicos para Wink, tales como un apuntador para mi clase Application y mi patrón de URL deseado, el cual en este caso es /service/resource:

Listado 5. Uniendo a Wink mediante web.xml
<servlet>
 <servlet-name>MarmarisApp</servlet-name>
 <servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
 <init-param>
  <param-name>javax.ws.rs.Application</param-name>
  <param-value>com.b50.marmaris.MarmarisApplication</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
 <servlet-name>MarmarisApp</servlet-name>
 <url-pattern>/service/*</url-pattern>
</servlet-mapping>

Como una prueba, intente volver a ejecutar el comando mvn install e inicie la aplicación (en este caso Magnus) localmente. Debe poder enviar un documento de JSON (mostrado en el Listado 6) al punto final http://localhost:8080/service/location/{account_id}, donde account_id es un número.

Listado 6. Un documento de JSON representando una ubicación
{
 "name":"location payload",
 "latitude":"46.49",
 "longitude":"71.11",
 "timestamp":"09-02-2011 14:43"
}

Escribir esta aplicación no fue difícil, y ahora estamos listos para la parte que es aún más fácil: ¡desplegarla en la nube de Heroku!


Heroku y Git

La interconexión de implementación de Heroku es Git, lo que puede requerir algunos ajustes si no está familiarizado con el control de versión distribuido. Desplegar en Heroku (mediante Git) es similar a emitir una confirmación Subversión en una ramificación distinta de la línea principal. Pero en este caso, Heroku no es el repositorio de código principal; es sólo un repositorio remoto alternativo. Para desplegar una aplicación, usted empuja su código de origen mediante Git.

Tome en cuenta que más que desplegar archivos de war, Heroku lo hace desplegar su proyecto como está. Como verá cuando comencemos a compilar el Procfile de nuestra aplicación, Heroku es sólo una JVM que busca algo de código para ejecutar. (Si desea ver en este momento de lo que estoy hablando, vea el archivo Main.java generado en la infraestructura de paquete de su proyecto, después correlacione su entrada en su POM.)

Un consejo para Git

Si es un usuario de Github, puede pensar en Heroku simplemente como otro repositorio en el cual empuja las ramificaciones deseadas en su base de código, tal como el desarrollo, QA o la transferencia.

Aunque no es inmediatamente intuitivo, el modelo de desarrollo de Heroku tiene sentido una vez que comienza a utilizarlo. Más aún, la estrecha integración de Heroku con Git hace que empujar diversas ramificaciones hacia distintos entornos sea rápido y sencillo.

Implementación de dos fases

La configuración de la implementación sucede en dos etapas: primero, necesita crear y confirmar su código en un repositorio de Git local. Puede hacer esto en el directorio de raíz de su proyecto, al escribir los comandos en el Listado 7 en un terminal:

Listado 7. Inicialización y confirmación de Git
$> git init
$> git add .
$> git commit -m "initial commit before Heroko deployment"

Ahora su repositorio de Git local tiene una instantánea de su código (es decir, que el código ha sido versionado).

A continuación, creará una aplicación en Heroku. Lo he hecho en el Listado 8 mediante el cliente de línea de comandos heroku (aquí es donde es esencial que tenga Ruby y RubyGems instalados):

Listado 8. Creando una aplicación de Heroku
$> heroku create marmaris --stack cedar

El comando heroku create en el Listado 8 crea una aplicación llamada "marmaris" en la pila de cedar. Note que tendrá que elegir un nombre de aplicación distinto, ya que ese ya ha sido elegido. Alternativamente, puede dejar el nombre en manos de Heroku, y generará uno exclusivo para usted.

Heroku tiene un número de pilas. Cedar soporta Java y Node.js, mientras que otros (como Bamboo) soportan versiones más recientes de Ruby. Cuando ejecuta el comando heroku create , actualizará su configuración de Git y añadirá un repositorio remoto llamado heroku.

Procfile de Heroku

Antes de que pueda desplegar su base de código en Heroku, necesita decirle cómo ejecutar su aplicación. Esto es fácilmente realizado con un Procfile, que simplemente es un archivo de texto que indica un comando. Mi Procfile, mostrado a continuación, apunta hacia el script de shell webapp encontrado en mi directorio target .

Listado 9. Creando un Procfile
$> echo 'web: sh target/bin/webapp' > Procfile

Después de crear un nuevo archivo, es importante que notifique a Git; de otra manera Heroku no sabrá sobre él cuando implementación la aplicación mediante un empuje de Git.

Listado 10. Notificando a Git
$> git add Profile
$> git commit -m "updated to include my Profile"

Finalmente, para desplegar la aplicación, simplemente emitirá un empuje de Git en el repositorio remoto heroku , mostrado en el Listado 11:

Listado 11. Desplegando en Heroku
$> git push heroku

Debe ver una serie de mensajes retornados por heroku, pero busque aquel que dice algo como lo siguiente:

http://your_app_name.herokuapp.com deployed to Heroku

Ingrese ese URL en su navegador favorito y (asumiendo que ha dejado el archivo index.html predeterminado en su directorio del proyecto) verá una salida impresa de "hello, world!" .

Aunque "hello, world!" siempre es muy interesante, el propósito de esta aplicación era aceptar la información de ubicación mediante HTTP PUTs. Consecuentemente, usando RESTClient de WizTools.org, puedo emitir un HTTP PUT en mi punto final de RESTful, proporcionar un documento de JSON, ¡y listo! Envié una bonita respuesta de JSON con la fantástica palabra success.


Escalando y manteniendo Heroku

Heroku de forma predeterminada ejecuta su aplicación en un solo dyno. Este dyno, que es gratuito, esencialmente se desactiva en momentos de inactividad y se vuelve a activar cuando llega una solicitud. Si necesita escalar su aplicación, usted añade más dynos, lo que puede hacer mediante el comando heroku scale :

Listado 12. Escalando la aplicación
$> heroku scale web=2

Si llega a necesitarlo, también puede escalar hacia abajo una aplicación al reducir el número de dynos seleccionados. Por ejemplo, en este caso yo quisiera escalar hacia web=1. También puede hacer estas dos operaciones mediante la interfaz web de Heroku.

También puede perseguir registros en Heroku mediante el comando heroku logs en el Listado 13:

Listado 13. Viendo los registros en Heroku en tiempo real
$> heroku logs -t

El cliente de línea de comandosheroku soporta numerosos dispositivos para escalar, supervisar y gestionar su aplicación; vea Recursos para obtener documentación. Heroku también soporta muchos add-ons de terceros, además de un almacén de datos predeterminado. Yo recomiendo verificar el soporte de Heroku para MongoHQ y PostgreSQL.


En conclusión

Podcast: Adam Wiggins y Jesper Joergensen sobre Heroku

En este podcast, aprenda más sobre los inicios de Heroku, su soporte para múltiples idiomas y cómo iniciarse.

La estrecha integración de Heroku con Git presenta un nuevo paradigma para desplegar y escalar aplicaciones de Java mediante la nube, pero también hace que el proceso sea excepcionalmente sencillo y poderoso. Considerando todo, tener la libertad de usar bibliotecas de Java ilimitadas y después desplegar las aplicaciones resultantes casi sin esfuerzo es algo que definitivamente me agrada.

Recursos

Aprender

Obtener los productos y tecnologías

Comentar

  • Participe en la comunidad developerWorks. Conéctese con otros usuarios developerWorks mientras explora los blogs, foros, grupos y wikis dirigidos a desarrolladores.

Comentarios

developerWorks: Ingrese

Los campos obligatorios están marcados con un asterisco (*).


¿Necesita un IBM ID?
¿Olvidó su IBM ID?


¿Olvidó su Password?
Cambie su Password

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. La información en su propio perfil (nombre, país/región y nombre de la empresa) se muestra al público y acompañará a cualquier contenido que publique, a menos que opte por la opción de ocultar el nombre de su empresa. Puede actualizar su cuenta de IBM en cualquier momento.

Toda la información enviada es segura.

Elija su nombre para mostrar



La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Los campos obligatorios están marcados con un asterisco (*).

(Por favor elija un nombre de 3 - 31 caracteres.)

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


Toda la información enviada es segura.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=tecnologia Java, Cloud computing
ArticleID=811631
ArticleTitle=Desarrollo de Java 2.0: Confirmar en Git sus aplicaciones de Java con PaaS de Heroku
publish-date=04302012