Avatar billede thomses Nybegynder
11. januar 2007 - 01:33 Der er 13 kommentarer og
1 løsning

Fejldetecte en server (RMI)

Er der nogen der ved hvordan jeg implementerer i RMI følgende:

Jeg har en server og en client. Hvis servere går ned skal min klient have besked om dette ( fejldetecter) Men kan ikke finde ud af om jeg skal lade min server udsende et "ALIVE" signal hver f.eks. 10'nde sekund eller jeg skal lade min klient forespørger servere om den er i live. Øhh hvad er egentlig bedst rent performace mæssigt( båndbredde ) ? 

Jeg skal vel egentlig også implemntere noget callback og nogle tråde eller tager jeg helt fejl ?
Avatar billede arne_v Ekspert
11. januar 2007 - 03:09 #1
umiddelbart lyder det ret ens i performance mæssig impact
Avatar billede jime_boy Nybegynder
11. januar 2007 - 14:37 #2
For mig lyder det bare som om at du skal gribe en exception.
Avatar billede thomses Nybegynder
12. januar 2007 - 01:44 #3
jime

En exception. Dvs når min client efter 10 sekunder prøver at lave lookup på servere. Når den ikke svarer får jeg en en exception jeg griber ?  Er det det du mener ?
Avatar billede jime_boy Nybegynder
12. januar 2007 - 10:10 #4
Ja, det var sådan jeg nok ville gribe det an.
Avatar billede jime_boy Nybegynder
12. januar 2007 - 10:12 #5
Du kan sandsynligvis finde ud hvilken det er her:
http://java.sun.com/j2se/1.3/docs/api/java/rmi/package-summary.html
Avatar billede thomses Nybegynder
13. januar 2007 - 02:15 #6
Ok har kigget på det. Har lavet en tråd der lavet lookup hver 100 ms. Problemet er bare at når jeg ikke får svar så stopper min tråd helt. Det skulle gerne være sådan at når jeg ikke får svar(exception kastes)  kan jeg kalde et metoder og foretaget noget andet. Helst en metode der er i klienten. Men har jo min tråd i en anden klasse


Smider lige min kode: (håber med lidt hjælp)

