Как правильно имитировать передачу по ссылке в Java RMI с сериализуемыми объектами и методом обратного вызова? - PullRequest
3 голосов
/ 25 февраля 2012

У меня есть распределенное приложение, использующее Java RMI и основной объект (CoreApplication), который реализует java.io.Serializable.Каждую минуту этот главный объект отправляется на удаленный компьютер и обрабатывается в пуле потоков этой JVM.Поскольку он асинхронный, объект обрабатывается без блокировки основного потока на главном компьютере.

Когда объект CoreApplication завершает обработку в удаленном потоке, он вызывает метод обратного вызова и отправляется обратно на главный компьютер..

Вот некоторый код удаленного компьютера, обрабатывающего задание, вызванное с главного компьютера через RMI, и метод sendJob

public void sendJob(final CoreApplication aJob) throws RemoteException{
    Runnable r = new Runnable(){
        public void run(){
            try {
                WorkResponse wr = aJob.process();
                client.coreApplicationHandler(aJob,wr); 
            }catch(RemoteException e){}
        }
    };
    workQueue.execute(r);
}

Вы можете увидеть client.coreApplicationHandler - это метод обратного вызова дляглавный сервер и отправляет вместе с ним объект CoreApplication вместе с объектом ответа.

Вот код метода coreApplicationHandler на главном компьютере

    public void coreApplicationHandler(CoreApplication j,WorkResponse wr){
        String ticker = j.getTickerSymbol();
        coreApplicationObjects.put(ticker, j);
        if(GlobalParameters.DEBUG_MODE){ 
            System.out.println("WORK RESPONSE IS "+wr.getMessage());
        }
    }

Мой вопрос заключается в замене CoreApplication.объект каждый раз в методе обратного вызова - лучший способ убедиться, что он актуален в течение следующей минуты, когда он был отправлен?CoreApplication плавный и меняется, и состояние должно быть сохранено.Я отправляю его обратно на главный компьютер, поэтому его состояние можно контролировать из центрального расположения.Если бы у меня было 100 вычислительных узлов, и они не возвращали свои объекты, было бы очень грязно, я думаю, что отследить их все.

До сих пор это работает довольно хорошо, если работа не обрабатываетсявремя он пытается отправить другой и приводит к отправке устаревшего объекта со старым состоянием (то есть, тот же объект, что и в последнюю минуту).Пожалуйста, прокомментируйте, если это не имеет смысла, и я сделаю все возможное, чтобы объяснить это.

1 Ответ

1 голос
/ 13 июля 2012

RMI - это не способ синхронизации объектов в кластере.Но есть инструменты для этого.Например, посмотрите http://www.hazelcast.com/,.

Если у вас кластер компьютеров и вам нужна синхронизация, вам нужно использовать кластеризацию с помощью инструментов сервера или стороннего инструмента.

Iрекомендую фундук.Он очень прост в использовании и позволяет локальным кластерам использовать быстрые кластеры UDP или WAN, используя TCP-сокет к TCP-сокету.

Например, Hazelcast позволит вам сделать что-то вроде этого:

import com.hazelcast.core.MultiMap;
import com.hazelcast.core.Hazelcast;
import java.util.Collection;

// a live shared multimap shared across all cluster nodes
MultiMap<String, Order> mmCustomerOrders = Hazelcast.getMultiMap("customerOrders");

mmCustomerOrders.put("1", new Order ("iPhone", 340));

Thread.Sleep( 1000 );

Order order = (Order) mmCustomerOrders.get("1");

System.out.println( Order.quantity() ); // 340 ?? Nobody knows, it might have been changed

Какой выход?Если член кластера изменил элемент «1» на карте, то вы получите это значение автоматически.Больше не нужно кодировать….

Надеюсь, это поможет

-Alex

...