2017-01-09 5 views
1

Ich arbeite an einem persönlichen Projekt für die Schule, wo ich RMI verwenden muss, um zwischen Server und Client zu kommunizieren.Java RMI Anruf langsam zuerst

Projektinfo

Das Ziel meines Projektes ist stock info abrufen (aus NYSE) für jeden Tag auf dem Server zu einem bestimmten Zeitpunkt (nach NYSE geschlossen ist). Jedes Bestandsobjekt wird in einer Datenbank gespeichert. Die Informationen werden über HTTP abgerufen und haben nichts mit RMI zu tun.

Für den Kunden ist es auch möglich, die Bestände abzurufen. Wenn ein Benutzer das Bestandsobjekt für den aktuellen Tag abrufen möchte, wird es direkt vom dritten Parteidienst abgerufen. Wenn ein Nutzer beispielsweise die Google-Aktie vom letzten Monat abrufen möchte, wird er auf dem Server über RMI angefordert. Der Server sucht nach dem Bestandsobjekt in der Datenbank und ruft ein Bestandsobjekt ab und sendet es an den Kunden.

Problem

Wenn ich die Client-Anwendung zu starten, muss ich anmelden. Der Client erstellt ein Benutzerobjekt, das den Benutzernamen und das Passwort enthält. Wenn ich die Login-Taste drücke, dauert es etwa 2 Minuten, bis der Hauptbildschirm angezeigt wird.

Unterhalb des Quellcodes, wo ich die RMI-Verbindung eingerichtet habe.

Server (main.java)

public static void main(String[] args) throws UnknownHostException { 

    InetAddress IP= InetAddress.getLocalHost(); 
    System.out.println("IP of my system is := "+IP.getHostAddress()); 

    if(args.length == 1 && args[0].toLowerCase().equals("local")) { 
     System.out.println("Running on localhost"); 
     System.setProperty("java.rmi.server.hostname", IP.getHostAddress()); 
    } else { 
     System.out.println("rmi hostname is set to 37.97.223.70"); 
     System.setProperty("java.rmi.server.hostname", "37.97.223.70"); 
    } 

    try { 
     Registry reg = LocateRegistry.createRegistry(1099); 
     StockAppServer server = StockAppServer.getInstance(); 
     reg.rebind("StockApp", server); 
     System.out.println("StockApp bound for StockAppServer object."); 
    } catch (RemoteException e) { 
     e.printStackTrace(); 
    } 
} 

Basierend auf den Argumenten, die an die Anwendung übergeben werden, wenn es beginnt, stelle ich die RMI-Hostnamen auf meine aktuelle IP-Adresse oder an den Remote-Server-Adresse . Die Adresse des Remote-Servers ist eine statische IP-Adresse. Dies ändert sich nicht.

Server (StockAppServer.java)

Diese Klasse implementiert die Schnittstellen, die vom Client verwendet wird, Methoden auf dem Server aufzurufen. Also erweitert diese Klasse UnicastRemoteObject. Wenn ich den Server starte, wird registerStockTask() aufgerufen. Diese Methode ruft die Tickersymbole ab (What are ticker symbols?) und plant dann eine Aufgabe, um alle Bestandsobjekte zu einem bestimmten Zeitpunkt abzurufen.

private static StockAppServer _instance; 
private List<User> loggedInUsers; 
private List<Group> activeGroups; 
private List<Notification> registeredNotifications; 

private StockAppServer() throws IOException { 
    _instance = this; 

    this.loggedInUsers = new ArrayList<>(); 
    this.activeGroups = new ArrayList<>(); 
    this.registeredNotifications = new ArrayList<>(); 

    this.registerStockTask(); 

    clearActiveGroups(); 
    checkForCompletedNotifications(); 

    // Start the restful framework to allow incoming connections from the NodeJS server to manage new notification 
    Router.getInstance(); 
} 

