简介
我们知道,在Vert.x中的路由处理都是异步的,如果需要在处理程序中执行一些阻塞API或者密集计算的话就不能使用常用的handler来处理了,此时需要使用Vert.x提供的blockingHandler来处理,下面就介绍以下
示例
在这个例子中定义了一个路由——blocking,请求它时会执行里面的阻塞程序,阻塞程序为一个Thread.sleep定时向response中写入内容,最后end。下面就用俩种不同的方式来进行实现。
方式一:有序执行
有序执行是什么意思?有序执行指的是在完成上一个之前下一个是不会执行的,可以想象这样一个场景,我请求了blocking这个路由后该请求在等待程序处理完所有的内容,如果在处理过程中再次请求了blocing这个路由那么此时第二次请求不会有响应,知道第一次的请求执行完毕。如下动图演示。
通过上图可以看到,设置为有序执行的时候俩次请求请求同一个路由,第二次请求只有在第一次请求完成后才会开始。因此该种请求适合对同步要求高的场景。Vert.x在默认的情况下就是采用的这种方式。上述demo的示例代码如下:
package demo;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.Router;
public class MainVerticle extends AbstractVerticle {
@Override
public void start(Promise<Void> startPromise) throws Exception {
System.setProperty("vertxweb.environment","dev");
HttpServer httpServer = vertx.createHttpServer(); //创建HTTP服务
Router router = Router.router(vertx); //创建路由对象
router.route("/blocing/")
.blockingHandler(ctx->{
HttpServerResponse response = ctx.response();
response.setChunked(true);
for(int i=0; i<10; i++){
try {
Thread.sleep(500L);
response.write("test " + i+"\n");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ctx.end("over");
},true);
httpServer.requestHandler(router).listen(8888).onSuccess(server-> System.out.println("Server start and port :"+server.actualPort()));
}
}
blockingHandler方法默认情况下第二个参数是可以不写的,默认为true,这里我显示的设置出来了。
第二种方式:可以无序执行
这种方式适合我们请求的路由接口不在乎执行顺序并且不介意阻塞的程序可以并行执行,此时我们可以将ordered设置为false来禁用有序行为。这种方式多次请求会并行执行,不会阻塞请求,注意:这里说的不会阻塞不是指请求不会阻塞,不是请求处理里面的代码。使用这种方式得到的效果如下:
总结
在使用Vert.x过程中能使用异步的handler就尽量使用异步执行,除非相关代码块或业务方法必须要保证同步再考虑上面两种方式。