1. 最近在开源中国看到一个服务器框架的性能测试图,如下(http://www.oschina.net/news/49158/undertow_vert_x_and_netty_benchmarks)
我们看到了熟悉的netty,但是两个些许比较陌生的名字,vertx和undertow。最近这些天,看了一下这两个框架的东西,觉得设计的各方面非常棒。 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.本篇文章以最入门的例子来探索二者的用法,后续还会深入源码进行解析(使用了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>
* 设计思路上可以从BIO->NIO理解,如BIO中的connect/read/write方法都是阻塞操作,而NIO模式下如果没有结果则方法立即返回
* </pre>
*
* @author landon
* @since 1.8.0_25
*/
public class Vertx3Example {
public void useFile() {
Vertx vertx = Vertx.factory.vertx();
FileSystem fs = vertx.fileSystem();
// copy过程为纯异步操作,异步回调在lambda执行
// 1.游戏开发过程中通常需要异步回调给主线程进行处理
// 2.对于此实现完全可以使用guava的线程池进行异步回调处理
// 3.完全可以用显示的异步线程池处理,即IO操作交给异步线程,IO操作完毕后交给主线程进行处理
// 4.个人更倾向于异步回调的方式用消息进行处理
// 5.当然可以使用vertx,在完成的handler进行回调主线程进行处理
fs.copy("foo.txt", "bar.txt", res -> {
// 输出异步完成调用线程
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进行比较
public void useHttp() {
Vertx vertx = Vertx.factory.vertx();
// builder模式
HttpServerOptions httpServerOptions = new HttpServerOptions().setMaxWebsocketFrameSize(1000000);
HttpServer httpServer = vertx.createHttpServer(httpServerOptions);
// 监听,监听选项由HttpServerOptions提供,默认port:80,host:0.0.0.0
// 注:调用listen前必须设置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);
// 必须调用end,调用end前必须设置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_发布消息
eb.publish("nba.sport", "curry shot a 3-p ball!");
// 发送消息_注册了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接口显示的加上函数式接口就更好了
// 即只要接口中有一个方法就可以使用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/ 默认80端口 页面输出:Hello,World!
example.helloWorld();
}
}
结束语:只是展示了一下用法,尤其是vertx,框架设计的非常好,后续会根据源码进行解析。敬请期待后续系列! 附:本人最近正在学习的一些开源框架,有兴趣的可以一起交流: 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 阅读(5690)
评论(1) 编辑 收藏 所属分类:
Program 、
ServerFramework