Introducción a la programación reactiva con Vert.x. Esta presentación la utilicé en una charla para desarrolladores https://www.meetup.com/es-ES/Software-Crafters-Alicante/events/264365511/
6. ¿Qué es la programación reactiva?¿Qué es la programación reactiva?
Se refiere a un paradigma de programación enfocado
al tratamiento de flujos de datos de forma asíncrona
tal y como se recoge en el Reactive Manifesto
http://www.reactivemanifesto.org
7. Principios del Reactive ManifestoPrincipios del Reactive Manifesto
Responsivos
Resilientes
Elásticos
Orientados a Mensajes
12. Arquitectura del Manifiesto de SistemasArquitectura del Manifiesto de Sistemas
ReactivosReactivos
Responsive
Resilient
Message Driven
Elastic
Fuente: http://www.reactivemanifesto.org
14. ¿Qué es Vert.x?¿Qué es Vert.x?
Eclipse Vert.x ( ) es un conjunto de
utilidades (no un framework) basado en 2 conceptos
Diseño dirigido por los eventos
Es NO bloqueante
http://vertx.io
16. Características de Vert.xCaracterísticas de Vert.x
Muy ligero
Rápido
No es un servidor de aplicaciones
Modular
Sencillo pero no simplista
Ideal para microservicios
Buenísima documentación
18. Instalación de Vert.xInstalación de Vert.x
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk install vertx
19. Vert.x coreVert.x core
Clientes y servidores TCP
Clientes y servidores HTTP
Websockets
Event bus
Datos compartidos
Acciones periódicas
Desplegar verticles
Clientes DNS
Acceso al sistema de ficheros
Alta disponibilidad
Clustering
21. ¿Qué es el event loop?¿Qué es el event loop?
¿Tenemos algún evento que procesar?
Lo proceso y llamo a los handlers necesarios
Y así constantemente
Tantos hilos de event loop como número de
núcleos * 2
24. ¿Igual que Node.js?¿Igual que Node.js?
Node.js utiliza un único event loop mientras que Vert.x
utiliza un event loop por cada core multiplicado por
dos. Esto se conoce como Multi-Reactor Pattern.
25. La regla de oroLa regla de oro
!!No bloquees el event loop!!
26. Ejemplos de bloquear el event loopEjemplos de bloquear el event loop
Thread.sleep()
Costosas operaciones con bases de datos
Cálculos complejos que tarden mucho
27. Ejecutar código bloqueanteEjecutar código bloqueante
vertx.executeBlocking({ future ->
// Llama a métodos bloqueantes
def result = someAPI.blockingMethod("hello")
future.complete(result)
}, { res ->
println("The result is: ${res.result()}")
})
28. Talk is cheap, show me the codeTalk is cheap, show me the code
Fuente: Recruiting daily
29. Ejemplo: Hello world!Ejemplo: Hello world!
vertx run s01e01.groovy
import io.vertx.core.http.HttpServer
HttpServer httpServer = vertx.createHttpServer()
//Responder a cada petición con un Hello World!
httpServer.requestHandler({ request ->
// Este handler será llamado con una petición al servidor
request.response().end("hello world!")
})
httpServer.listen(8080)
30. Ejemplo: Devolviendo JsonEjemplo: Devolviendo Json
vertx run s01e02.groovy
import io.vertx.core.http.HttpServer
HttpServer httpServer = vertx.createHttpServer()
//Responder a cada petición con un Hello World!
httpServer.requestHandler({ request ->
String json = """{"foo":"bar"}"""
request.response()
.putHeader("Content-Type", "application/json")
.putHeader("Content-Length",json.size().toString())
.write(json)
.end()
})
httpServer.listen(8080)
33. VerticlesVerticles
Suponen el corazón de Vert.x
Aunque no estás obligado a utilizarlos
Una aplicación consiste habitualmente en
muchos verticles ejecutándose simultáneamente
en una instancia de Vert.x
38. Desplegando verticles de formaDesplegando verticles de forma
asíncronaasíncrona
vertx run s01e07.groovy
import io.vertx.core.Future
void vertxStart(Future future) {
vertx.deployVerticle("s01e06.groovy", { res ->
if (res.succeeded()) {
println "s01e06 started successfully asynchronously"
future.complete()
} else {
println "error starting s01e06 asynchronously"
future.fail("Error starting s01e06")
}
})
}
void vertxStop(Future future) {
39. Desplegando verticles de formaDesplegando verticles de forma
asíncronaasíncrona
vertx run HelloWorldHttpVerticleAsync.groovy
import io.vertx.core.AbstractVerticle
import io.vertx.core.Future
public class HelloWorldHttpVerticleAsync extends AbstractVerti
public void start(Future future) {
println "starting"
vertx.deployVerticle("s01e06.groovy", { res ->
if (res.succeeded()) {
println "s01e06 started successfully asynchronously"
future.complete()
} else {
println "s01e06 not started asynchronously due to an e
future.fail()
}
40. Desplegando verticles con variasDesplegando verticles con varias
instanciasinstancias
vertx run s01e08.groovy
vertx.deployVerticle("HelloWorldHttpVerticle.groovy", [instanc
42. Standard verticlesStandard verticles
Se asigna un event loop cuando se crean
Vert.x garantiza que cualquier código de estos
verticles siempre se ejecutará en el mismo event
loop
De esta forma, escribe tu aplicación como si fuera
monohilo que Vert.x ya se encargará de hacerlo
multihilo y de la escalabilidad
43. Worker verticlesWorker verticles
No utilizan el event loop
Utilizan un thread del pool de threads de Vert.x
Están diseñados para ejecutar código bloqueante
def options = [
worker:true
]
vertx.deployVerticle("MyFirstVerticle", options)
45. Event busEvent bus
Es el sistema nervioso de Vert.x
Un unico event bus para cualquier verticle
Es la mejor forma de comunicar verticles en Vert.x
46. ¿Cómo funciona el Event bus?¿Cómo funciona el Event bus?
Mandamos mensaje a una dirección, e.g.
europe.news.feed
Los mensajes son simples cadenas de texto
Los handlers reciben los mensajes, pero antes
habrá que registrarlos
Varios handlers pueden estar suscritos en una
misma dirección
Un mismo handler puede estar suscritos en varias
direcciones
48. Tipos de subscripción:Tipos de subscripción:
Publish/SubscribePublish/Subscribe
Todos los handlers suscritos a una dirección recibirán
el mensaje.
49. Tipos de suscripción: Punto a puntoTipos de suscripción: Punto a punto
Vert.x se encargará de que sólo un handler reciba el
mensaje. Se puede especificar incluso un reply
handler.
50. Tipos de mensajes en el event busTipos de mensajes en el event bus
Normalmente se utiliza Json, aunque no estamos
forzados a ello.
52. Ejemplo: Publish/SubscribeEjemplo: Publish/Subscribe
vertx run PublishingMessage.groovy
import io.vertx.core.http.HttpServer
def eventBus = vertx.eventBus()
eventBus.consumer("news.uk.sport", { message ->
println("EH1: I have received a message: ${message.body()}")
})
eventBus.consumer("news.uk.sport", { message ->
println("EH2: I have received a message: ${message.body()}")
})
HttpServer httpServer = vertx.createHttpServer()
httpServer.requestHandler({ request ->
53. Ejemplo: Punto a puntoEjemplo: Punto a punto
vertx run PointToPointExample.groovy
import io.vertx.core.http.HttpServer
def eventBus = vertx.eventBus()
eventBus.consumer("news.uk.sport", { message ->
println("EH1: I have received a message: ${message.body()}")
})
eventBus.consumer("news.uk.sport", { message ->
println("EH2: I have received a message: ${message.body()}")
})
HttpServer httpServer = vertx.createHttpServer()
httpServer.requestHandler({ request ->
54. Ejemplo: Respondiendo al eventoEjemplo: Respondiendo al evento
vertx run EventReplyExample.groovy
import io.vertx.core.http.HttpServer
def eventBus = vertx.eventBus()
eventBus.consumer("news.uk.sport", { message ->
println("I have received a message: ${message.body()}")
message.reply("Event received, thanks!")
})
HttpServer httpServer = vertx.createHttpServer()
httpServer.requestHandler({ request ->
eventBus.send("news.uk.sport", "Yay! Someone kicked a ball",
if (ar.succeeded()) {
request.response().end("This is what we received: "${ar
} else {
request.response().end("There was an error")
55. EjercicioEjercicio
Si sólo conocieramos Eclipse Vert.x, ¿como
diseñaríamos la arquitectura de un servicio para
registrar usuarios que necesita mandar un mail de
confirmación a través de un servicio externo y al
mismo tiempo el nuevo usuario debe ser añadido a
otro servicio externo?