1. 最近在開源中國看到一個服務(wù)器框架的性能測試圖,如下(http://www.oschina.net/news/49158/undertow_vert_x_and_netty_benchmarks)
我們看到了熟悉的netty,但是兩個些許比較陌生的名字,vertx和undertow。最近這些天,看了一下這兩個框架的東西,覺得設(shè)計的各方面非常棒。 2. http://vertx.io/ Vert.x is a lightweight, high performance application platform for the JVM that's designed for modern mobile, web, and enterprise applications. 3.http://undertow.io/ Undertow is a flexible performant web server written in java, providing both blocking and non-blocking API’s based on NIO. 4.本篇文章以最入門的例子來探索二者的用法,后續(xù)還會深入源碼進(jìn)行解析(使用了Java8的Lambda) package com.mavsplus.example.vertx;
import io.vertx.core.Vertx;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.eventbus.MessageConsumer;
import io.vertx.core.file.FileSystem;
import io.vertx.core.http.HttpClient;
import io.vertx.core.http.HttpClientOptions;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions;
/**
* Vert.x例子
*
* <pre>
* 設(shè)計思路上可以從BIO->NIO理解,如BIO中的connect/read/write方法都是阻塞操作,而NIO模式下如果沒有結(jié)果則方法立即返回
* </pre>
*
* @author landon
* @since 1.8.0_25
*/
public class Vertx3Example {
public void useFile() {
Vertx vertx = Vertx.factory.vertx();
FileSystem fs = vertx.fileSystem();
// copy過程為純異步操作,異步回調(diào)在lambda執(zhí)行
// 1.游戲開發(fā)過程中通常需要異步回調(diào)給主線程進(jìn)行處理
// 2.對于此實現(xiàn)完全可以使用guava的線程池進(jìn)行異步回調(diào)處理
// 3.完全可以用顯示的異步線程池處理,即IO操作交給異步線程,IO操作完畢后交給主線程進(jìn)行處理
// 4.個人更傾向于異步回調(diào)的方式用消息進(jìn)行處理
// 5.當(dāng)然可以使用vertx,在完成的handler進(jìn)行回調(diào)主線程進(jìn)行處理
fs.copy("foo.txt", "bar.txt", res -> {
// 輸出異步完成調(diào)用線程
System.out.println(String.format("callback thread:%s", Thread.currentThread().getName()));
// 判斷異步操作是否成功
if (res.succeeded()) {
System.out.println("fs.copy successed!");
} else {
System.out.println("fs.copy failed!");
// 如果失敗的話判斷異常
if (res.failed() && res.cause() != null) {
res.cause().printStackTrace();
vertx.close();
}
}
});
}
// 用vertx做embedded的httpserver/client挺方便
// 實際使用需要壓力測試和其他方面測試 或者和其他如undertow進(jìn)行比較
public void useHttp() {
Vertx vertx = Vertx.factory.vertx();
// builder模式
HttpServerOptions httpServerOptions = new HttpServerOptions().setMaxWebsocketFrameSize(1000000);
HttpServer httpServer = vertx.createHttpServer(httpServerOptions);
// 監(jiān)聽,監(jiān)聽選項由HttpServerOptions提供,默認(rèn)port:80,host:0.0.0.0
// 注:調(diào)用listen前必須設(shè)置requestHandler
httpServer.requestHandler(request -> {
request.response().end("Hello,Vertx!");
}).listen(listen -> {
if (listen.succeeded()) {
System.out.println("The httpServer is now listenning now");
} else {
System.out.println("The httpServer failed to bind!");
}
});
HttpClientOptions httpClientOptions = new HttpClientOptions();
HttpClient httpClient = vertx.createHttpClient(httpClientOptions);
// 必須調(diào)用end,調(diào)用end前必須設(shè)置responseHandler
httpClient
.request(HttpMethod.GET, "http://127.0.0.1:80")
.handler(
response -> {
System.out.println("response statusMessage:" + response.statusMessage() + " statusCode:"
+ response.statusCode());
response.bodyHandler(body -> {
System.out.println("response body:" + body);
});
}).end();
}
// The event bus implements publish / subscribe, point to point messaging
// and request-response messaging
public void useEventBus() {
Vertx vertx = Vertx.vertx();
EventBus eb = vertx.eventBus();
// subscribe_訂閱消息
MessageConsumer<String> consumer = eb.consumer("nba.sport", message -> {
System.out.println("I have receive a msg:" + message.body());
// reply
message.reply("how interesting!");
});
consumer.completionHandler(res -> {
if (res.succeeded()) {
System.out.println("The handler registration has reached all nodes");
} else {
System.out.println("Registration failed");
}
});
// publish_發(fā)布消息
eb.publish("nba.sport", "curry shot a 3-p ball!");
// 發(fā)送消息_注冊了reply_handler
eb.send("nba.sport", "lbj dunk!", ar -> {
if (ar.succeeded()) {
System.out.println("Receieved reply:" + ar.result().body());
}
});
}
public static void main(String[] args) {
Vertx3Example example = new Vertx3Example();
// example.useFile();
// example.useHttp();
example.useEventBus();
}
}
package com.mavsplus.example.undertow;
import io.undertow.Undertow;
import io.undertow.util.Headers;
/**
* Undertow例子
*
* @author landon
* @since 1.8.0_25
*/
public class UndertowExample {
public void helloWorld() {
// builder模式,使用lambda,如果HttpHandler接口顯示的加上函數(shù)式接口就更好了
// 即只要接口中有一個方法就可以使用lambda
Undertow server = Undertow.builder().addHttpListener(80, "localhost").setHandler(exchange -> {
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
exchange.getResponseSender().send("Hello,World!");
}).build();
server.start();
}
public static void main(String[] args) {
UndertowExample example = new UndertowExample();
// 瀏覽器地址欄輸入 http://127.0.0.1/ 默認(rèn)80端口 頁面輸出:Hello,World!
example.helloWorld();
}
}
結(jié)束語:只是展示了一下用法,尤其是vertx,框架設(shè)計的非常好,后續(xù)會根據(jù)源碼進(jìn)行解析。敬請期待后續(xù)系列! 附:本人最近正在學(xué)習(xí)的一些開源框架,有興趣的可以一起交流: disruptor http://lmax-exchange.github.io/disruptor/ hornetq http://hornetq.jboss.org/ rocketmq https://github.com/alibaba/RocketMQ vertx http://vertx.io/ undertow http://undertow.io/ mina3/netty5/xnio protobuf/thrift artemis flume
posted on 2015-06-10 11:48
landon 閱讀(5700)
評論(1) 編輯 收藏 所屬分類:
Program 、
ServerFramework