<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-ignite</artifactId>
<version>5.0.1</version>
</dependency>
Vert.x 的 Apache Ignite 集群管理器
这是 Vert.x 的集群管理器实现,它使用 Apache Ignite。
在 Vert.x 中,集群管理器用于多种功能,包括
-
集群中 Vert.x 节点的发现和组成员管理
-
维护集群范围的主题订阅者列表(以便我们知道哪些节点对哪些事件总线地址感兴趣)
-
分布式 Map 支持
-
分布式锁
-
分布式计数器
集群管理器*不*处理事件总线节点间传输,这由 Vert.x 直接通过 TCP 连接完成。
Vert.x 集群管理器是一个可插拔组件,因此您可以选择您想要的,或最适合您环境的。因此,您可以用此实现替换默认的 Vert.x 集群管理器。
使用 Ignite 集群管理器
如果 jar 包在您的类路径中,Vert.x 将自动检测并将其用作集群管理器。请确保您的类路径中没有其他集群管理器,否则 Vert.x 可能会选择错误的。
或者,您可以配置以下系统属性来指示 Vert.x 使用此集群管理器:-Dvertx.clusterManagerFactory=io.vertx.spi.cluster.ignite.IgniteClusterManager
从命令行使用 Vert.x
vertx-ignite-5.0.1.jar
应位于 Vert.x 安装的 lib
目录中。
在 Maven 或 Gradle 项目中使用 Vert.x
添加对该工件的依赖。
-
Maven(在您的
pom.xml
中)
-
Gradle(在您的
build.gradle
文件中)
compile 'io.vertx:vertx-ignite:5.0.1'
编程方式指定集群管理器
您也可以通过编程方式指定集群管理器。为此,只需在创建 Vert.x 实例时在选项中指定它,例如
ClusterManager clusterManager = new IgniteClusterManager();
VertxOptions options = new VertxOptions().setClusterManager(clusterManager);
Vertx.clusteredVertx(options, res -> {
if (res.succeeded()) {
Vertx vertx = res.result();
} else {
// failed!
}
});
配置集群管理器
注意:从 2.0 版本开始,Apache Ignite 引入了一种新的堆外内存架构。所有缓存默认都使用堆外内存。新的内存架构在 Ignite 虚拟内存 文章中进行了描述。
使用配置文件
集群管理器通过 jar 包中包含的 default-ignite.json
文件进行配置。
如果您想覆盖此配置,您可以在类路径中提供 ignite.json
文件,它将替代使用。该配置映射到 IgniteOptions
,您可以在其中找到每个单独选项的更多详细信息。
在下面的示例中,默认配置被扩展以激活集群通信的 TLS。
{
"cacheConfiguration": [{
"name": "__vertx.*",
"cacheMode": "REPLICATED",
"atomicityMode": "ATOMIC",
"writeSynchronizationMode": "FULL_SYNC"
}, {
"name": "*",
"cacheMode": "PARTITIONED",
"backups": 1,
"readFromBackup": false,
"atomicityMode": "ATOMIC",
"writeSynchronizationMode": "FULL_SYNC"
}],
"sslContextFactory": {
"protocol": "TLSv1.2",
"jksKeyCertOptions": {
"path": "server.jks",
"password": "changeme",
},
"jksTrustOptions": {
"path": "server.jks",
"password": "changeme",
},
"trustAll": false
},
"metricsLogFrequency": 0,
"shutdownOnSegmentation": true
}
作为 JSON 格式的替代,您可以使用原生的 Ignite XML 配置。您可以在类路径中提供一个 ignite.xml
文件,它将替代使用。
首先,添加 ignite-spring
依赖。
-
Maven(在您的
pom.xml
中)
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-spring</artifactId>
<version>${ignite.version}</version>
</dependency>
-
Gradle(在您的
build.gradle
文件中)
compile 'org.apache.ignite:ignite-spring:${ignite.version}'
然后添加一个 ignite.xml
文件,如下所示
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<bean class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="discoverySpi">
<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
<property name="ipFinder">
<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder"/>
</property>
</bean>
</property>
<property name="cacheConfiguration">
<list>
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="__vertx.*"/>
<property name="cacheMode" value="REPLICATED"/>
<property name="atomicityMode" value="ATOMIC"/>
<property name="writeSynchronizationMode" value="FULL_SYNC"/>
</bean>
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="*"/>
<property name="cacheMode" value="PARTITIONED"/>
<property name="backups" value="1"/>
<property name="readFromBackup" value="false"/>
<property name="atomicityMode" value="ATOMIC"/>
<property name="affinity">
<bean class="org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction">
<property name="partitions" value="128"/>
</bean>
</property>
<property name="writeSynchronizationMode" value="FULL_SYNC"/>
</bean>
</list>
</property>
<property name="gridLogger">
<bean class="io.vertx.spi.cluster.ignite.impl.VertxLogger"/>
</property>
<property name="metricsLogFrequency" value="0"/>
</bean>
</beans>
JSON 格式是 XML 配置的简化版本,详细信息请参见 Apache Ignite 文档。
编程方式配置
您也可以通过编程方式指定配置
IgniteConfiguration cfg = new IgniteConfiguration();
// Configuration code (omitted)
ClusterManager clusterManager = new IgniteClusterManager(cfg);
VertxOptions options = new VertxOptions().setClusterManager(clusterManager);
Vertx.clusteredVertx(options, res -> {
if (res.succeeded()) {
Vertx vertx = res.result();
} else {
// failed!
}
});
集群故障排除
如果默认的多播配置不起作用,以下是一些常见原因
机器上未启用多播。
默认情况下,集群管理器使用 TcpDiscoveryMulticastIpFinder
,因此需要 IP 多播。在某些系统上,需要将多播路由添加到路由表,否则将使用默认路由。
请注意,某些系统不查询路由表进行 IP 多播路由,只查询单播路由
MacOS 示例
# Adds a multicast route for 224.0.0.1-231.255.255.254
sudo route add -net 224.0.0.0/5 127.0.0.1
# Adds a multicast route for 232.0.0.1-239.255.255.254
sudo route add -net 232.0.0.0/5 192.168.1.3
请在 Google 上搜索更多信息。
使用错误的网络接口
如果您的机器上有多个网络接口(如果您在机器上运行 VPN 软件也可能出现这种情况),那么 Apache Ignite 可能正在使用错误的接口。
要告诉 Ignite 使用特定接口,您可以使用 localHost
属性向 IgniteConfiguration
类型的 bean 提供该接口的 IP 地址。例如
{
"localHost": "192.168.1.20"
}
当 Vert.x 在集群模式下运行时,您还应确保 Vert.x 知道正确的接口。在命令行中运行时,可以通过指定 cluster-host
选项来完成此操作
vertx run myverticle.js -cluster -cluster-host your-ip-address
其中 your-ip-address
是您在 Apache Ignite 配置中指定的相同 IP 地址。
如果以编程方式使用 Vert.x,您可以使用 .setHost(java.lang.String)
来指定此项。
使用 VPN
这是上述情况的一种变体。VPN 软件通常通过创建虚拟网络接口来工作,而这些接口通常不支持多播。如果您正在运行 VPN,并且没有在 Ignite 配置和 Vert.x 中指定要使用的正确接口,那么可能会选择 VPN 接口而不是正确的接口。
因此,如果您正在运行 VPN,您可能需要按照上一节所述,配置 Ignite 和 Vert.x 都使用正确的接口。
当多播不可用时
在某些情况下,您可能无法使用多播,因为它在您的环境中可能不可用。在这种情况下,您应该使用相应的 IP 查找器配置另一种传输方式,例如使用 TcpDiscoveryVmIpFinder
来使用 TCP 套接字,或使用 TcpDiscoveryS3IpFinder
来使用 Amazon S3。
有关可用的 Ignite 传输及其配置方法的更多信息,请查阅 Ignite 集群 文档。
启用日志记录
在排查集群问题时,通常获取 Ignite 的日志输出以查看其是否正确形成集群是很有用的。您可以通过在类路径中添加一个名为 vertx-default-jul-logging.properties
的文件来完成此操作(使用默认的 JUL 日志记录时)。这是一个标准的 java.util.logging (JUL) 配置文件。在其中设置
org.apache.ignite.level=INFO
并且
java.util.logging.ConsoleHandler.level=INFO
java.util.logging.FileHandler.level=INFO
JDK17 及更高版本
添加 VM 选项
--add-opens=java.base/java.nio=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.base/java.lang.invoke=ALL-UNNAMED
--add-opens=java.base/java.lang=ALL-UNNAMED