Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to Vert.x

6f8d092fec403f766c734ce36e1eef93?s=47 Horacio Gonzalez
September 18, 2014

Introduction to Vert.x

6f8d092fec403f766c734ce36e1eef93?s=128

Horacio Gonzalez

September 18, 2014
Tweet

Transcript

  1. Introduction to Vert.x By @LostInBrittany

  2. Horacio Gonzalez Spaniard lost in Brittany, Java developer, dreamer and

    all-around geek • Senior Software Engineer at Cityzen Data ◦ Cityzen Data provides a scalable, secure, ethical and open platform for sensor data • Co-founder & co-leader of FinistJUG & GDG Finistère http://lostinbrittany.org/ +Horacio.Gonzalez @LostInBrittany
  3. Introduction Because I love to tell old stories

  4. The old one thread per connection model... One thread per

    request model
  5. The old one thread per connection model... • Limitation to

    number of concurrent users ◦ Threads are a scarce resource • Non-efficient use of resources ◦ Lots of time spent idly waiting • High charges ask for lots of servers ◦ Infrastructure management problems...
  6. The old one thread per connection model... Connection Request 1

    Request 3 Request 2 Thread 1 Thread 2 Thread 3 Waiting time
  7. But the web evolved Static pages Form-driven applications Ajax-driven applications

  8. To a real-time web Static pages Form-driven applications Ajax-driven applications

    Real-time applications
  9. And the mobile web happened More and more users Users

    using the Web on mobility More and more device types
  10. Enter the C10k problem How does your application server handle

    ten thousand clients simultaneously?
  11. The Reactive Manifesto Reactive Systems are: • Responsive • Resilient

    • Elastic • Message-driven http://www.reactivemanifesto.org/
  12. A different approach was needed • Asynchronous model ◦ Not

    only non-blocking IO ◦ Every potentially blocking task must be asynchronous • Event/message driven programming
  13. A different approach was needed • Event-loop ◦ A lone

    thread waits for data/jobs ◦ It dispatches tasks to thread to do them • Reactor pattern
  14. Filling forms in the post-office analogy

  15. Nginx vs Apache HTTPD Nginx is event-driven and asynchronous Apache

    relies on processes and threads Apache is like Microsoft Word, it has a million options but you only need six. Nginx does those six things, and it does five of them 50 times faster than Apache. Chris Lea on Nginx and Wordpress
  16. In 2008 the unthinkable happened... • A fully asynchronous platform,

    build on an event- driven, non-blocking I/O model • And built in JavaScript!
  17. And it simply works... Highly efficient use of resources!

  18. Node is great… but it has some problems 1. JavaScript

    2. Vertical scaling 3. Interprocess communication 4. Event loop
  19. Problem #1: JavaScript Non, seriously, I really like JavaScript but

    sometimes...
  20. Problem #2: Vertical scaling • A single instance of Node

    runs in a single thread ◦ To scale vertically you must spawn a cluster var cluster = require('cluster'); var http = require('http'); var numCPUs = require('os').cpus().length; if (cluster.isMaster) { // Fork workers. for (var i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', function(worker, code, signal) { console.log('worker ' + worker.process.pid + ' died'); }); } else { // Workers can share any TCP connection // In this case its a HTTP server http.createServer(function(req, res) { res.writeHead(200); res.end("hello world\n"); }).listen(8000); }
  21. Problem #3: Interprocess communication How do two Node process communicate?

    Lots of options (TCP, UDP, sockets, MQ, Redis pub/sub…) None simple and fully integrated
  22. Problem #4: Event loop In Node there is a single

    event loop everything runs on it! It must not be blocked!
  23. Enter Vert.x Let's take Node and rebuild it better...

  24. What's Vert.x A lightweight asynchronous platform, build on an event-driven,

    non-blocking I/O model inspired by NodeJS
  25. Answers to problems on Node • Problem #1: JavaScript ◦

    Polyglot API • Problem #2: Vertical scaling ◦ Built on JVM, naturally multi-threaded • Problem #3: Interprocess communication ◦ Event bus and native clustering • Problem #4: Event-loop ◦ Multi-reactor and worker verticles
  26. Vert.x under the hood • Written in Java • Built

    on NIO 2, Netty and Hazelcast ◦ Java 7+ • Polyglot bindings ◦ JavaScript, Groovy, Scala, Clojure, Ruby • Based on an extended reactor pattern: multi-reactor
  27. Vert.x Core concepts Verticles, event loop, distributed event bus...

  28. Core concepts • Verticles • Vert.x instances • Event Bus

    • Background Workers • Modules
  29. Verticles: packages of code executed by Vert.x JVM Vert.x instance

    Event Loop Workers Verticle 1 Verticle 2 Verticle 3 Verticle 4 Worker 1 Worker 2 Worker 3 JVM Vert.x instance Event Loop Workers Verticle 1 Verticle 2 Verticle 5 Verticle 6 Worker 2 Worker 4 Worker 5 Distributed Event Bus
  30. Verticles: packages of code executed by Vert.x • Many verticles

    can be executing concurrently in the same Vert.x instance • An application might be composed of ◦ multiple verticles ◦ deployed on different Vert.x instances ◦ communicating over the Vert.x event bus.
  31. Vert.x instances • Verticles run inside a Vert.x instance •

    A single Vert.x instance runs inside its own JVM instance • There can be many verticles running inside a single Vert.x instance • There can be many Vert.x instances ◦ running on the same host, or on different hosts ◦ configured to cluster with each other ▪ distributed event bus
  32. Easy concurrency • A verticle instance is never executed by

    more than one thread concurrently ◦ You can program all your code as single threaded • Different verticle instances ◦ exchange messages over the event bus ◦ share data on immutable shared maps and sets • Actor-like model ◦ Verticles - Actors
  33. Asynchronous Programming Model

  34. Asynchronous Programming Model • Asynchronous core APIs ◦ Programming by

    setting event handlers • Able to handle many verticles using a small number of operating system threads (event loop threads) ◦ Vert.x sets the number of threads to the number of available cores
  35. Event loops • Loop while waiting for events, then deliver

    them to the handlers ◦ Example of event: data read from a socket, timer fired, HTTP response ended… • Each verticle is assigned to an event loop thread ◦ The same from deployment to server stop • Multi-reactor pattern Golden rule: never block the event loop!
  36. Worker verticles • When you need to perform blocking operations

    ◦ E.g. computationally intensive operations or JDBC connections • Worker verticles not assigned to event loop threads ◦ Worker verticles executes in threads from the worker pool ◦ Worker verticles can be executed concurrently by several threads ▪ Not concurrency-safe • They doesn't scale well ◦ Use them only when unavoidable Hybrid threading model
  37. Core API Provides functionality for: • TCP/SSL servers and clients

    • HTTP/HTTPS servers and clients • WebSockets servers and clients • The distributed event bus • Periodic and one-off timers • Buffers • Flow control • File-system access • Shared map and sets • Accessing configuration • SockJS
  38. Container API Provides functionality for: • Deploy and undeploy verticles

    • Deploy and undeploy modules • Retrieve verticle configuration • Logging
  39. Benchmark http://vertxproject.wordpress.com/2012/05/09/vert-x-vs-node-js-simple-http-benchmarks/

  40. Example: Polyglot Vert.x A web server in four languages

  41. Polyglot - web server in Java Run it: vertx run

    Server.java note no compile is needed! import org.vertx.java.core. Handler; import org.vertx.java.core.http. HttpServerRequest ; import org.vertx.java.platform. Verticle; public class Server extends Verticle { public void start() { vertx.createHttpServer().requestHandler( new Handler<HttpServerRequest >() { public void handle(HttpServerRequest req) { String file = req.path().equals( "/") ? "index.html" : req.path(); req.response().sendFile( "webroot/" + file); } }).listen( 8080); } }
  42. Polyglot - web server in JavaScript Run it: vertx run

    server.js var vertx = require('vertx'); vertx.createHttpServer().requestHandler( function(req) { var file = req.path() === '/' ? 'index.html' : req.path(); req.response.sendFile( 'webroot/' + file); }).listen(8080)
  43. Polyglot - web server in Groovy Run it: vertx run

    Server.groovy vertx.createHttpServer().requestHandler { req -> def file = req.uri == "/" ? "index.html" : req.uri req.response.sendFile "webroot/$file" }.listen(8080)
  44. Polyglot - web server in Python Run it: vertx run

    server.py import vertx server = vertx.create_http_server() @server.request_handler def request_handler(req): file = "index.html" if req.uri == "/" else req.uri req.response.send_file( "webroot/%s"%file) server.listen( 8080)
  45. Example: Echo! A TCP echo server in Groovy

  46. A TCP echo server in Groovy A raw Groovy verticle:

    you can directly execute it Run it: vertx run Server.groovy note no compile is needed! To test it: telnet 127.0.0.1 1234 import static org.vertx.groovy.core.streams. Pump.createPump vertx.createNetServer().connectHandler { socket -> createPump(socket, socket).start() }.listen(1234)
  47. A TCP echo server in Groovy A compiled Groovy verticle

    Run it: vertx groovy:examples.EchoServer To test it: telnet 127.0.0.1 1234 package examples import org.vertx.groovy.platform. Verticle import static org.vertx.groovy.core.streams. Pump.createPump import org.vertx.groovy.core. Vertx class EchoServer extends Verticle { def start() { vertx.createNetServer().connectHandler { socket -> createPump(socket, socket).start() }.listen( 1234) } def stop() { } }
  48. Example: Modules Because verticles are better cooked than raw

  49. Modules • Applications composed of modules ◦ Modules can contain

    multiple verticles ▪ Potentially written in different languages ◦ Encapsulation and reuse ▪ Shared on classic repositories ▪ Registered in module registry • Eco-system managed by the community
  50. Structure of a module • Module: zip file ◦ contains

    the resources needed by the module ▪ class files, .java files, script files, jar files… • Identified by an owner, a name and a version com.cityzendata~testvertx~test~3.2
  51. File mod.json • Descriptor of the module ◦ description, licence,

    author, keywords, developers, homepage ▪ used in the module registry ◦ main: verticle to start (if module is runnable) ◦ worker: true if it's a worker module ◦ includes: comma-separated list of modules dependencies ◦ auto-redeploy, lang-impl, multi-threaded, preserve-cwd, resident, system, deploys...
  52. File mod.json { "description": "Cityzen Data vert.x test project ",

    "author": "Horacio Gonzalez ", "main": "groovy:com.cityzendata.test.verticle.Main ", "auto-redeploy" : true "includes": "com.acme.common-stuff-v1.0" }
  53. Module classpath and classloaders • Each module is given its

    own class loader ◦ Multiple instances of the same module (same name and version) share classloader ◦ Multiple versions of the same module have independent classloaders • Module classpath: ◦ The root of each module ◦ Any jar on libs directory
  54. Running a module vertx runmod com.cityzendata~testvertx~test~ 3.2 • You can

    run the module by it's identifiers • You can use directly the zip file vertx runzip com.cityzendata-testvertx-test- 3.2.zip
  55. Vert.x module registry

  56. The Event Bus The nervous system of Vert.x

  57. The Event Bus • Allows verticles to communicate with each

    other ◦ Irrespective of language ◦ Irrespective of Vert.x instance ◦ Even client side JS running in a browser can use it Distributed peer-to-peer network spanning multiple server nodes and multiple browsers
  58. The Event Bus is simple • It basically involves: ◦

    Registering handlers ◦ Unregistering handlers ◦ Sending and publishing messages.
  59. Event bus: addressing and handlers • Addressing ◦ Messages are

    sent on the event bus to an address ▪ An address is any valid string • Handler ◦ A handler is a thing that receives messages from the bus ◦ Handlers are registered to addresses ▪ Different handlers can be registered at the same address ▪ A handler can be registered at different addresses.
  60. Event bus: sending and receiving Two communication types • Publish/Subscribe

    ◦ Messages are published to an address. ◦ All handlers registered at the address receive the message • Point to point ◦ Messages are sent to an address ◦ Only one of the handlers registered at that address receive it ▪ Round-robin ◦ With our without reply
  61. Event bus messages • Message body types: • boolean •

    byte[] • byte • char • double • float • int • long • short • java.lang.String • java.util.Map - representing a JSON object • org.vertx.java.groovy.buffer.Buffer
  62. Example: The Event Bus How do you use it?

  63. The echo message verticle def myHandler = { message ->

    println "I received a message: ${message.body}" message.reply "Response!" // Reply to it } def eb = vertx.eventBus eb.registerHandler("test.address", myHandler) vertx.createHttpServer().requestHandler { request -> eb.send("test.address", "Message!") { message -> request.response.with { statusCode = 200 statusMessage = "Hi FinistJUG" chunked = true write("I received a response: ${message.body}\n") end() } } }.listen(8080)
  64. The fat Jar There is beauty on XL size

  65. How do I deploy it? We chose the fat jar

    gradle fatJar The full Vert.x server is zipped inside the jar No repackaging, meesa isn't JarJar
  66. Some links Because I like promoting procrastination

  67. Some links: C10k problem and real-time Web • The C10k

    problem (original article) • Wikipedia - C10k problem • Ars Technica - Say hello to the real-time Web • MMOAsteroids • Nginx vs Apache
  68. Some links: Vert.x • vertx.io • GitHub repository