Ignite拥有一项非常出色的"零部署"功能,其工作流程如下:
- Ignite将检查本地类路径上是否有该类(即在系统启动时加载),如果有,则返回该类。在这种情况下,不会从对等节点加载任何类。
- 如果本地没有可用的类,则会向原始节点发送请求以提供类定义。原始节点将发送类字节码定义,然后在工作节点上加载类。这只会发生一次 - 一旦类定义在节点上加载,就不必再次加载。
另外,我写了一个示例代码:
Collection<Long> broadcastResult = compute.broadcast(new IgniteCallable<Long>() {
@Override
public Long call() throws Exception {
long result = 0;
Long total = getTotal(10);
for (int i = 0; i < total; i++) {
LOGGER.info("adding {}, result {}", i, (result = result + i));
}
return result;
}
});
...
public static Long getTotal(long total) {
LOGGER.info("Total:{}", total);
return total;
}
它可以正常工作,远程节点打印了add xxx
日志十次。但我真的很想知道是怎么做到的?
- Ignite如何知道
My IgniteCallable Instance
需要getTotal(long total)
方法? - 当我只给它
My IgniteCallable Instance's Reference
而不是一个类文件时,Ignite如何将My IgniteCallable Instance's Byte Code
传输到远程节点?
请帮帮我,谢谢!
getTotal
方法是静态的,所以封闭类的实例不会被序列化(甚至可能不存在)。但是当服务器节点需要时,该类的字节码将由服务器节点的类加载器加载。 - Valentin KulichenkoIgniteCallable
实例到远程节点执行时,它通常会被序列化。关键点在于远程节点有一个特殊的类加载器,在反序列化过程中,类加载器的resolve()
方法将被调用,并且所有依赖的类都将被传递给类加载器,类加载器将尝试从本地加载类,如果本地有,则直接加载,否则将广播一个Class Fetch
请求并从其他节点获取。但我还不是完全确定或清楚。 - BilboDaiIgniteCallable
源代码中被使用时,将只会在JVM执行到需要该依赖类的地方时才会被加载。 - dmagdaClassloader
工作的详细信息。 - BilboDai