** CLIENTEN  **
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class TestNodeClient {

    public TestNodeClient(){
    }
   
    public void testCoordinatorAlice(){
        AliveThread alive = new AliveThread();
        alive.start();
        try
        {
            alive.join();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
    public static void main(String[] args)
    { 
        new TestNodeClient().testCoordinatorAlice();
        try
        {
        NodeMethods node = (NodeMethods)Naming.lookup("node2");
        System.out.println(node.add(2,3));
        System.out.println(node.mul(2,3));
       
           
      }
      catch (MalformedURLException e)
      {
        e.printStackTrace();
      }
      catch (RemoteException e)
      {
        e.printStackTrace();
      }
      catch (NotBoundException e)
      {
        e.printStackTrace();
      }
  } 
}
** AliveThread ***
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class AliveThread extends Thread
{
    private boolean run = true;
    private long acceptableTime = 5;
    public void run()
    {
       
        while(run)
        {
            System.out.println("Tråd kører");
            try
            {
                AliveThread.sleep(100);
            }
            catch (InterruptedException e1)
            {
                e1.printStackTrace();
            }
           
        try
        {
                NodeMethods node = (NodeMethods)Naming.lookup("node2");
                long startTime = System.currentTimeMillis();
               
                if(node.isalive()== true)
                  {
                long diffTime = System.currentTimeMillis()-startTime;
                System.out.println(diffTime);
                if(diffTime < acceptableTime)
                    System.out.println("coordinator is alive !!!");
                  }
                  else
                  {
                      System.out.println("server responding in an unacaptle time");
                  }
        }
        catch (MalformedURLException e)
        {
          e.printStackTrace();
        }
        catch (RemoteException e)
        {
          e.printStackTrace();
        }
        catch (NotBoundException e)
        {
          e.printStackTrace();
        }
       
       
        }
    }
}

** serveren **
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.List;

import alm.Participant;

public class Node extends UnicastRemoteObject implements NodeMethods
{
    static int NodeId = -1; // nodeID
    private List list;
   
    public Node(int nodeId) throws RemoteException
    {
        setNodeId(nodeId);
    }
    public void receiveMessage(String message)
    {
        if(message.equals("election"))
        {
            System.out.println("election started");
        }   
    }
    public boolean isalive()
    {
        return true;   
       
    }
    public void register(MyClient c)
    {
          synchronized(list)
          {
            list.add(c);
            System.out.println("Number of clients: " + list.size());
          }
      }
      public void unregister(MyClient c) {
          synchronized(list) {
            list.remove(c);
            System.out.println("Number of clients: " + list.size());
          }
      }

  public int add(int a, int b)throws RemoteException
  {
      System.out.println("Vi er blevet bedt om at lave en add");
      return (a + b);
  }
  public int mul(int a, int b)throws RemoteException
  {
      System.out.println("Vi er blevet bedt om at lave en mul");
      return (a * b);
  }
  public static void main(String[] args)
  {
    System.out.println("starting nodeID");
      try
      {
        //Naming.rebind("node"+args[0], new Node(Integer.parseInt(args[0])));
          Naming.rebind("node2", new Node(2));
      }
      catch (RemoteException e)
      {
        e.printStackTrace();
      }
      catch (MalformedURLException e)
      {
        e.printStackTrace();
      }
     
  }

/**
* @return Returns the nodeId.
*/
  private int getNodeId() {
    return NodeId;
}

/**
* @param nodeId The nodeId to set.
*/
    private void setNodeId(int nodeId) {
    NodeId = nodeId;   
    }
}
Avatar billede jime_boy Nybegynder
13. januar 2007 - 12:06 #7
Jeg må indrømme at jeg ikke er så stærk på RMI, men jeg kan se at du ikke gør noget når du catcher en exception. Min forståelse er at når der kastes en exception stopper programmet der. Det vil sige at der skal laves en opsamling på hvor programmet var da det skete, og evt. skal der laves en ny forbindelse.

Spørgsmålet er om der overhovedet er brug for din tråd, da der i http protekoler er indbygget en timer.

Arne_v hvis du læser med kunne jeg godt tænke mig at hører din mening?
Avatar billede thomses Nybegynder
14. januar 2007 - 16:34 #8
Hej jime>>
Jeg gør nu følgende

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimeManager(highest,getNodeId()),0,1000);

public class TimeManager extends TimerTask
{
    public TimeManager(int highest, int nodeId)
    {
        this.highest = highest;
        this.nodeId = nodeId;
    }
    public void run()
    {
    checkCoordinatorAlice(); // sker 1000 milisekund
    }

}
Ny forbindelse ?  Hvis en tråd stopper (Timer eller Thread) er det så muligt at starte den ( vel også stoppen den ) ?
Avatar billede arne_v Ekspert
14. januar 2007 - 17:31 #9
du kan cancle en timer

men skal du ikke catche en exception i din check tråd hvor du markerer noden som
nede men kører videre alligevel ?
Avatar billede thomses Nybegynder
14. januar 2007 - 17:42 #10
ok nu ser min kode således ud(bruger Thread), det andet blev en smule for forvirrende for mig)

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;

public class Node extends UnicastRemoteObject implements NodeMethods, Runnable
{
    private List allNodes;
    private int nodeId = -1;
    private NodeMethods node;
    private boolean isAlive = true;
    private Message message;
    private boolean isCoordinator = false;
    private Thread thread;
    private boolean electionInProgress = false;
    private long acceptableTime = 600;
    private int highest = -1;
   
    public Node(int nodeId) throws RemoteException
    {
        setNodeId(nodeId);
        RegisterServerMethods reg;
        try
        {
            reg = (RegisterServerMethods)Naming.lookup("register");
            reg.register(""+nodeId);
            this.allNodes = reg.getAllNodes();
        }
        catch (MalformedURLException e)
        {
        e.printStackTrace();
        }
        catch (RemoteException e)
        {
            e.printStackTrace();
        }
        catch (NotBoundException e)
        {
            e.printStackTrace();
        }
        checkCoordinatorAlice();
    }
    private int getNodeId()
    {
        return nodeId;
    }
    private void setNodeId(int nodeId)
    {
        this.nodeId = nodeId;
    }
   
   
   
   
    private void checkCoordinatorAlice()
    {
        Iterator it = allNodes.iterator();
          while (it.hasNext())
          {
              int value = Integer.parseInt((String)it.next());
              if(value > highest)
              {
                  highest= value;
              }
          } 
        int size = allNodes.size();
        if(highest == getNodeId())
        {
            System.out.println("New coordinator is Node" +getNodeId());
            this.setCoordinator(true);
        }
        if(size > 1 && highest != getNodeId())
        {
            if(isElectionInProgress() != true)// check if another election is running
            {
                setElectionInProgress(true);
                thread = new Thread(this);
                thread.start(); 
            }
            //Timer timer = new Timer();
            //timer.scheduleAtFixedRate(new TimeManager(highest,getNodeId()),0,1000);
           
        }
    }
       
