集群管理器
在Vert.x中群集管理器被用于多个功能,包括:
发现和编组群集中Vert.x节点成员。
维护全局主题订阅列表(因为需要知道哪个节点对哪个事件总线地址感兴趣)
分布式映射支持
分步式锁
分步式计数器
集群管理器不处理事件总内节点传输这是Vert.x直接通过TCP连接完成的。在Vert.x分布环境下默认的群集管理器是一个用Hazelcast实现,但这很容易被不同的实现替换,因为Vert.x的群集管理器是可接插的。一个群集管理器必须实现ClusterManager接口。Vert.x在运行时使用Java服务加载器功能在类路径定中位群集管理器实例。
如果正在命令行使用Vert.x并且想使用集群,应该确认Vert.x安装路径中的lib目录是否包含群集管理器jar包。
如果你在Maven或者Gradle项目中使用Vert.x,仅需要添加群集管理器jar包作为项目的依赖。
如是嵌入应用Vert.x,使用setClusterManager方法,通过程序指定群集管理器。
日志
Vert.x日志使用其内建的日志API。默认实现使用JDK(JUL)日志,所以不需要另外的日志依赖。
配置JUL日志
一般使JUL方式是通过设置叫做:java.util.logging.config.file的系统属性,指定一个配置文件。关于这个及JUL配置文件结构的更多信息,请参考JUL日志文档。Vert.x提供了一个轻量的更方便的方法设置配置文件,不需要设系统属性。只需在内路径中(也可以在fatjar中)提供JUL配置文件,此配置文件命必须是vertx-default-jul-logging.properties。Vert.x将使用
此文件配置JUL。
使用其他的日志框架
如果不想Vert.x使用JUL作为自己的日志。可以提定其他的日志框架例如LOG4j,SLF4j。作这个需要设置叫vertx.logger-delegate-factory-class-name的系统属性,此属性值是一个实现了LogDelegateFactory接口的类,同时类必须在类路径中。Vert.x提供了预构建的Log4j(版本1),Log2J 2 和 SLF4J实现,类名如下:
io.vertx.core.logging.Log4jLogDelegateFactory
io.vertx.core.logging.Log4j2LogDelegateFactory
io.vertx.core.logging.SLF4JLogDelegateFactory。
为了使用这些日志实现,必须确认相关的Log4j和SLF4J的jar包在类路径上。
注意,为Log4j提供的日志代理不支持参数化消息。针对Log4j 2的代理使用与SLF4J代理类似的{}语法。JUL代理使用{X}语法。
在应用应用日志
Vert.x自己仅是一个库,只要你喜欢可在应用中使用任意日志库和其日志API。然而,只要喜欢,也能向上面描述的一样使用Vert.x的日志设施为你的应用提供日志。为了做到那些,能过使用LoggerFactory获取一个Logger实例,用此实例记录日志。例事:
Logger logger =LoggerFactory.getLogger(className);
logger.info("something happened");
logger.error("oops!", exception);
主机名解析
Vert.x使用地址解析器将主机名解析成IP地址以代替JVM内建的阻塞解析器。一个主机名解析成IP地址要用到:
操作系统的hosts文件
依靠服务器进行另外的DNS查询
Vert.x默认使用来自环境系统DNS服务器地址列表,如果不能获取这个列表,Vert.x将使用谷歌的公共DNS服务器“8.8.8.8”和”4.4.4.4”。DNS服务器也可通过Vert.x实例进行配置
Vertx vertx = Vertx.vertx(new VertxOptions().
setAddressResolverOptions(
new AddressResolverOptions().
addServer("192.168.0.1").
addServer("192.168.0.2:40000"))
);
默认的DNS服务器端口是53,当一个服务器使用不同端口时,端口可以用冒号与IP地址分隔。解析器也可以用一个hosts文件替代。
Vertx vertx = Vertx.vertx(new VertxOptions().
setAddressResolverOptions(
new AddressResolverOptions().
setHostsPath("/path/to/hosts"))
);
默认解析器将从环境中使用系统DNS查找域名。另一种是提供一个清楚的域名查询列表:
Vertx vertx = Vertx.vertx(new VertxOptions().
setAddressResolverOptions(
newAddressResolverOptions().addSearchDomain("foo.com").addSearchDomain("bar.com"))
);
在使用查询域名列表时,点的数量边界值是1,可以用setNdots方法设置。
注意:有时可能要求使用JVM内建的解析器,用JVM系统属性Dvertx.disableDnsResolver=true 激法此行为
高可用与故障备份
Vert.x允许用高可用支持运行verticle。在那种情况下,在一个正在运行的verticle实例突然崩溃,verticle会被迁移到另外的vertx实例。当然此实例必须在同一个群集中。
自动恢复
当vert.x启用HA后,如果verticle所在的vert.x实例失败或宕机,verticle会自动被布署了集群中的其他vert.x实例。我们称之为verticle的故障恢复。为了启用HA运行verticle只需在命令行添加-ha标识。
vertx run my-verticle.js –ha
现在HA开始工作了,在集群中你需要多个Vert.x实例,所以让我们通知你已经有启动了另外一个Vert.x实例,例如:
vertx run my-other-verticle.js –ha
如果正在运行my-verticle.js的Vert.x实例宕掉(可以用kill-9方式杀掉进程),正在运行my-other-verticle.js的Vert.x实例将自动布署my-verticle.js,所以现在Vert.x实例上正运行两个verticles.
注意:如果第二个vert.x实例已经访问了verticle文件(这里是my-verticle.js),这样刮迁移仅是可能。重要:请注意,干净地清除Vert.x实例将不会产生故障恢复,例如Ctrl+C或者kill –SIGINT。
也可以初始化不运任何verticle实例的裸Vert.x实例,群集中的他们也将故障恢复。简单这样做可以启动一个裸实例。
vertx run –ha
在使用-ha开关时,你不必提供-cluster开关,因为如果使用HA,集群就是前题。
注意:取决于群集的配置,可以自定义群集管理器配置(默认Hazelcast),并且/或者添加cluster-host与cluster-port参数。
HA组
在使用HA运行一个Vert.x实例时,也可以选择性地提供一个HA组,一个HA组表示集群中节点的逻辑组。只有在相同的HA组中的节点会故障恢复到另外一个。如果不指定一个HA组,默认组是__DEFAULT__将被使用
为了指定HA组,在运行verticle时指定-hagroup选项,例如。
vertx run my-verticle.js -ha -ha-group my-group
让我们看一个例子:
第一终端:
vertx run my-verticle.js -ha -hagroup g1
第二终端,国我们用相同的组运行另一个verticle
vertx run my-other-verticle.js -ha -hagroup g1
最后,在第三个终端,加载使用不同的组加载另外verticle:
vertx run yet-another-verticle.js -ha -hagroupg2
如果杀掉第一个终端的实例,verticle实例将会恢复到第二个终端上,而不是作为不同组的第三个终端上的实例。
如果杀掉第三个终端上的实例,将不会恢复,因为在这个组中没有其他vert.x实例。
处理网络分区-仲裁
HA实现也支持仲裁。仲裁指的是最小的投票数,表示分布式事件为了在分布式系统上执行操作必须要得到的票数。
在开始一个Vert.x实例的HA布署之前,可以指定一个法定投票数量。在此上下文中,一法定投票数是特定群集中特定组中节点的最小数,法定票数为Q = 1+N/2,这里的N是组中的节点数。如果群集中的节点数少于Q,HA部署交御载。如果集群的投票数再次达到,将会重新布署。为了做到这些,可以阻止网络分区,也叫脑裂。
这里有更多的仲裁信息http://en.wikipedia.org/wiki/Quorum_(distributed_computing)
为了支行仲裁的Vert.x实例,可以在命令行上使用-quorum参数。
第一个终端:
vertx run my-verticle.js -ha -quorum 3
这时Vert.x实例将会启动,但是不布署模块因为只有一个节点在集群中,而不是3。
第二个终端:
vertx run my-other-verticle.js -ha -quorum 3
这时Vert.x实例将会启动,但是不布署模块因为只有一个节点在集群中,而不是3。
第三个终端,你可以开始另外一个vert.x实例:
vertx run yet-another-verticle.js -ha -quorum 3
现在我们有了三个节点,这是法定节点数。这时模块将会自动布署到所有实例。如果现在关闭或者杀掉其中一个节点,模块将会在其他节点上御载,因为不再达到法定节点数。Quora可以与组联合使用。如果那样,quora将会在每个特定组中被处理。
安全说明
Vert.x一个工具箱,不是一个固执的强迫你按照特定方式做事的框架。这给开发者很大的力量,随之而来的是很好的响应性。作为一个工箱,可能会编写出不安全的应用,所以在开发应用时,特别是而向公共的应用,应当总是小心翼翼。
Web应用程序‘
如果编写一个web应用,作为最好的推荐是直接使用Vert.x-web模块代替Vert.x内核模块,提供资源服务和处理文件上传。
Vert.x-Web使请求中路径规范化,以阻止恶意客户端,用别有用心的URLs访问web根路径以外的资源。文件上传与此相似,Vert.x-Web提供上传文件到磁盘已知的地方,并且在上传的过程中不依赖文件上传的文件名,如果依赖文件名,将会被精心设计地上传到磁盘的不同地方。Vert.x内核模块自身不提这样的检查,所以作为一个开发者,这由你决定是否自己实现他们。
集群的事件总线传输
当在同一个网络的不同的Vert.x节点之间集群事件总时,数据未经加密就被传输,如果机密的数据被发送到不可信网络中的Vert.x节点,不要这样做。
标准安全最佳实践
不论是用Vert.x编写还是其他工具编 官吏,总有一些服务存在潜在的缺陷,所以遵循安全最佳实践必须一贯,特别是面向公共的服务。例如总应该在DMZ区运行并且用一个受限的帐号,如果服和被入侵,这样可限制灾难漫延。