首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java第一次调用慢

Java第一次调用慢
EN

Stack Overflow用户
提问于 2017-01-09 08:48:41
回答 1查看 1.2K关注 0票数 2

我正在为学校做一个个人项目,在那里我必须使用RMI在服务器和客户端之间进行通信。

项目信息

我的项目的目标是在特定的时间(在NYSE关闭之后)检索服务器上的每一天的股票信息(从NYSE)。每个库存对象都保存在数据库中。信息通过http检索,与RMI无关。

对于客户端,也可以获取股票。当用户想要获取当前日期的股票对象时,它将直接从第三方服务中获取。例如,当用户想从上个月获取Google的股票时,就会通过RMI在服务器上请求它。服务器将在数据库中查找stock对象,并检索Stock对象并将其发送到客户端。

问题

当我启动客户机应用程序时,我必须登录。客户端将创建一个包含用户名和密码的用户对象。当我按下登录按钮时,大约需要2分钟才能显示主屏幕。

在源代码下面,我设置了RMI连接。

服务器(main.java)

代码语言:javascript
复制
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()。此方法将获取代码符号(什么是滴答符号?),然后调度一个任务,以便在特定时间获取所有股票对象。

代码语言:javascript
复制
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)

代码语言:javascript
复制
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 param运行程序。

更新1 (9-1-2017)

正如注释中的yanys所要求的那样,我应该运行以下命令:

-q主机-a名称本地主机

这将返回以下输出:

麦克:

代码语言:javascript
复制
name: localhost
ip_address: 127.0.0.1

Ubuntu:

代码语言:javascript
复制
dscacheutil: command not found

更新2 (9-1-2017)

我向运行java服务器的VPS提供程序进行了检查。站在他们这边一切都会好的。根据他们的说法,这不应该是dns问题。经过一些研究,我发现RMI同时使用DNS和反向DNS。在这种情况下,反向DNS才是问题所在。请看我如何解决问题的答案。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-10 12:39:31

正如EJP在关于这个问题的评论中指出的那样,这是一个DNS问题。

我联系了我的主机提供商的支持,看看我是否有一些错误的设置。他们帮助我解决了这个问题。

首先我们测试了我的VPS的速度,这大约是1000 this的下载和上传速度。我们查过之后,他们说他们这边没什么不对。

经过一些研究,我发现RMI同时使用DNS和反向DNS。问题是我没有在服务器上设置反向DNS。我已经有一个域名用于反向DNS。

我做了以下几点:

  1. 在我的网站上创建一个指向服务器IP地址的A记录.我把它命名为vps.mydomain.com
  2. 在我的服务器的控制面板中添加反向DNS
  3. 将我的服务器的主机名更改为vps.mydomain.com*

*我的服务器运行Ubuntu16.04,在Ubuntu机器上使用systemd,您可以使用以下命令

sudo hostnamectl集-主机名新名称

更改主机名

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41544114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档