Java Hazelcast调用方成员在被调用方成员上发生序列化异常时引发超时异常
我在一个有两个成员的场景中使用了Hazelcast(JAVA,版本3.7.5)。第一个成员通过Java Hazelcast调用方成员在被调用方成员上发生序列化异常时引发超时异常,java,hazelcast,unparseable,Java,Hazelcast,Unparseable,我在一个有两个成员的场景中使用了Hazelcast(JAVA,版本3.7.5)。第一个成员通过IExecutorService将任务委托给第二个成员。经过一些处理后,第二个成员尝试发回一个不可序列化的响应 由于无法发回响应,第二个成员打印与HazelcastSerializationException相关的堆栈跟踪 当没有响应到达时,第一个成员在达到操作心跳超时时抛出一个OperationTimeoutException 目前,当IExecutorService在解析可调用结果时失败时,它会打印
IExecutorService
将任务委托给第二个成员。经过一些处理后,第二个成员尝试发回一个不可序列化的响应
由于无法发回响应,第二个成员打印与HazelcastSerializationException
相关的堆栈跟踪
当没有响应到达时,第一个成员在达到操作心跳超时时抛出一个OperationTimeoutException
目前,当IExecutorService在解析可调用结果时失败时,它会打印一个堆栈跟踪(在被调用方一侧)。
假设我有一个简单的来电者:
private Future<Object> startFlow() {
//This throws an OperationTimeoutException
return hazelcastInstance.getExecutorService("myExecutor").submit(myRunnable);
}
被调用方在解析响应失败后打印stacktrace(请参阅文章末尾)
在我的例子中,不可能知道服务
可能返回什么类型的对象,也不可能信任服务
发回可序列化的对象
我想知道呼叫者端超时的原因。
经过一些搜索,我发现没有配置/API可用于拦截IExecutorService在序列化响应失败时引发的异常
因此,我试图看看是否有可能检查Hazelcast是否可以解析对象,但同样没有成功
有什么想法吗
多谢各位
被调用方打印的stacktrace如下所示:
Exception in thread "hz._hzInstance_1_dev.cached.thread-1" com.hazelcast.nio.serialization.HazelcastSerializationException: Failed to serialize 'com.hazelcast.spi.impl.operationservice.impl.responses.NormalResponse'
at com.hazelcast.internal.serialization.impl.SerializationUtil.handleSerializeException(SerializationUtil.java:73)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toBytes(AbstractSerializationService.java:143)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toBytes(AbstractSerializationService.java:124)
at com.hazelcast.spi.impl.operationservice.impl.OperationServiceImpl.send(OperationServiceImpl.java:427)
at com.hazelcast.spi.impl.operationservice.impl.RemoteInvocationResponseHandler.sendResponse(RemoteInvocationResponseHandler.java:51)
at com.hazelcast.spi.Operation.sendResponse(Operation.java:291)
at com.hazelcast.executor.impl.DistributedExecutorService$CallableProcessor.sendResponse(DistributedExecutorService.java:269)
at com.hazelcast.executor.impl.DistributedExecutorService$CallableProcessor.run(DistributedExecutorService.java:253)
at com.hazelcast.util.executor.CachedExecutorServiceDelegate$Worker.run(CachedExecutorServiceDelegate.java:212)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:76)
at com.hazelcast.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:92)
Caused by: com.hazelcast.nio.serialization.HazelcastSerializationException: Failed to serialize 'com.myomain.UnserialiableObject'
at com.hazelcast.internal.serialization.impl.SerializationUtil.handleSerializeException(SerializationUtil.java:73)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.writeObject(AbstractSerializationService.java:236)
at com.hazelcast.internal.serialization.impl.ByteArrayObjectDataOutput.writeObject(ByteArrayObjectDataOutput.java:371)
at com.hazelcast.spi.impl.operationservice.impl.responses.NormalResponse.writeData(NormalResponse.java:91)
at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.write(DataSerializableSerializer.java:189)
at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.write(DataSerializableSerializer.java:54)
at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.write(StreamSerializerAdapter.java:43)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toBytes(AbstractSerializationService.java:140)
... 12 more
Caused by: com.hazelcast.nio.serialization.HazelcastSerializationException: There is no suitable serializer for class com.myomain.UnserialiableObject
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.serializerFor(AbstractSerializationService.java:469)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.writeObject(AbstractSerializationService.java:232)
... 18 more
public class GlobalSerializerException implements StreamSerializer<Object> {
@Override
public void write(ObjectDataOutput out, Object object) throws IOException {
String objectInfo;
if(object == null){
objectInfo = "Object was null.";
}else{
objectInfo = String.format("Object of class %s and printed as String gives %s", object.getClass().getCanonicalName(), object.toString());
}
objectInfo = "Hazelcast was unable to serialize an object. " + objectInfo;
out.writeUTF(objectInfo);
}
@Override
public Object read(ObjectDataInput in) throws IOException {
String message = in.readUTF();
HazelcastSerializationException hazelcastSerializationException = new HazelcastSerializationException(message);
return hazelcastSerializationException;
}
@Override
public int getTypeId() {
return 63426;
}
@Override
public void destroy() {
}
}
编辑(解决方案)
所以我最终注册了一个全局序列化程序,只要调用它就可以发送一个异常。大概是这样的:
Exception in thread "hz._hzInstance_1_dev.cached.thread-1" com.hazelcast.nio.serialization.HazelcastSerializationException: Failed to serialize 'com.hazelcast.spi.impl.operationservice.impl.responses.NormalResponse'
at com.hazelcast.internal.serialization.impl.SerializationUtil.handleSerializeException(SerializationUtil.java:73)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toBytes(AbstractSerializationService.java:143)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toBytes(AbstractSerializationService.java:124)
at com.hazelcast.spi.impl.operationservice.impl.OperationServiceImpl.send(OperationServiceImpl.java:427)
at com.hazelcast.spi.impl.operationservice.impl.RemoteInvocationResponseHandler.sendResponse(RemoteInvocationResponseHandler.java:51)
at com.hazelcast.spi.Operation.sendResponse(Operation.java:291)
at com.hazelcast.executor.impl.DistributedExecutorService$CallableProcessor.sendResponse(DistributedExecutorService.java:269)
at com.hazelcast.executor.impl.DistributedExecutorService$CallableProcessor.run(DistributedExecutorService.java:253)
at com.hazelcast.util.executor.CachedExecutorServiceDelegate$Worker.run(CachedExecutorServiceDelegate.java:212)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:76)
at com.hazelcast.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:92)
Caused by: com.hazelcast.nio.serialization.HazelcastSerializationException: Failed to serialize 'com.myomain.UnserialiableObject'
at com.hazelcast.internal.serialization.impl.SerializationUtil.handleSerializeException(SerializationUtil.java:73)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.writeObject(AbstractSerializationService.java:236)
at com.hazelcast.internal.serialization.impl.ByteArrayObjectDataOutput.writeObject(ByteArrayObjectDataOutput.java:371)
at com.hazelcast.spi.impl.operationservice.impl.responses.NormalResponse.writeData(NormalResponse.java:91)
at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.write(DataSerializableSerializer.java:189)
at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.write(DataSerializableSerializer.java:54)
at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.write(StreamSerializerAdapter.java:43)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toBytes(AbstractSerializationService.java:140)
... 12 more
Caused by: com.hazelcast.nio.serialization.HazelcastSerializationException: There is no suitable serializer for class com.myomain.UnserialiableObject
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.serializerFor(AbstractSerializationService.java:469)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.writeObject(AbstractSerializationService.java:232)
... 18 more
public class GlobalSerializerException implements StreamSerializer<Object> {
@Override
public void write(ObjectDataOutput out, Object object) throws IOException {
String objectInfo;
if(object == null){
objectInfo = "Object was null.";
}else{
objectInfo = String.format("Object of class %s and printed as String gives %s", object.getClass().getCanonicalName(), object.toString());
}
objectInfo = "Hazelcast was unable to serialize an object. " + objectInfo;
out.writeUTF(objectInfo);
}
@Override
public Object read(ObjectDataInput in) throws IOException {
String message = in.readUTF();
HazelcastSerializationException hazelcastSerializationException = new HazelcastSerializationException(message);
return hazelcastSerializationException;
}
@Override
public int getTypeId() {
return 63426;
}
@Override
public void destroy() {
}
}
公共类GlobalSerializerException实现StreamSerializer{
@凌驾
公共无效写入(ObjectDataOutput,Object对象)引发IOException{
字符串objectInfo;
if(object==null){
objectInfo=“对象为空。”;
}否则{
objectInfo=String.format(“类%s的对象和打印为字符串的对象给出了%s”,Object.getClass().getCanonicalName(),Object.toString());
}
objectInfo=“Hazelcast无法序列化对象。”+objectInfo;
out.writeUTF(objectInfo);
}
@凌驾
公共对象读取(ObjectDataInput in)引发IOException{
String message=in.readUTF();
HazelcastSerializationException HazelcastSerializationException=新的HazelcastSerializationException(消息);
返回hazelcastSerializationException;
}
@凌驾
public int getTypeId(){
返回63426;
}
@凌驾
公共空间销毁(){
}
}
调用者失败并超时,因为它没有从目标获得响应。目标节点未能序列化响应,原因是未能发送响应。这是当前的行为,但我认为也可以发送一个特殊的异常来表示响应失败
默认情况下,Hazelcast能够序列化实现java.io.Serializable
、java.io.Externalizable
和一些Hazelcast特定接口的类,例如。还可以定义自定义序列化程序或委托给另一个序列化库。有关更多信息,请参见第节
在分布式系统中,节点之间交换的消息必须可序列化为二进制形式,以便通过网络传输。因此,参与分布式系统的实体/服务必须确保其消息以某种形式可序列化
如果您不知道消息的类型,则可以注册Hazelcast a,它首先尝试使用已知格式(Serializable
,Externalizable
等)进行序列化,如果类型未知,则改为写入自定义错误消息。
或者,您可以使用自定义的可序列化包装器对象包装服务的执行结果。在序列化过程中,若原始包装结果未能序列化,则再次编写自定义错误消息
比如,
class NonSerializableResponseException extends Exception {}
class ServiceResponseWrapper implements DataSerializable {
private Object response;
@Override
public void writeData(ObjectDataOutput out) throws IOException {
try {
out.writeObject(response);
} catch (HazelcastSerializationException e) {
out.writeObject(new NonSerializableResponseException());
}
}
@Override
public void readData(ObjectDataInput in) throws IOException {
response = in.readObject();
}
}
谢谢你的回答。我将尝试这两种建议,看看会发生什么。