Участник вызывающего Hazelcast генерирует исключение тайм-аута, когда исключение сериализации происходит на члене вызываемого - PullRequest
0 голосов
/ 25 сентября 2018

Я использую Hazelcast (JAVA, версия 3.7.5) в сценарии с 2 членами .Первый участник делегирует задачу второму участнику через IExecutorService.После некоторой обработки второй участник пытается отправить обратно несериализуемый ответ .

Поскольку невозможно отправить ответ, второй элемент печатает трассировку стека, связанную с HazelcastSerializationException.

Поскольку ответа не приходит, первый член выдает OperationTimeoutException при достижении срабатывания-сердцебиения операции .

В настоящее время, когда IExecutorService не удается выполнить синтаксический анализ результата Callable, он печатает трассировку стека (на стороне вызываемого).Допустим, у меня есть простой вызывающий:

private Future<Object> startFlow() {
    //This throws an OperationTimeoutException
    return hazelcastInstance.getExecutorService("myExecutor").submit(myRunnable);
}

, который вызывает простого вызываемого абонента:

@Override
public Object call() throws Exception {
    //The object returned is not serializable, therefore an HazelcastSerializationException is thrown
    return service.execute();
}

Вызываемый абонент печатает трассировку стека после того, как ему не удалось проанализировать ответ (см. Конец сообщения).

В моем случае невозможно узнать, какой тип объекта может возвращать service, и невозможно доверять service в отправке обратно сериализуемых объектов.

Я хотел бы знать причину тайм-аута на стороне вызывающего абонента.

После некоторого поиска я обнаружил, что нет конфигурации / API, доступной для перехвата исключений, выданных IExecutorServiceкогда не удается сериализовать ответ.

Поэтому я попытался выяснить, можно ли проверить Hazelcast, можно ли было разобрать объект, опять же без успеха.

Есть идеи?

Спасибо


Трассировка стека, напечатанная вызываемым пользователем, будет выглядеть следующим образом:

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() {

    }
} 

1 Ответ

0 голосов
/ 25 сентября 2018

Звонящий не работает с таймаутом, потому что не получает ответ от целиЦелевой узел не может сериализовать ответ, так как причина не может отправить ответ.Это текущее поведение, но я также думаю, что можно также отправить специальное исключение, чтобы обозначить этот сбой ответа.

Hazelcast по умолчанию может сериализовать классы, реализующие java.io.Serializable, java.io.Externalizable и некоторые специфичные для Hazelcastинтерфейсы, такие как DataSerializable , Portable .Также возможно определить пользовательские сериализаторы или делегировать другую библиотеку сериализации.См. Справочное руководство Hazelcast - Сериализация раздел для получения дополнительной информации.

В распределенной системе сообщения, которыми обмениваются узлы, должны быть сериализуемыми в двоичную форму для передачи их по сети.Таким образом, субъект / служба, участвующая в распределенной системе, должна гарантировать, что ее сообщения сериализуются в той или иной форме.

Если вы не знаете тип сообщений, вы можете зарегистрировать Hazelcast глобальный сериализатор , который сначала пытается сериализовать с использованием известных форматов (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();
    }
}
...