vertx模块DeploymentManager部署管理器
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部署管理器的更多相关文章
- python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。
本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...
- Node线上部署管理器PM2
PM2是一个带有负载均衡功能的Node应用的进程管理器.PM2可以利用服务器上的所有CPU,并保证进程永远都活着,0秒的重载,部署管理多个Node项目.PM2是Node线上部署完美的管理工具. PM2 ...
- python爬虫模块之URL管理器模块
URL管理器模块 一般是用来维护爬取的url和未爬取的url已经新添加的url的,如果队列中已经存在了当前爬取的url了就不需要再重复爬取了,另外防止造成一个死循环.举个例子 我爬www.baidu. ...
- 利用Azure虚拟机安装Dynamics 365 Customer Engagement之七:安装前端服务器及部署管理器
我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...
- Tkinter模块:Grid几何管理器
Tkinter模块是Python的标准库模块之一,也是使用Python语言进行图形化用户界面(GUI)开发的基础. 本文介绍一下Tkinter模块的Grid几何管理器. 使用VB.MFC进行GUI开发 ...
- 对于React各种状态管理器的解读
首先我们要先知道什么是状态管理器,这玩意是干啥的? 当我们在多个页面中使用到了相同的属性时就可以用到状态管理器,将这些状态存到外部的一个单独的文件中,不管在什么时候想使用都可以很方便的获取. reac ...
- JS模块规范 前端模块管理器
一:JS模块规范(为了将js文件像java类一样被import和使用而定义为模块, 组织js文件,实现良好的文件层次结构.调用结构) A:CommonJS就是为JS的表现来制定规范,因为js没有模块的 ...
- Webpack: 为Web开发而生的模块管理器[转]
Webpack: 为Web开发而生的模块管理器 原文地址:http://hanjianwei.com/2014/09/10/webpack-package-manager-for-web/ 10 Se ...
- .NET持续集成与自动化部署之路第二篇——使用NuGet.Server搭建公司内部的Nuget(包)管理器
使用NuGet.Server搭建公司内部的Nuget(包)管理器 前言 Nuget是一个.NET平台下的开源的项目,它是Visual Studio的扩展.在使用Visual Studio开发基 ...
随机推荐
- echarts 页面对应更改
---legrnd legend: { icon: "circle", orient: 'vertical', right: 10, top: 20, bottom: 20, da ...
- [ffmpeg] 滤波
ffmpeg中有很多已经实现好的滤波器,这些滤波器的实现位于libavfilter目录之下,用户需要进行滤波时,就是是调用这些滤波器来实现的.ffmpeg对于调用滤波器有一整套的调用机制. 基本结构 ...
- 拆系数FFT
学习内容:国家集训队2016论文 - 再谈快速傅里叶变换 模板题:http://uoj.ac/problem/34 1.基本介绍 对长度为L的\(A(x),B(x)\)进行DFT,可以利用 \[ \b ...
- 使用apidoc生成项目文档
[1]npm install apidoc -g 全局安装apidoc [2]apidoc -v 查看是否安装成功 [3]apidoc.json apidoc的项目级配置文件,它必须位于整个工程目录顶 ...
- centos7升级内核至最新
应用背景: 最近在接触docker,其对内核版本要求较高,就连目前使用的centos7.x默认内核版本为3.10.0-xxx,也是刚好满足其最低要求,故借此机会记录一下升级内核的操作步骤. 测试环境: ...
- sqlserver建立远程查询
开始远程查询前: ----open:Ad Hoc Distributed QueriesEXEC sp_configure 'show advanced options',1reconfigureex ...
- mysql删除多个重复数据,多个字段添加唯一性索引
需求:删除station_id.ab_data_time.item_code_id.data_cycle.ab_value 字段重复的记录 #查询重复的数据 select b.id,b.station ...
- linux的sed命令(一)
转自:https://www.cnblogs.com/ginvip/p/6376049.html Sed 简介 sed 是一种新型的,非交互式的编辑器.它能执行与编辑器 vi 和 ex 相同的编辑任务 ...
- sql连接查询中的分类
sql连接查询中的分类 1.内连接(结果不保留表中未对应的数据) 1.1等值连接:关联条件的运算符是用等号来连接的. 1.2不等值连接:连接条件是出等号之外的操作符 1.3自然连接:特殊的等值连接,在 ...
- Microsoft Internet Explorer v11 / XML External EntityInjection 0day
[+] Credits: John Page (aka hyp3rlinx) [+] Website: hyp3rlinx.altervista.org[+] Source: http://hyp3 ...