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开发基 ...
随机推荐
- IIS日志分析工具
发现一个强大的图形化IIS日志分析工具:Log Parser Studio. 安装 需要先安装Log Parser下载地址:http://www.microsoft.com/en-us/downloa ...
- Java 学习(1)----- java 学习的总体感觉
好久没有更新博客了,是因为最近在集中精力学习java, Java 的基础知识确实是比 js 多太多了. 学习java 断断续续的差不多有一年左右的时间, 这一年来,感觉懂了一点,过一段时间又忘记了,总 ...
- luogu P2194 HXY烧情侣
残忍的题面 我们来看这一道题,其实冗长的题目告诉我们一个核心——用tarjan tarjan是用来干什么呢?是用来求强连通分量(代码中指sc) 求出来又有什么用呢?每当我们求出一个强连通分量时,就去计 ...
- JetBrain系列IDE提示Filesystem Case-Sensitivity Mismatch的解决
目录 解决方法 1. 用文本编辑器修改APP包文件中的属性文件(不推荐) 2. 复制或新建属性文件到APP的启动目录,添加对应的属性项(推荐) 解决方法1 1. 用文本编辑器修改APP包文件中的属性文 ...
- pjb fabu
#!/bin/bash PyPath=/opt/shell/mysql LocaName=`pwd` bagname=`basename $LocaName` sleep 1s ConfList=`p ...
- MT【323】向量模的范围
已知单位向量 $\overrightarrow e_1,\overrightarrow e_2$ 的夹角为 $120^\circ$,$\left|x\overrightarrow e_1+y\over ...
- Spring Boot整合Elasticsearch
Spring Boot整合Elasticsearch Elasticsearch是一个全文搜索引擎,专门用于处理大型数据集.根据描述,自然而然使用它来存储和搜索应用程序日志.与Logstash和K ...
- SaltStack配置管理和YAML
配置管理和YAML 配置管理 所谓的配置管理,也称为状态管理,就是可以通过编写文件,文件的内容为安装什么功能.开启什么服务,执行什么任务等信息,然后通过salt的配置管理,指定minion来执行这些操 ...
- Python高级笔记(四) -- 多继承_方法解析顺序表MRO
1. 多继承以及MRO顺序 1.1 单独调用父类的方法 # -*- encoding=utf-8 -*- class Parent(object): def __init__(self, name): ...
- python学习08
python中的异常处理 1.格式 try 语句块 except else finally else 是如果try语句没有异常,就执行,否则不执行 finally 不管程序是否异常,都会执行. 2.异 ...