zoukankan      html  css  js  c++  java
  • Vert.x介绍以及与Node.js性能比较

    Vert.x是一个轻量级的高性能JVM应用平台,基于它可开发各种移动,Web和企业应用程序。一个主要特点是可使用多种语言编写应用,如Java, JavaScript, CoffeeScript, Ruby, Python 或 Groovy等等,它的简单actor-like机制能帮助脱离直接基于多线程编程。它是基于Netty和Java 7的NIO2的编写的。

       当前业界遭遇C10K问题,当并发连接超过10,000+以上时使用传统技术会引发暂停,移动设备或视频 声音如类似微信这样的实时聊天,都是属于长任务连接Long-lived。

       通常Tomcat会在100个并发长请求(这个请求要求做很多事长任务)下堵塞,而Vertx将长任务委托给另外一个线程来执行,从而不会堵塞当前线程,与NodeJS的原理非常类似,如下图:

       事件循环的线程和长任务工作线程之间是通过事件总线EventBus通讯的,这个事件总线是一个JVM之中,如下图:

       图中每个Verticle是一个线程,符合单写原则,避免了写争夺。总线可以拓展到客户端边的Javascript,可以在客户端和服务器端分发事件,可以如下图在多个客户端或服务器端:

       下图是在一个Web应用中,多层之间也可以通过EventBus通讯实现调用:

     

    代码演示

       下面是一个服务器的Java代码:

    public class ServerExample extends Verticle {
      public void start() {
        vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() {
          public void handle(HttpServerRequest req) {
            System.out.println("Got request: " + req.uri());
     req.response().headers().set("Content-Type", "text/html; charset=UTF-8");
            req.response().end("<html><body><h1>Hello from vert.x!</h1></body></html>");
          }
        }).listen(8080);
      }
    }

      groovy版本:

    package http
    vertx.createHttpServer().requestHandler { req ->
      req.response.end "<html><body><h1>Hello from vert.x!</h1></body></html>"
    }.listen(8080, "localhost")

      Javascript版本:

    var vertx = require('vertx')
    vertx.createHttpServer().requestHandler(function(req) {
      req.response.end("<html><body><h1>Hello from vert.x!</h1></body></html>");
    }).listen(8080);

    WebScoket实现

      WebSocket是Web服务器端向客户端推送信息的协议,使用vert.x实现如下:

    vertx.createHttpServer().websocketHandler { ws ->
      ws.dataHandler { data -> ws.writeTextFrame(data.toString()) }
    }.requestHandler { req ->
      if (req.uri == "/") req.response.sendFile "websockets/ws.html"
    }.listen(8080)

      浏览器客户端通过JS调用:

    <script>
        var socket;
        if (window.WebSocket) {
            socket = new WebSocket("ws://localhost:8080/myapp");
            socket.onmessage = function(event) {
                alert("Received data from websocket: " + event.data);
            }
            socket.onopen = function(event) {
                alert("Web Socket opened!");
            };
            socket.onclose = function(event) {
                alert("Web Socket closed.");
            };
        } else {
            alert("Your browser does not support Websockets. (Use Chrome)");
        }
        function send(message) {
            if (!window.WebSocket) {
                return;
            }
            if (socket.readyState == WebSocket.OPEN) {
                socket.send(message);
            } else {
                alert("The socket is not open.");
            }
        }
    </script>

       SocketJS是一种处理客户端和服务器通讯的框架,能够在客户端提供类似websocket的API,支持JSON-Polling, XHR-Polling/Streaming。

    <html>
    <head>
        <title>SockJS Test</title>
        <script src="http://cdn.sockjs.org/sockjs-0.3.4.min.js"></script>
    </head>
    <body>
    <script>
       var sock = new SockJS('http://localhost:8080/testapp');
       sock.onopen = function() {
           console.log('open');
       };
       sock.onmessage = function(e) {
           console.log('message', e.data);
           alert('received message echoed from server: ' + e.data);
       };
     
     sock.onclose = function() {
           console.log('close');
       };
       function send(message) {
         if (sock.readyState === SockJS.OPEN) {
            console.log("sending message")
            sock.send(message);
         } else {
            console.log("The socket is not open.");
         }
       }
    </script>
    <form οnsubmit="return false;">
        <input type="text" name="message" value="Hello, World!"/>
        <input type="button" value="Send SockJS data" οnclick="send(this.form.message.value)"/>
    </form>
    </body>
    </html>

    服务器端创建一个SocketJS的Server:

    def server = vertx.createHttpServer()
    // Serve the index page
    server.requestHandler { req ->
      if (req.uri == "/") req.response.sendFile 'sockjs/index.html'
    }
    // The handler for the SockJS app - we just echo data back
    vertx.createSockJSServer(server).installApp(prefix: '/testapp') { sock ->
      sock.dataHandler { buff ->
        sock << buff
      }
    }
    server.listen(8080)

    消息模型

       使用vert.x可以实现1:N和1:1的消息模型。Publish/subscribe如下:

    JS代码如下:

    var eb = require("vertx/event_bus");
    var console = require("vertx/console");
    var vertx = require("vertx")
    vertx.setPeriodic(1000, function sendMessage() {
      eb.publish('news-feed', 'some news!');
    })

    订阅者:

    var eb = require("vertx/event_bus");
    var console = require("vertx/console");
    eb.registerHandler("news-feed", function(message) {
      console.log('Received news ' + message);
    });

    一对一的队列方式:

    发布者JS代码如下:

    var eb = require("vertx/event_bus");
    var console = require("vertx/console");
    var vertx = require("vertx")
    vertx.setPeriodic(1000, function sendMessage() {
      eb.send('ping-address', 'ping!', function(reply) {
        console.log("Received reply: " + reply);
      });
    })

    订阅者代码如下:

    var eb = require("vertx/event_bus");
    var console = require("vertx/console");
    eb.registerHandler("ping-address", function(message, replier) {
      console.log('Received message ' + message);
      // Now reply to it
      replier('pong!');
    });

    共享数据

      消息传递是非常有用的。然而,它并不总是在所有类型的应用程序解决并发的最好选择。缓存也是最流行的解决方式之一。如果只有一个Verticle有一一个缓存,这是非常低效的。当其他Verticles需要缓存,每个Verticle应该共享相同的缓存数据。 因此,Vert.x提供全局访问共享的MAP的方式,称为 Shared Map。 共享的是不变性数据。

    与NodeJS比较

    安装使用

       vertx使用了invokeDynamic in JDK7.因此需要JDK7环境。从 http://vertx.io/downloads.html下载,解压,将bin目录加入环境PATH中。在windows环境可以执行vertx version

    比如建设一个JS编写的服务器代码:

    load('vertx.js');
     
    vertx.createHttpServer().requestHandler(function(req) {
    req.response.end("Hello World!");}) .listen(8080, 'localhost');

    在命令行只有运行下面命令可启动这个服务器:

    $ vertx run server.js

    在浏览器打开http://localhost:8080,可看到hello World

  • 相关阅读:
    STL(1) 指针迭代器
    不错我博主
    C++ 学习书目
    写给VC++ Windows开发的初学者 一片不错的博文
    算法:C语言实现 (4)队列的数组实现
    算法:C语言实现 (4)下推栈的数组实现
    算法:C语言实现 (4)下推栈的链表实现
    vs 使用笔记
    自定义组合控件,适配器原理-Day31
    Android30-Fragment-理解
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13317551.html
Copyright © 2011-2022 走看看