Я работаю над личным проектом для школы, где у меня есть RMI для связи между сервером и клиентом.Java RMI call slow first time
Информация о проекте
Целью моего проекта является получение информации запаса (от NYSE) за каждый день на сервере в определенное время (после того, как NYSE закрыт). Каждый объект запаса сохраняется в базе данных. Информация извлекается по http и не имеет ничего общего с RMI.
Для клиента также можно получить акции. Когда пользователь хочет получить объект запаса на текущий день, он напрямую извлекается из 3-го партийного сервиса. Когда пользователь, например, хочет получить товар Google за последний месяц, он запрашивается на сервере через RMI. Сервер будет искать объект запаса в базе данных и получить объект Stock и отправить его клиенту.
Проблема
При запуске клиентского приложения, я должен войти в систему. Клиент создаст объект User, содержащий имя пользователя и пароль. Когда я нажимаю кнопку входа в систему, это займет около 2 минут, прежде чем будет показан основной экран.
Ниже исходного кода, где я устанавливаю соединение RMI.
Сервер (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();
}
}
на основе аргументов, которые передаются приложению при запуске, я установить имя хоста RMI на мой текущий IP-адрес, или адрес удаленного сервера , Адрес удаленного сервера представляет собой статический IP-адрес, поэтому это не изменится.
Сервер (StockAppServer.java)
Этот класс реализует интерфейсы, которые используются клиентом для вызова методов на сервере. Таким образом, этот класс расширяет UnicastRemoteObject. Когда я запустил сервер, вызывается registerStockTask(). Этот метод будет извлекать символы тикера (What are ticker symbols?), а затем планировать задачу для извлечения всех объектов запаса в определенное время.
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);
}
Как я пытался решить мою проблему
Когда я проверить свои приложения на местном, нет никаких проблем. Метод входа будет завершен в течение нескольких миллисекунд, и я буду представлен основным экраном.
- Я начал с включения моего брандмауэра в своем macbook. Нет результата, метод входа еще занимает около 2 секунд.
- Я отключил брандмауэр моего сервера Ubuntu. Нет результата, оба брандмауэра на сервере и macbook отключены. Метод входа по-прежнему занимает около 2 секунд.
- На сервере запускается (благодаря jenkins) другая (несвязанная) программа. Эта программа использует сокеты вместо RMI.Когда эта программа не запущена, метод входа в систему по-прежнему занимает около 2 минут.
В StockAppServer.java, я назвал следующий метод:
супер (1099); Это результат, аналогичный приведенным выше шагам.
Я не знаю, что еще я могу попытаться решить свою проблему.
Я попытался предоставить как можно больше кода для части RMI. Мне нужен какой-либо другой исходный код, просто спросите, и я могу обновить этот вопрос. Кроме того, исходный код доступен через github: https://github.com/juleskreutzer/GSO-Maatwerk. Обязательно запустите программу с параметром -remote.
Update 1 (9-1-2017)
Как yanys запрошенные в комментариях, я должен выполнить следующую команду:
dscacheutil -q -a пройдет имя локального
это возвращает следующий результат:
Mac:
name: localhost
ip_address: 127.0.0.1
Ubuntu:
dscacheutil: command not found
Update 2 (9-1-2017)
Я проверил с поставщиком моего VPS, где я бегу сервер Java на. На их стороне все должно быть в порядке. По их словам, это не должно быть проблемой DNS. После некоторых исследований я узнал, что RMI использует DNS и обратный DNS. В этом случае обратная DNS была проблемой. Пожалуйста, см. Мой ответ о том, как я решил свою проблему.
Это будет poblem DNS, а не проблема RMI. – EJP
@Jules Что является результатом команды 'dscacheutil -q host -a name localhost'? Ваша проблема может иметь какое-то отношение к содержимому файла/etc/hosts. Отсутствует строка «127.0.0.1 localhost» или аналогичная. –
@yanys - Я обновил свой вопрос с помощью команды, которую вы предложили. – Jules