DeploymentManager

public DeploymentManager(VertxInternal vertx) {
this.vertx = vertx;
loadVerticleFactories();
} /**
* ServiceHelper本质对jdk ServiceLoader的封装,vertx大量使用 SPI 扩展功能实现
*/
private void loadVerticleFactories() {
Collection<VerticleFactory> factories = ServiceHelper.loadFactories(VerticleFactory.class);
factories.forEach(this::registerVerticleFactory);
VerticleFactory defaultFactory = new JavaVerticleFactory();
defaultFactory.init(vertx);
defaultFactories.add(defaultFactory);
}

verticle部署

/**
* 部署verticle
* @params identifier 类全限定名称
* @params options 部署选项
* @params completionHandler 回调处理逻辑
*/
public void deployVerticle(String identifier,
DeploymentOptions options,
Handler<AsyncResult<String>> completionHandler) {
if (options.isMultiThreaded() && !options.isWorker()) {
throw new IllegalArgumentException("If multi-threaded then must be worker too");
}
//获取context
ContextImpl callingContext = vertx.getOrCreateContext();
//jdk9+不支持 isolationGroup,通常情况都不会使用isolationGroup
ClassLoader cl = getClassLoader(options, callingContext);
// deployment Id 采用 UUID
doDeployVerticle(identifier, generateDeploymentID(), options, callingContext, callingContext, cl, completionHandler);
} /**
* 部署verticle 逻辑
*/
private void doDeployVerticle(String identifier,
String deploymentID,
DeploymentOptions options,
ContextImpl parentContext,
ContextImpl callingContext,
ClassLoader cl,
Handler<AsyncResult<String>> completionHandler) {
//根据identifier查找对应的 xxFactory,查找不到使用默认JavaVerticleFactory
List<VerticleFactory> verticleFactories = resolveFactories(identifier);
Iterator<VerticleFactory> iter = verticleFactories.iterator();
doDeployVerticle(iter, null, identifier, deploymentID, options, parentContext, callingContext, cl, completionHandler);
} private void doDeployVerticle(Iterator<VerticleFactory> iter,
Throwable prevErr,
String identifier,
String deploymentID,
DeploymentOptions options,
ContextImpl parentContext,
ContextImpl callingContext,
ClassLoader cl,
Handler<AsyncResult<String>> completionHandler) {
if (iter.hasNext()) {
//是否解析,default false
...
//执行部署verticle逻辑
fut.setHandler(ar -> {
Throwable err;
if (ar.succeeded()) {
//判断解析之后名称是否相等
...
if (verticleFactory.blockingCreate()) {//是否是阻塞创建
/**根据instances数量执行deploy*/
vertx.<Verticle[]>executeBlocking(createFut -> {
try {
Verticle[] verticles = createVerticles(verticleFactory, identifier, options.getInstances(), cl);
createFut.complete(verticles);
} catch (Exception e) {
createFut.fail(e);
}
}, res -> {
if (res.succeeded()) {
doDeploy(identifier, deploymentID, options, parentContext, callingContext, completionHandler, cl, res.result());
} else {
// 失败继续执行下一个
doDeployVerticle(iter, res.cause(), identifier, deploymentID, options, parentContext, callingContext, cl, completionHandler);
}
});
return;
} else {
try {
/**根据instances数量执行deploy*/
Verticle[] verticles = createVerticles(verticleFactory, identifier, options.getInstances(), cl);
doDeploy(identifier, deploymentID, options, parentContext, callingContext, completionHandler, cl, verticles);
return;
} catch (Exception e) {
err = e;
}
}
}
}
...
} /**
* 根据instances数量初始化verticle实例
*/
private Verticle[] createVerticles(VerticleFactory verticleFactory, String identifier, int instances, ClassLoader cl) throws Exception {
Verticle[] verticles = new Verticle[instances];
for (int i = ; i < instances; i++) {
verticles[i] = verticleFactory.createVerticle(identifier, cl);
if (verticles[i] == null) {
throw new NullPointerException("VerticleFactory::createVerticle returned null");
}
}
return verticles;
} private void doDeploy(String identifier, String deploymentID, DeploymentOptions options,
ContextImpl parentContext,
ContextImpl callingContext,
Handler<AsyncResult<String>> completionHandler,
ClassLoader tccl, Verticle... verticles) {
// Copy一份副本
JsonObject conf = options.getConfig() == null ? new JsonObject() : options.getConfig().copy();
String poolName = options.getWorkerPoolName();//获取定义的worker Pool 名称 Deployment parent = parentContext.getDeployment();
DeploymentImpl deployment = new DeploymentImpl(parent, deploymentID, identifier, options); AtomicInteger deployCount = new AtomicInteger();
AtomicBoolean failureReported = new AtomicBoolean();
/**根据instances verticle 数量执行多实例,利用CPU多核心*/
for (Verticle verticle: verticles) {
/**
* 三种context类型,默认Standard
* Standard Verticles(eventloop)
* Worker Verticles(DeploymentOptions_workerPoolName & DeploymentOptions_workerPoolSize & DeploymentOptions_worker)
* Multi-threaded worker verticles(worker Verticles 基础上 & DeploymentOptions_multiThreaded)
*/
WorkerExecutorImpl workerExec = poolName != null ? vertx.createSharedWorkerExecutor(poolName, options.getWorkerPoolSize(), options.getMaxWorkerExecuteTime()) : null;
WorkerPool pool = workerExec != null ? workerExec.getPool() : null;
ContextImpl context = options.isWorker() ? vertx.createWorkerContext(options.isMultiThreaded(), deploymentID, pool, conf, tccl) :
vertx.createEventLoopContext(deploymentID, pool, conf, tccl); if (workerExec != null) {//使用worker verticle 添加Close Hook
context.addCloseHook(workerExec);
}
//绑定当前context
context.setDeployment(deployment);
deployment.addVerticle(new VerticleHolder(verticle, context)); //执行deploy
context.runOnContext(v -> {
try {
//verticle初始化
verticle.init(vertx, context);
Future<Void> startFuture = Future.future();
//调用deploy verticle的start 方法
verticle.start(startFuture);
//deployVerticle 调用complete方法的回调处理
startFuture.setHandler(ar -> {
if (ar.succeeded()) {
if (parent != null) {//parentVericl不为null,绑定父子映射关系
if (parent.addChild(deployment)) {
deployment.child = true;
} else {
// Orphan
deployment.undeploy(null);
return;
}
}
VertxMetrics metrics = vertx.metricsSPI();//初始化verticle metrics
if (metrics != null) {
metrics.verticleDeployed(verticle);
}
deployments.put(deploymentID, deployment);//添加集合中
//实例数量是否全部部署成功
if (deployCount.incrementAndGet() == verticles.length) {
reportSuccess(deploymentID, callingContext, completionHandler);
}
} else if (failureReported.compareAndSet(false, true)) {//部署失败
deployment.rollback(callingContext, completionHandler, context, ar.cause());
}
});
} catch (Throwable t) {
if (failureReported.compareAndSet(false, true))
deployment.rollback(callingContext, completionHandler, context, t);
}
});
}
}

Verticle Types

Verticle Types : 一、Standard Verticles、二、Worker Verticles、三、Multi-threaded worker verticles.
本质还是eventloop处理connection、read/write、encode/decode , 事件处理(eventHandler)在配置
何种类型的verticle相应的context处理 , 调度逻辑在VertxHandler类配置的context调度,
和vertx.executeBlocking->{...} 相同效果.

Context Class diagram 如图:

DeploymentOptions

//添加配置,当前部署verticle共享配置
private JsonObject config; //是否使用WorkerContext
private boolean worker; /**
* 是否使用mutil workerContext,不推荐,通常使用eventloop或worker,
* 运行是在worker pool不同线程执行,需考虑线程安全,如果使用将无法使用其他多数模块
*/
private boolean multiThreaded; //隔离组配置,部署隔离相关配置,不推荐,并且JDK9+不支持
private String isolationGroup; //定义的worker pool名称前缀
private String workerPoolName; // 定义打worker pool线程数量
private int workerPoolSize; //定义最大worker poll 执行时间,Thread超过时间阀值输出level:warn报警 ,不配置默认 60s
private long maxWorkerExecuteTime; //是否启用HA(高可用),默认false
private boolean ha; //配置额外的Classpath路径,如果未设置isolationGroup 则忽略
private List<String> extraClasspath; //配置verticle 实例数量
private int instances; //配置隔离的类,路径为完全限定名,可使用通配符 *
private List<String> isolatedClasses;

vertx模块DeploymentManager部署管理器的更多相关文章

  1. python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。

    本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...

  2. Node线上部署管理器PM2

    PM2是一个带有负载均衡功能的Node应用的进程管理器.PM2可以利用服务器上的所有CPU,并保证进程永远都活着,0秒的重载,部署管理多个Node项目.PM2是Node线上部署完美的管理工具. PM2 ...

  3. python爬虫模块之URL管理器模块

    URL管理器模块 一般是用来维护爬取的url和未爬取的url已经新添加的url的,如果队列中已经存在了当前爬取的url了就不需要再重复爬取了,另外防止造成一个死循环.举个例子 我爬www.baidu. ...

  4. 利用Azure虚拟机安装Dynamics 365 Customer Engagement之七:安装前端服务器及部署管理器

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  5. Tkinter模块:Grid几何管理器

    Tkinter模块是Python的标准库模块之一,也是使用Python语言进行图形化用户界面(GUI)开发的基础. 本文介绍一下Tkinter模块的Grid几何管理器. 使用VB.MFC进行GUI开发 ...

  6. 对于React各种状态管理器的解读

    首先我们要先知道什么是状态管理器,这玩意是干啥的? 当我们在多个页面中使用到了相同的属性时就可以用到状态管理器,将这些状态存到外部的一个单独的文件中,不管在什么时候想使用都可以很方便的获取. reac ...

  7. JS模块规范 前端模块管理器

    一:JS模块规范(为了将js文件像java类一样被import和使用而定义为模块, 组织js文件,实现良好的文件层次结构.调用结构) A:CommonJS就是为JS的表现来制定规范,因为js没有模块的 ...

  8. Webpack: 为Web开发而生的模块管理器[转]

    Webpack: 为Web开发而生的模块管理器 原文地址:http://hanjianwei.com/2014/09/10/webpack-package-manager-for-web/ 10 Se ...

  9. .NET持续集成与自动化部署之路第二篇——使用NuGet.Server搭建公司内部的Nuget(包)管理器

    使用NuGet.Server搭建公司内部的Nuget(包)管理器 前言     Nuget是一个.NET平台下的开源的项目,它是Visual Studio的扩展.在使用Visual Studio开发基 ...

随机推荐

  1. Linux查看用户所属用户组

    1.查看当前用户所属用户组 [oracle@serverhl ~]$ groups oinstall dba 2.查看<user1>, <user2> 和 <user3& ...

  2. 常见的cmd命令

    1.查看所有端口的使用情况:netstat -ano

  3. Linux下MySql的登陆和管理操作

    一.mysql数据库启停1.linux下启动mysql的命令:    mysqladmin start/ect/init.d/mysql start (前面为mysql的安装路径)2.linux下重启 ...

  4. Logback日志基础配置以及自定义配置

    Logback日志基础配置 logback日志配置有很多介绍,但是有几个非常基础的,容易忽略的.下面是最简单的一个配置,注意加粗的描述 <?xml version="1.0" ...

  5. jquery 设置 transform/translate 获取 transform/translate 的值

    //获取 transform 值 var reg=/matrix.(((-)?([0-9]+.)?\d+([, ]+)?){6})./g; var str= progressUI.css(" ...

  6. practice01

    1. 组合数公式: C(n, k) =C(n-1, k) +C(n-1, k-1) 要求利用该公式写递归函数求组合数. #include <stdio.h> int C(int a,int ...

  7. P4178 Tree(点分治)

    题面要求小于等于K的路径数目,我么很自然的想到点分治(不会的就戳我) 这道题的统计答案与模板题不一样的地方是由等于K到小于等于K 那么我们可以把每一个子节点到当前根(重心)的距离排序,然后用类似双指针 ...

  8. yii2 命令行执行php命令 commands(命令)

    YII2可以在命令行执行php命令,作为半路出家的撩妹君可谓是抠脚福音.作为一个屌丝级的程序员必须要有智能提示代码的IDE,比如PHPstorm.至于如何免费使用嘛..... 首先明白YII2自带的c ...

  9. CF350E 【Wrong Floyd】

    Description 给定n个点,m条边,k个标记点,hack掉给出的程序. Solution 先考虑不可能hack掉的情况.当所有点都是标记点的时候肯定不能hack掉,也就是\(n=k\).还有就 ...

  10. pytest 14 使用自定义标记mark

    标记失败用到的情况是,本身就知道这是失败的例子,所以,不用让他运行,直接跳过.或者是依赖于某个方法,某个方式失败的话,用例直接标记成失败. 标记失败有两种方法,一种是方法内部,一种是方法外部.内部用p ...