public static StockAppServer getInstance() { 
    try{ 
     return _instance == null ? new StockAppServer() : _instance; 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    return null; 
} 

Client (main.java)

public static void main(String[] arguments) throws Exception { 
    args = arguments; 
    Application.launch(); 
} 

@Override 
public void start(Stage primaryStage) throws Exception { 
    InetAddress IP= InetAddress.getLocalHost(); 
    System.out.println("IP of my system is := "+IP.getHostAddress()); 



    if(args.length == 1 && args[0].toLowerCase().equals("local")) { 
     // Program started with local command, expect that server is running on local host 
     reg = LocateRegistry.getRegistry(IP.getHostAddress(), 1099); 
     System.out.println("Attempting to connect to RMI server over 127.0.0.1"); 
    } else { 
     // Program started without additional commands. Except that "the server" is available; 
     reg = LocateRegistry.getRegistry("37.97.223.70", 1099); 
     System.out.println("Attempting to connect to RMI server over 37.97.223.70"); 
    } 

    try { 
     StockApp.getInstance().setServerInterfaces((IStockSend) reg.lookup("StockApp"), (IUserHandling) reg.lookup("StockApp")); 
    } catch(RemoteException e) { 
     AlertMessage.showException("Unable to connect to server.", e); 
    } catch (NotBoundException e) { 
     AlertMessage.showException("No server has been found with the name \"StockApp\" on the remote host.\nPlease try again later", e); 
    } 

    LoginController.showMenu(); 

    //FileNotFoundException e = new FileNotFoundException("Couldn't find file blabla.txt"); 
    //AlertMessage.showException("Something went wrong. Please try again later.", e); 
} 

Wie ich versuchte, mein Problem zu lösen

Wenn ich meine Anwendungen lokal testen, ist es kein Problem. Die Login-Methode wird innerhalb weniger Millisekunden abgeschlossen und ich werde den Hauptbildschirm darstellen.

  • Ich begann mit dem Umdrehen meiner Firewall auf meinem MacBook. Kein Ergebnis, die Login-Methode dauert immer noch ca. 2 Sekunden.
  • Ich habe die Firewall von meinem Ubuntu-Server ausgeschaltet. Kein Ergebnis, sowohl Firewalls auf Server als auch Macbook sind ausgeschaltet. Die Login-Methode dauert immer noch ca. 2 Sekunden.
  • Auf dem Server läuft (dank Jenkins) ein anderes (nicht verwandtes) Programm. Dieses Programm verwendet Sockets anstelle von RMI.Wenn dieses Programm nicht ausgeführt wird, dauert die Anmeldemethode immer noch ca. 2 Minuten.
  • In StockAppServer.java, I bezeichnet die folgende Methode:

    Super (1099); Dies hat das gleiche Ergebnis wie die oben genannten Schritte.

Ich weiß nicht, was ich sonst noch versuchen kann, um mein Problem zu lösen.

Ich habe versucht, so viel Code wie möglich für den RMI-Teil zu geben. Ich brauche irgendeinen anderen Quellcode, frag einfach und ich kann diese Frage aktualisieren. Der Quellcode ist auch über github verfügbar: https://github.com/juleskreutzer/GSO-Maatwerk. Stellen Sie sicher, dass das Programm mit dem Parameter -remote ausgeführt wird.

-Update 1 (9-1-2017)

Als yanys in den Kommentaren aufgefordert, sollte ich den folgenden Befehl ausführen:

dscacheutil -a Name localhost -q Host

diese liefert die folgende Ausgabe:

Mac:

name: localhost 
ip_address: 127.0.0.1 

Ubuntu:

dscacheutil: command not found 

aktualisieren 2 (9-1-2017)

ich mit dem Anbieter von meinem VPS überprüft, wo ich auf der Java-Server laufen. Auf ihrer Seite sollte alles in Ordnung sein. Ihnen zufolge sollte es kein DNS-Problem sein. Nach einigen Recherchen fand ich heraus, dass RMI sowohl DNS als auch Reverse-DNS verwendet. In diesem Fall war Reverse-DNS das Problem. Bitte sehen Sie meine Antwort, wie ich mein Problem gelöst habe.

+1

Dies ist ein DNS-Problem, kein RMI-Problem. – EJP

+0

@Jules Was ist das Ergebnis des Befehls 'dscacheutil -q host -a name localhost'? Ihr Problem könnte etwas mit dem Inhalt der Datei "/ etc/hosts" zu tun haben. Die Zeile '127.0.0.1 localhost' oder ähnlich fehlt. –

+0

@yanys - Ich habe meine Frage mit dem Ergebnis des von Ihnen vorgeschlagenen Befehls aktualisiert. – Jules

Antwort

0

Wie EJP in den Kommentaren auf die Frage hingewiesen, war ein DNS-Problem.

Ich kontaktierte die Unterstützung meines Hosting-Providers, um zu sehen, ob ich einige falsche Einstellungen hatte. Sie haben mir sehr geholfen, dieses Problem zu lösen.

Zuerst haben wir die Geschwindigkeit meines VPS getestet, das ist etwa 1000mbit Download-und Upload-Geschwindigkeit. Nachdem wir das überprüft hatten, sagten sie, dass auf ihrer Seite nichts falsch liege.

Nach einigen Nachforschungen fand ich heraus, dass RMI sowohl DNS als auch Reverse DNS verwendet. Das Problem war, dass ich das Reverse-DNS auf meinem Server nicht eingerichtet habe. Ich habe bereits einen Domain-Namen für Reverse-DNS.

ich als das folgende tat:

  1. erstellen A-Rekord auf meiner Website, die auf die IP-Adresse des Servers verweist. Ich nannte es vps.mydomain.com
  2. Hinzufügen der Reverse-DNS in der Systemsteuerung meines Servers
  3. Ändern Sie den Hostnamen meines Servers zu vps.mydomain.com *

* Mein Server läuft Ubuntu 16.04, auf Ubuntu Maschinen mit Systemd, können Sie den Befehl

sudo hostnamectl Set-Host-Namen neuer_Name

den Hostnamen ändern

+0

* Java * verwendet aus Sicherheitsgründen Reverse-DNS. Es ist nicht nur RMI. – EJP