在Vert.x中,Vertx接口是最为重要的一个接口,vertx-core的基础功能都在此接口中提供。这篇文章中我们就来分析一下Vertx接口体系的内部实现以及创建流程。本文对应Vert.x的版本为 3.2.1

Vertx接口体系

我们来看一下Vertx接口的UML关系:

可以看到有VertxImpl <:< VertxInternal <:< Vertx这个继承链。这里我们先不研究MeasuredMetricsProvider这两个接口。我们先来看一下VertxInternal的结构:

可以看到里边包含了各种操作多线程、执行回调等等的方法。VertxInternal接口仅供vertx-core内部调用。

VertxImpl类是对VertxInternalVertx接口的实现。我们创建的Vertx实例都是VertxImpl

Vertx创建流程以及内部实现

通常,我们都会通过Vertx接口中的静态方法vertx创建Vertx实例:

1
Vertx vertx = Vertx.vertx();

vertx方法底层通过工厂模式创建VertxImpl实例:

1
2
3
static Vertx vertx() {
 return factory.vertx();
}
1
2
3
4
5
6
7
8
public class VertxFactoryImpl implements VertxFactory {

  @Override
 public Vertx vertx() {
   return new VertxImpl();
 }
 // ...
}

下面我们来探究一下VertxImpl类的创建流程和内部实现。我们首先来看一下VertxImpl类的实例成员:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private final FileSystem fileSystem = getFileSystem();
private final SharedData sharedData;
private final VertxMetrics metrics;
private final ConcurrentMap<Long, InternalTimerHandler> timeouts = new ConcurrentHashMap<>();
private final AtomicLong timeoutCounter = new AtomicLong(0);
private final ClusterManager clusterManager;
private final DeploymentManager deploymentManager;
private final FileResolver fileResolver;
private final Map<ServerID, HttpServerImpl> sharedHttpServers = new HashMap<>();
private final Map<ServerID, NetServerImpl> sharedNetServers = new HashMap<>();
private final ExecutorService workerPool;
private final ExecutorService internalBlockingPool;
private final OrderedExecutorFactory workerOrderedFact;
private final OrderedExecutorFactory internalOrderedFact;
private final ThreadFactory eventLoopThreadFactory;
private final NioEventLoopGroup eventLoopGroup;
private final NioEventLoopGroup acceptorEventLoopGroup;
private final BlockedThreadChecker checker;
private final boolean haEnabled;
private EventBus eventBus;
private HAManager haManager;
private boolean closed;

这里面包含了一系列重要的类。我们将在初始化部分来分析这些成员的作用。下面我们来看一下构造函数:

1
2
3
4
5
6
7
8
9
10
11
VertxImpl() {
 this(new VertxOptions());
} VertxImpl(VertxOptions options) {
 this(options, null);
} VertxImpl(VertxOptions options, Handler<AsyncResult<Vertx>> resultHandler) {
 // ...
}

可以看到最终都会调用到VertxImpl(VertxOptions options, Handler<AsyncResult<Vertx>> resultHandler)这个构造函数,下面我们就来分析一下。

首先,Vertx会检查当前是否有Vertx实例运行(通过factory.context()方法)。如果有实例运行的话就会给出警告。

1
2
3
4
// Sanity check
if (Vertx.currentContext() != null) {
 log.warn("You're already on a Vert.x context, are you sure you want to create a new Vertx instance?");
}

接着Vertx会初始化checker成员,它是一个BlockedThreadChecker,作用是检查vertx context中是否有阻塞的线程,如果有线程阻塞则给出警告。

1
2
checker = new BlockedThreadChecker(options.getBlockedThreadCheckInterval(), options.getMaxEventLoopExecuteTime(),
                                  options.getMaxWorkerExecuteTime(), options.getWarningExceptionTime());

接下来,Vertx会初始化EventLoop线程工厂eventLoopThreadFactory,它用于产生EventLoop线程。然后初始化eventLoopGroup并进行配置。NioEventLoopGroup是Netty里的概念,将在稍后进行介绍。

1
2
3
eventLoopThreadFactory = new VertxThreadFactory("vert.x-eventloop-thread-", checker, false);
eventLoopGroup = new NioEventLoopGroup(options.getEventLoopPoolSize(), eventLoopThreadFactory);
eventLoopGroup.setIoRatio(NETTY_IO_RATIO);

