vert.x Supporting tagline
Pourquoi vert.x
Pour répondre à 2 problèmes majeurs :
- C10K problem
- serveur push
Les solutions existantes
Les solutions thread driven
c’est une solution basée sur « un thread par Requète/Réponse ». C’est le paradigme des « anciens » frameworks WEB (> 2008). Il n’est particulièrement pas adapté au push server qui mobilise un grand nombre de connection ouvertes mais inactives (idle).
Les solutions event driven
TODO
Vert.x vs Node.js
Les problèmes de Node.js:
-
Le langage de programmation: Node ne supporte que JavaScript : pas besoin d’en dire plus!! Vert.x support plusieurs languages (polyglot programming), dont Java, Ruby, Python et même … JavaScript.
-
Le clustering vertical : c’est démarrer plusieurs instances sur la même machine. C’est donc la capacité à profité de tous les coeurs, de toute la RAM d’une machine. Node.JS etant mono-thread, il faut démarrer plusieurs node pour profiter de la puissance de la machine hote. Il faut alors utiliser
child_process.fork()
ou le module cluster. Le code devient plus « touchy ». Vert.x fournit les verticles pour répondre à se besoin et propose une API d’abstraction supérieure (moins de plomberie) à Node, donc plus facile à écrire/maintenir. - La communication interprocess: Avec tous ces instances exécutant du cote de manière complétement isolées les une des autres, comment organiser le travail.
Du coté de Node, on trouve :- TCP/UDP/UNIX Sockets
- Redis Pub/Sub (http://redis.io/)
- ZeroMQ (http://www.zeromq.org/)
- Process Signaling/Cluster Module
- Eventing Frameworks: Hook.io (dead), JSSignals, Bean, etc.
- Memcached
- Etc…
Vert.x proose quand à lus l’event bus.
-
L’ event loop.
Node est une implémentation du pattern Reactor
Les caractéristiques du pattern reactor:- Single thread / single event loop
- EVERYTHING runs on it
- You MUST NOT block the event loop
Node est donc adapté au traitement NIO (non-blocking IO).
Mais les caractéristique vues ci-dessus sont souvent incompatibles avec nos applications. Nous voulons plusieurs threads car nous travaillons avec des I/O bloquantes (ex: JDBC), des calculs couteux, etc. Si nous le faisons dans Node.JS, nous bloquons l’event loop, et c’est le drame!!
Il faudrait donc qu’il y ai du multi-threading sur Node.JS => le seul moyen serait de hacker la V8!
=> Nous ne voulons pas faire ça !!
La solution proposer par vet.x : les worker verticles.
Les concepts de Vert.x
Verticle (Atomic Particule)
Un verticle correspond à une unité de traitement dans le monde de vert.x.
Un traitement s’executera donc dans un verticle, un verticle ayant les caractéristiques suivantes:
- une instance de verticle est assignée à un unique thread/event loop de vert.x. Elle s’exécute toujours dans ce même thread.
- On peut écrire le code comme si il n’était pas concurrent (single thread), c.à.d sans synchronized, lock, ….
- une instance de verticle à un classloader isolé et ne peut pas partager d’état (variables globales, membres static, …).
Worker verticles
- Un Worker verticles n’est pas assigné à un vert.x thread/event loop
- S’execute dans un « background » thread pool.
- n’est jamais exécuté par plus d’un thread en même temps (pas de traitement concurrent).
- Ne peut pas utiliser les clients/serveurs TCP ou HTTP.
- Communique en utilisant l’ event bus.
Event Bus
L’event bus permet de traiter les problèmes:
- d’addressage** (addressing)
- d’enristrement de Handler sur le bus
- d’émission d’évenements (event) sur le bus
- de type de message echangés
addressage
les adresses sont de simples string, dont la profondeur d’adressage est géré par l’opérateur « . » messages.inbound.A
.
Enregistrement de Handler sur le bus
Permet de réagir/traiter par des handlers les evenements survenant sur le bus.
EventBus eb = vertx.eventbus();
...
Handler<Message> myHandler = new Handler<Message> () {
public void handle(Message message) {
System.out.println("received message : " + message.body);
}
};
eb.publish("test.address", "hello world !");
Emission d’évenements sur le bus
Plusieurs natures d’évenements peuvent être envoyés sur le bus.
Publisher/Subscriber
C’est du broadcast. Tous les handlers reçoivent l’événement.
EventBus eb = vertx.eventbus();
...
eb.publish("test.address", "hello world !");
Peer to peer : Un seul handlers peut recevoir l’événement.
EventBus eb = vertx.eventbus();
...
eb.publish("test.address", "hello world !");
Request/Response
communication bi-directionelle entre un sender et un receiver.
Type de message
- String
- Primitives (int, long, short, float, double, …)
- Boxed Primitives
- boolean/Boolean
- org.vertx.java.core.json.JsonObject
- org.vertx.java.core.buffer.Buffer
Privilégier JSON pour les échanges de de données structurées.
JSON est la lingua franca entre les verticles qui peuvent être implémentés dans des langages différents.
Le Clustering
Verticles déployés sur plusieurs machines.
Utilise notament Hazelcast.
Vert.x dans le browser
communication entre le bus et le navigateur. Basé sur SockJS (client).
Il existe un module AngularJS facilitant l’intégration de SockJS avec AngularJS : angular-sockjs.
Vert.x shared state
Uniquement disponible dans une instance de vert.x (≠ cluster).
Les éléments partagés doivent être immutables.
De bons candidats sont les :
- String
- primitives
Shared Collection proposées par Vert.x
Shared Map
Shared Set
Goodies
- Growing Module Repository
- web server
- persistors (Mongo, JDBC, …)
- work queue
- authentication manager
- session manager
- Socket.IO
- TCP/SSL servers/clients
- HTTP/HTTPS servers/clients
- WebSockets support
- SockJS support
- Timers
- Buffers
- Streams and Pumps
- Routing
- Asynchronous File I/O