我在 hazelcast 中启用了用户代码部署以使用入口处理器。 入口处理器和我的实体类已部署到 hazelcast,但未部署紧凑序列化器,因此在成员端,我在实体序列化时遇到异常。如何将我的compactSerializer从客户端部署到hazelcast成员并注册?
紧凑型串行器有两种使用方式。
我将向您展示零配置,因为您正在使用用户代码部署(UCD)。
假设您有如下课程。这个类没有实现了序列化机制。
public class MyWorker {
String name;
public MyWorker(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "MyWorker{" +
"name='" + name + '\'' +
'}';
}
}
我们还有一个 EntryProcessor,如下所示。 EntryProcessor 实现Serialized。所以 MyWorkerEntryProcessor 也是可序列化的。我返回 null 因为我不需要在客户端更新地图结果。
public class MyWorkerEntryProcessor implements EntryProcessor<Integer, MyWorker, MyWorker> {
@Override
public MyWorker process(Map.Entry<Integer, MyWorker> entry) {
MyWorker newWorker = new MyWorker("new-worker1");
entry.setValue(newWorker);
return null;
}
}
按如下方式启动服务器。 UCD 必须在服务器端启用
public static void main(String[] args) {
Config config = new Config();
UserCodeDeploymentConfig ucdConfig = config.getUserCodeDeploymentConfig();
ucdConfig.setEnabled(true);
HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance(config);
}
让我们在客户端使用这些辅助方法。
private static HazelcastInstance getHazelcastClientInstance() {
ClientConfig clientConfig = new ClientConfig();
// UCD
ClientUserCodeDeploymentConfig ucdConfig = clientConfig.getUserCodeDeploymentConfig();
ucdConfig.setEnabled(true);
ucdConfig.addClass(MyWorker.class);
ucdConfig.addClass(MyWorkerEntryProcessor.class);
return HazelcastClient.newHazelcastClient(clientConfig);
}
private static void populateMap(HazelcastInstance hazelcastClientInstance) {
IMap<Integer, MyWorker> myWorkerMap = hazelcastClientInstance.getMap(MAP_NAME);
myWorkerMap.put(KEY, new MyWorker("worker1"));
}
private static void updateWorker(HazelcastInstance hazelcastClientInstance) {
IMap<Integer, MyWorker> myWorkerMap = hazelcastClientInstance.getMap(MAP_NAME);
MyWorkerEntryProcessor entryProcessor = new MyWorkerEntryProcessor();
myWorkerMap.executeOnEntries(entryProcessor);
}
private static void printWorker(HazelcastInstance hazelcastClientInstance) {
IMap<Integer, MyWorker> myWorkerMap = hazelcastClientInstance.getMap(MAP_NAME);
MyWorker worker = myWorkerMap.get(KEY);
LOGGER.info("New Worker : {}", worker);
}
让我们从客户端调用它们
public static void main(String[] args) throws Exception {
// Start client
HazelcastInstance hazelcastClientInstance = getHazelcastClientInstance();
// Do test
populateMap(hazelcastClientInstance);
updateWorker(hazelcastClientInstance);
printWorker(hazelcastClientInstance);
// Shut down HZ clien
hazelcastClientInstance.shutdown();
}
因此,通过零配置紧凑序列化,我不需要做任何事情。从文档中可以看到这句话
也可以使用紧凑序列化,而无需在成员或客户端配置中注册序列化程序。
HZ 自动为我创建一个序列化器。但也有一些限制。再次从文档中。所以你的类只能有某些成员字段类型
目前,Hazelcast 支持从具有上面显示的字段类型和其他一些字段类型的类中提取模式,以方便用户。
对于我在开始时提到的显式序列化情况,您需要注册一个序列化器来成员,而不是部署它。您可以在文档中找到示例
我希望这有帮助
这个答案用于从客户端注册自定义紧凑序列化器。 在客户端有这个类。这次我用了lombok来make,让代码变得更短
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
@Getter
@RequiredArgsConstructor
@ToString
public class MyWorker {
private final String name;
}
在客户端有一个序列化器
public class MyWorkerSerializer implements CompactSerializer<MyWorker> {
@Override
public MyWorker read(CompactReader compactReader) {
String name = compactReader.readString("name");
return new MyWorker(name);
}
@Override
public void write(CompactWriter compactWriter, MyWorker myWorker) {
compactWriter.writeString("name", myWorker.getName());
}
@Override
public String getTypeName() {
return "myworker";
}
@Override
public Class<MyWorker> getCompactClass() {
return MyWorker.class;
}
}
然后按如下方式启动客户端。序列化器已添加到 SerializationConfig
ClientConfig clientConfig = new ClientConfig();
// UCD
ClientUserCodeDeploymentConfig ucdConfig = clientConfig.getUserCodeDeploymentConfig();
ucdConfig.setEnabled(true);
ucdConfig.addClass(MyWorker.class);
ucdConfig.addClass(MyWorkerEntryProcessor.class);
clientConfig.getSerializationConfig()
.getCompactSerializationConfig()
.addSerializer(new MyWorkerSerializer());
HazelcastInstance hazelcastClientInstance =
HazelcastClient.newHazelcastClient(clientConfig);
然后在第一个答案上使用 populateMap(),updateWorker(),printWorker()