接下来,Vertx会初始化Acceptor EventLoop线程工厂,并对其进行配置。然后对workerPoolinternalBlockingPool这两个线程池进行初始化。其中workerPool用于执行worker线程,internalBlockingPool用于执行阻塞操作线程。

1
2
3
4
5
6
7
8
9
ThreadFactory acceptorEventLoopThreadFactory = new VertxThreadFactory("vert.x-acceptor-thread-", checker, false);
// The acceptor event loop thread needs to be from a different pool otherwise can get lags in accepted connections
// under a lot of load
acceptorEventLoopGroup = new NioEventLoopGroup(1, acceptorEventLoopThreadFactory);
acceptorEventLoopGroup.setIoRatio(100);
workerPool = Executors.newFixedThreadPool(options.getWorkerPoolSize(),
                                         new VertxThreadFactory("vert.x-worker-thread-", checker, true));
internalBlockingPool = Executors.newFixedThreadPool(options.getInternalBlockingPoolSize(),
                                                   new VertxThreadFactory("vert.x-internal-blocking-", checker, true));

然后,Vertx会初始化两个线程池工厂workerOrderedFactinternalOrderedFact,它们的类型是OrderedExecutorFactory,里边包含一种能够按照次序执行线程的线程池。

1
2
workerOrderedFact = new OrderedExecutorFactory(workerPool);
internalOrderedFact = new OrderedExecutorFactory(internalBlockingPool);

接下来,Vertx会依次对文件解析器fileResolver、部署管理器deploymentManager、SPI管理器metrics进行初始化,并且根据配置来决定是否初始化集群管理器clusterManager和高可用管理器haManager。然后Vertx会调用createAndStartEventBus(options, resultHandler)方法,创建并启动EventBus。最后对共享数据成员sharedData进行初始化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
this.fileResolver = new FileResolver(this);
this.deploymentManager = new DeploymentManager(this);
this.metrics = initialiseMetrics(options);
this.haEnabled = options.isClustered() && options.isHAEnabled();
if (options.isClustered()) {
 this.clusterManager = getClusterManager(options);
 this.clusterManager.setVertx(this);
 this.clusterManager.join(ar -> {
   if (ar.failed()) {
     log.error("Failed to join cluster", ar.cause());
   } else {
     // Provide a memory barrier as we are setting from a different thread
     synchronized (VertxImpl.this) {
       haManager = new HAManager(this, deploymentManager, clusterManager, options.getQuorumSize(),
                                 options.getHAGroup(), haEnabled);
       createAndStartEventBus(options, resultHandler);
     }
   }
 });
} else {
 this.clusterManager = null;
 createAndStartEventBus(options, resultHandler);
}
this.sharedData = new SharedDataImpl(this, clusterManager);
}

经过一系列的构造后,VertxImpl创建完成。

以上。

以下为链接:

来自vertx中国用户组,

(不同版本,代码可能有少许不同之处(我目前使用的是3.3.2),但不妨碍阅读和理解)

http://mp.weixin.qq.com/s?__biz=MzA4MjUwNzQ0NQ==&mid=2650547613&idx=1&sn=5435d20496e4c9f57d958a45855f9f59&chksm=878c2647b0fbaf51bb8a937c2468117a159e2e0acc8a5bf4ba6404b6282d1f6fd1241f01de25&mpshare=1&scene=23&srcid=1206gxIsVTqNU9B885NQYJzL#rd

vertx核心类之VertxImpl的更多相关文章

  1. cesium核心类Viewer简介

    1.简单描述Viewer Viewer类是cesium的核心类,是地图可视化展示的主窗口,cesium程序应用的切入口,扮演必不可少的核心角色. 官网的英文解析如下: A base widget fo ...

  2. Webwork 学习之路【03】核心类 ServletDispatcher 的初始化

    1. Webwork 与 Xwork 搭建环境需要的的jar 为:webwork-core-1.0.jar,xwork-1.0.jar,搭建webwork 需要xwork 的jar呢?原因是这样的,W ...

  3. Hibernate核心类用法-使用Transaction管理事务

    一个典型的事务应该使用下面的形式 在创建完Session对象后即使用beginTransaction()启动事务 从此开始直到commit()之间的代码 都会处于同一个事务中 这两个函数之间所有的数据 ...

  4. 理解Lucene索引与搜索过程中的核心类

    理解索引过程中的核心类 执行简单索引的时候需要用的类有: IndexWriter.ƒDirectory.ƒAnalyzer.ƒDocument.ƒField 1.IndexWriter IndexWr ...

  5. android的消息处理有三个核心类:Looper,Handler和Message。

    android的消息处理机制(图+源码分析)——Looper,Handler,Message   作为 一名android程序员,我学习android的一大乐趣是可以通过源码学习google大牛们的设 ...

  6. codeigniter框架扩展核心类---实现前台后台视图的分离

    1. 扩展核心类,主要作用就是扩展系统现在的功能. 为前台增加独立的视图文件夹: a. 自定义路径常量 :在application ->config/  constants.php中增加 /*m ...

  7. Activiti源码分析(框架、核心类。。。)

    http://jiangwenfeng762.iteye.com/blog/1338553 Activiti是业界很流行的java工作流引擎,关于Activiti与JBPM5的关系和如何选择不是本文要 ...

  8. Spring Security——核心类简介——获得登录用户的相关信息

    核心类简介 目录 1.1     Authentication 1.2     SecurityContextHolder 1.3     AuthenticationManager和Authenti ...

  9. lucene原理及源码解析--核心类

    马云说:大家还没搞清PC时代的时候,移动互联网来了,还没搞清移动互联网的时候,大数据时代来了. 然而,我看到的是:在PC时代搞PC的,移动互联网时代搞移动互联网的,大数据时代搞大数据的,都是同一伙儿人 ...

随机推荐

  1. Sql server2012 常见异常处理

    网络相关 无法通过IP(127.0.0.1 或者其他本机)连接 确保TCP/IP功能开启 打开1433端口 权限相关 代理的权限,通过更改有最高权限的用户,或者给该用户指定的权限 给域用户开通SQLS ...

  2. 微软准备开源PowerShell

    微软有计划在近期内开源PowerShell 近日微软再次在向开源投出橄榄枝, PowerShell是面向Windows和Windows Server的自动化平台和脚本语言,帮助用户简化系统的管理.在纳 ...

  3. angular学习笔记(二十九)-$q服务

    angular中的$q是用来处理异步的(主要当然是http交互啦~). $q采用的是promise式的异步编程.什么是promise异步编程呢? 异步编程最重要的核心就是回调,因为有回调函数,所以才构 ...

  4. TCP/IP协议中网关和子网掩码概念

    网关: 不同网段的IP是不能直接互通的,需要一个设备来转发,这个设备就是网关,一般就是路由器,那么路由器的地址就是网关地址. 比如192.168.2.31要往192.168.3.31发送一条消息,他们 ...

  5. rpc框架之avro 学习 1 - hello world

    avro是hadoop的一个子项目,提供的功能与thrift.Protocol Buffer类似,都支持二进制高效序列化,也自带RPC机制,但是avro使用起来更简单,无需象thrift那样生成目标语 ...

  6. Github 使用

    创建repository 可以在Github上无限制使用public repository进行源代码管理,创建一个repository很简单,不多说了. 获取代码到本地 首先要安装Git,然后使用命令 ...

  7. sql case 用法总结

    快下班了,抽点时间总结一下sql 的 case 用法. sql 里的case的作用: 用于计算条件列表的表达式,并返回可能的结果之一.sql 的case 类型于编程语言里的 if-esle if-el ...

  8. CSS3系列之3D制作

    一.序 博主最近这些天,突发奇想的想研究一下CSS3的东西,从而提升一下CSS的能力,在学习的过程中发现其实CSS3是一个挺复杂的东西,深入的研究,你可能会涉及到初中的光学理论来帮助理解一些概念,同时 ...

  9. Javascript execCommon

    http://blog.csdn.net/woshinia/article/details/18664903 https://developer.mozilla.org/zh-CN/docs/Web/ ...

  10. 【javascript】箭头函数

    ES6标准新增了一种新的函数:Arraw Function(箭头函数). x => x * x 这个函数相当于 function (x){ return x * x; } 题外话:user st ...