        public void run()
        {
            Thread currentThread = Thread.currentThread();
            while (currentThread == thread)
            {
                try
                {   
                    System.out.println("Sending Periodic Check to Node:"+highest);
                    long start = System.currentTimeMillis();
                    node= (NodeMethods)Naming.lookup("node"+highest);
                    Message ackMessage = node.isAlive(message = new Message());
                    long diff = System.currentTimeMillis()-start;
                    if(diff > acceptableTime)
                    {
                        initiateElection();
                        stop();
                    }
                    else
                    {
                        System.out.println("Received Acknowledgment from Node"+ackMessage.getNodeId());
                    }
                }
                catch (MalformedURLException e)
                {
                    e.printStackTrace();
                }
                catch (RemoteException e)// 
                {
                    e.printStackTrace();
                }
                catch (NotBoundException e)
                {
                    e.printStackTrace();
                }   
            }   
        }
        public void stop()
        {   
            thread = null;
        }
        public Message isAlive(Message m)throws RemoteException 
        {
       
        m.setNodeId(this.nodeId);
        try
        {
            Thread.sleep(1000); //for test purpose
        }
        catch (InterruptedException ex)
        {
            System.out.println (ex);
        }
        return m;
    }
   
    private void setAlive(boolean isAlive)
    {
        this.isAlive = isAlive;
    }
    private void initiateElection()
    {
        if(isElectionInProgress() != false)// check if another election is running
        {
            setElectionInProgress(true);
            System.out.println("Timeout: initiating new Election");
        }
    }
   
    private boolean isElectionInProgress()
    {
        return electionInProgress;
    }
   
    private void setElectionInProgress(boolean electionInProgress) {
        this.electionInProgress = electionInProgress;
    }
    private boolean isCoordinator()
    {
        return isCoordinator;
    }
   
    private void setCoordinator(boolean isCoordinator)
    {
        this.isCoordinator = isCoordinator;
    }
    public static void main(String[] args) throws RemoteException
    {
        int a = Integer.parseInt(args[0]);
        try
        {
            Naming.rebind("node"+a, new Node(a)); 
          }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
          }
        catch (RemoteException e)
        {
            e.printStackTrace();
        }
      }
   
   
   
}


Det jeg prøver at lave er

1) Når jeg prøver at kalde en Node( public Message isAlive(Message m)throws RemoteException ). Hvis der går for lang tid med svar dvs. timeout skal jeg udføre metoden initiateElection(). Hvis jeg heller ikke får svar når metoden isAlive kaldes, så antages det at Noden jeg prøver at lave lookup på at crashet og så skal jeg kalde metoden initiateElection().Men nu når jeg prøver at lave lookup når min Node er crashet så fanger jeg en RemoteException og mit program stopper. Det skulle gerne fortsættet
Avatar billede jime_boy Nybegynder
14. januar 2007 - 21:59 #11
Det er fordi at du catcher en exception, udskriver det og gør ikke mere.

prøv at tilføje initiateElection(); til din catch af den exception
----------------------------------
catch (RemoteException e)
        {
            initiateElection();
            e.printStackTrace();
        }
----------------------------------

Jeg foreslår dog, hvis du laver det på den måde, at du laver en log som skriver til en tekst-fil eller lign, så du kan se hvormange gange det forkommer.
Avatar billede thomses Nybegynder
15. januar 2007 - 13:22 #12
Og så virker det. smider i ikke lige et svar. TAK for hjælpen
Avatar billede jime_boy Nybegynder
15. januar 2007 - 14:43 #13
Selv tak :-)
Avatar billede arne_v Ekspert
15. januar 2007 - 17:28 #14
bare giv alle points til jime_boy - jeg har ikke bidraget med ret meget
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester