3 optimizaciones simples para arquitecturas AngularJS + Java MVC REST

/ / Arquitectura, Blog, Digital Development
Descubre todo lo que traerá Alfresco 5.2
keensoft participa en las jornadas de Software Libre para bibliotecas

Las arquitecturas actuales para aplicaciones web suelen incluir una capa de AngularJS para el interfaz de usuario y una capa de Spring Boot para los servicios REST. Por ejemplo, el cada vez más utilizado framework JHipster sigue un patrón equivalente.

En este artículo, partiendo de la arquitectura de referencia que se describe en el gráfico superior, vamos a analizar tres sencillas optimizaciones que nos permitirán agilizar los tiempos de respuesta de la aplicación sin esfuerzo.

Para ello, hemos preparado un laboratorio de prueba en nuestra propia máquina de desarrollo mediante la herramienta Docker Compose.

Partimos como base de un método findAll que devuelve todas las filas de una tabla grande. De esta manera, al tener un tiempo alto, podemos medir mejor el impacto de nuestras modificaciones en la respuesta de la aplicación.

 

0-initial-time

 

  • Tiempo: 47,47 segundos
  • Tamaño: 21,6 MB

 

1. Añadiendo índices a la base de datos

En ocasiones, cuando utilizamos abstracciones JPA, olvidamos que detrás de todos estos objetos Java van a ejecutarse sentencias SQL en una base de datos. Y que esta base de datos necesita utilizar índices para optimizar sus tiempos de respuesta.

Declaramos el índice en la capa de entidades de JPA

@Entity
@Table(name = "element")
public class ElementEntity {

	@ManyToOne(optional = false)
	@JoinColumn(name = "category", foreignKey = @ForeignKey(name = "FK_CATEGORY_ELEMENT"))
        @Indexed
	private CategoryEntity category;

}

Creamos el índice en la base de datos

CREATE INDEX element_category ON ELEMENT(CATEGORY);

Verificamos el rendimiento de la aplicación una vez realizada esta operación y ya podemos observar una mejoría notable.

 

1-db-indexes

 

  • Tiempo: 40,88 segundos
  • Tamaño: 21,6 MB

 

2. Añadiendo cachés en la capa de servicios

De manera habitual, existen partes de las aplicaciones web que son utilizadas la mayoría del tiempo en modo lectura. En estos casos resulta muy conveniente utilizar el mecanismo de Cache de Spring junto con un gestor de caché como Hazelcast, lo que nos garantiza que muchas de las invocaciones no llegarán a la capa de base de datos, puesto que serán servidas directamente por este mecanismo.

Hay que tener algunas precauciones cuando se aplica este método:

  • Hay que vigilar el consumo de memoria estática de la aplicación, ya que si cacheamos muchos datos el heap aumentará de manera significativa
  • Hay que invalidar la caché cuando se realizan operaciones de modificación sobre el DTO que estamos cacheando

Definimos la caché en el servicio

@Service
public class ElementServiceImpl {
	
    @Cacheable("elementService.findAll")
    @Transactional
    public List<ElementDto> findAll() {
    }

    @CacheEvict(value = { "elementService.findAll" }, allEntries = true)
    @Transactional
    public void delete(Long id) {
    }

    @CacheEvict(value = { "elementService.findAll" }, allEntries = true)
    @Transactional
    public ElementEntity save(ElementDto elementUpdated) {
    }

}

Como vemos, tras aplicar esta técnica, hemos obtenido una mejora muy significativa del tiempo de respuesta.

 

2-cache-hazelcast

 

  • Tiempo: 13,84 segundos
  • Tamaño: 21,6 MB

 

3. Comprimiendo las respuestas JSON

No obstante, aún podemos hacerlo mejor. En este tipo de aplicaciones, la capa de AngujarJS suele consumir un elevado volumen de datos JSON para poder realizar operaciones en cliente de manera efectiva. Como observamos, en este caso estamos enviando una respuesta de 21,6 MB.

Para disminuir el tráfico de red, podemos incluir una directiva en Apache HTTPd para que los contenidos JSON sean comprimidos antes de ser enviados.

Establecemos la compresión en la configuración de Apache

AddOutputFilterByType DEFLATE application/json
DeflateCompressionLevel 7
DeflateMemLevel 8
DeflateWindowSize 10

Como se observa en nuestras pruebas, el tiempo sigue disminuyendo al enviar menos datos al cliente.

 

3-apache-compress

 

  • Tiempo: 6,49 segundos
  • Tamaño: 4,5 MB

 

Conclusiones

En este laboratorio, hemos conseguido optimizar un servicio REST tanto en tiempo como en tráfico de red.

  • Desde 47,47 segundos a 6,49 segundos
  • Desde 21,6 MB a 4,5 MB

Para ello, únicamente hemos aplicado tres técnicas fundamentales que pueden ser incorporadas de una manera sencilla:

  • Índices en la base de datos y la capa de JPA
  • Caché en la  capa de Servicios
  • Compresión en la capa web

Pueden aplicarse mecanismos de optimización más complejos, pero nunca conviene perder de vista las técnicas básicas para conseguir un funcionamiento efectivo de nuestras aplicaciones.

Unidad de negocio, keensoft

2 Comments to “ 3 optimizaciones simples para arquitecturas AngularJS + Java MVC REST”

  1. Carlos Pompa dice:

    Muy bueno el artículo ANGEL!. Gracias!
    Saludos. Carlos.

  2. Y sin paginar! , gracias, solo tendre que ver como hago para habilitar la compresion en el WAS