1.Vertx重要概念
vertx demo项目 方便了解vertx框架使用
- 概念1:Vertx
实现类VertxImpl,它的重要线程
eventLoopGroup
acceptorEventLoopGroup - 概念2: Verticle
1) Verticle起作用的方式,主要是通过Vertx进行部署,也就是deployVerticle
2) Verticle部署,主要是Vertx框架把vertx 和context 传给Verticle,并且通过context启动 - 概念3: Context上下文
1) 子类:ContextInternal EventLoopContext
2) 上下文是通过Vertx创建,如ContextInternal callingContext = vertx.getOrCreateContext();
3) context可以跑task,因为带了线程,线程是eventloop的是EventLoopContext,否则是普通context,普通context线程是VertxThread,是vertx的work线程
2.Vertx创建
以io.vertx.example.core.http.sharing.HttpServerVerticle为例子,该例子来源于上述的demo工程
Vertx创建很简单,传入VertxOptions 通过VertxBuilder进行创建VertxImpl实例,两类重要的网络I/O线程就是在此时创建的,见VertxImpl的构造函数
eventLoopGroup = transport.eventLoopGroup(Transport.IO_EVENT_LOOP_GROUP, options.getEventLoopPoolSize(), eventLoopThreadFactory, NETTY_IO_RATIO);
acceptorEventLoopGroup = transport.eventLoopGroup(Transport.ACCEPTOR_EVENT_LOOP_GROUP, 1, acceptorEventLoopThreadFactory, 100);
3.Vertx部署Verticle
vertx实例调用deployVerticle进行并部署,deployVerticle等待参数有Verticle,如例子中的HttpServerVerticle,另外可以定制部署参数,通过DeploymentOptions配置。
如下是部署过程,关键的流程
// 开始部署
verticleManager.deployVerticle(name, options).map(Deployment::deploymentID);
// 创建context
ContextInternal callingContext = vertx.getOrCreateContext();
//最后进入DeploymentManager.doDeploy,循环部署多个verticle实例
for (Verticle verticle: verticles) {
...
// 创建新的context
ContextImpl context = (options.isWorker() ? vertx.createWorkerContext(deployment, closeFuture, workerPool, tccl) :
vertx.createEventLoopContext(deployment, closeFuture, workerPool, tccl));
...
// 通过context的线程驱动verticle运行
context.runOnContext(v -> {
try {
// 把vertx和context传给verticle
verticle.init(vertx, context);
Promise startPromise = context.promise();
Future startFuture = startPromise.future();
// 运行start方法,用户的业务逻辑是在start方法实现,驱动用户的业务逻辑
verticle.start(startPromise);
...
} catch (Throwable t) {
if (failureReported.compareAndSet(false, true))
deployment.rollback(callingContext, promise, context, holder, t);
}
});
}
3.1 Server sharing 分析
vertx官方文档 里提到Server sharing,比如,部署一个HttpServerVerticle,启动多个实例,多verticle实例如何共享一个listen port呢?
3.1.1 demo演示
HttpServerVerticle启动httpServer,监听8080端口,
public class HttpServerVerticle extends AbstractVerticle {
@Override
public void start() throws Exception {
vertx.createHttpServer().requestHandler(req -> {
req.response()
.putHeader("content-type", "text/html")
.end("Hello from " + this + "
");
}).listen(8080);
}
}
Server verticle部署HttpServerVerticle,配置启动2个HttpServerVerticle instance
@Override
public void start() throws Exception {
vertx.deployVerticle(
"io.vertx.example.core.http.sharing.HttpServerVerticle",
new DeploymentOptions().setInstances(2));
}
启动Client运行结果如下,说明两个HttpServerVerticle实例成功部署,并且负载均衡对client服务
3.1.2 分析