【问题标题】:How to improve the performance of Client-Server Architecture Application?如何提高客户端-服务器架构应用程序的性能?
【发布时间】:2009-04-27 09:25:34
【问题描述】:

我们有一个基于客户端-服务器架构的产品。有关使用的技术堆栈的一些详细信息。

  • 客户端 - Java Swing
  • 服务器 - RMI
  • Java 数据库 - 甲骨文

客户端位于世界的不同地方,但 java 服务器和 oracle 数据库位于瑞典的同一台机器上。因此,存在很多网络延迟。位于遥远位置的客户端性能很差。该应用程序用于处理大小超过 50MB 的文件。通常,每个操作需要大约 1000 多个网络调用。

根据您的经验,您如何解决这个问题并提高性能?

编辑:回答几个问题

  1. 文件包含需要处理和更新到数据库的实际业务数据,不能部分发送。
  2. 可以批量处理一些网络调用,但需要对代码进行重大重构。这是 2001 年编写的一个非常古老的应用程序。应用程序的设计是这样的,服务器保存所有服务,它们可以跨代码重用,业务逻辑写在客户端。因此,此业务逻辑多次调用服务器,因此是天文数字。

-斯内哈尔

【问题讨论】:

标签: java performance client-server rmi


【解决方案1】:

减少往返次数

单次操作 1000 次往返是一个天文数字。你不应该看到这些数字。

尽管 50MB 的文件仍然存在问题。在这种情况下,您要么需要找到一种方法来提高传输效率(仅在两个相似文件之间传输增量?),要么使用某种缓存。

WAN 流量正在扼杀您的应用,听起来您需要进行重大重构。

【讨论】:

  • 不是批评,但设计这样的应用程序需要对网络流量的影响有基本的了解,尤其是在延迟是一个关键问题的广域网上传递的流量。
  • 我实际上正在维护这个古老的应用程序,并且我被分配了提高性能的任务。无论如何,感谢您指出这一点。
  • WAN - 广域网(与您公司内部的 LAN 相对)。这通常意味着同行通过 Internet 交谈。
【解决方案2】:

通过网络发送大文件和大量请求会花费大量时间。时期。即使您可以升级到千兆以太网,该协议仍然要求您的客户端在两个连续的网络数据包之间空闲几毫秒(以便其他主机也有机会交谈)。

但千兆以太网不可行,因为客户端距离很远(可能通过 Internet 连接)。

因此,唯一可行的方法是将业务代码移近服务器。最简单的解决方案是将客户端安装在与服务器相同的 LAN 中的小盒子上,并使用 VNC 或类似协议远程访问它们。

下一个层次是将客户端分为业务层和显示层。把业务层变成服务,在客户端安装显示层。通过这种方式,数据仅在(快速)Intranet 上被推送。当结果准备好显示时,客户端只获得结果(少量数据)。

【讨论】:

    【解决方案3】:

    -如果还没有,则使服务器无状态

    -考虑更轻量级的远程协议,例如 Hessian

    -延迟可能是你的瓶颈,考虑在客户端使用缓存并读取更大的数据块,1000 次往返是巨大的负载。

    -考虑重构客户端,使其能够在本地工作并在后台同步

    -使用分析器查看应用程序花费最多时间的位置并对其进行优化

    【讨论】:

    • 忘记分析器。该应用程序每次操作有 1K 次往返,文件大小为 50MB。 WAN 是瓶颈。
    • 不要使服务器无状态。这增加了问题
    • 你能说出为什么无状态会导致问题吗?
    【解决方案4】:

    您是否对操作的不同部分的相对时间消耗进行了任何测量?在你测量出各个过程需要多长时间之前,我不会碰任何东西。

    怀疑延迟问题是关键。但在查看任何解决方案之前,我会先测量并确定这一点。

    【讨论】:

      【解决方案5】:

      也许最好的办法是更好地了解基础设施的工作原理

      1. 为什么文件这么大?
      2. 必须发送整个文件,或者您可以只发送所需的部分进行处理
      3. 这些网络调用是什么?它们都是必需的吗?如果是这样,是否可以将调用批​​处理为一个调用?

      【讨论】:

        【解决方案6】:

        不确定,但看起来您在 50 MB 文件中有一些数据要验证/处理并存储在数据库中。对吗?

        为什么客户端可以简单地将文件传递给服务器,服务器执行验证/处理任务并存储在数据库中?这将没有网络调用,除了将文件数据传递给服务器。

        另一种可能性是,如果您可以在一次调用中组合多个操作,即会话外观模式。

        【讨论】:

          【解决方案7】:

          Steve Souders 的“高性能网站:前端工程师必备知识”是一本非常好的书。见here

          史蒂夫的网站是here

          【讨论】:

          • 不只是关于网站吗?
          【解决方案8】:

          我建议尽可能多地使这个过程异步。客户是否需要对处理进行实时响应?如果没有,您可以转向 MOM(面向消息的中间件)概念,并将 JMS 队列/主题放在客户端和服务器之间。

          客户端可以将要处理的记录发布到服务器正在监视的队列中。处理完成后,服务器会将结果放入客户端正在侦听的回复队列中。这将强制进行重构,但假设您的代码是松散耦合的,它不应该是非常具有侵入性的。

          【讨论】:

            【解决方案9】:

            要么以主要方式重构代码,要么重写整个应用程序。如果您的经理说添加进度条需要很长时间,以便用户认为它运行得更快。

            【讨论】:

              【解决方案10】:

              每个操作需要1000个请求是很多的! 这将杀死任何服务器。 这通常是无法通过添加更多硬件来解决的问题 或增加更多带宽。 这是一个设计问题。 无论如何,我会安装一个探查器以查看 服务器状态(内存消耗、cpu 等)。 看看 lambda 探针 (http://www.lambdaprobe.org)

              【讨论】:

              • LambdaProbe 是 Tomcat 特定的吗?
              • 是的!事实上,这个分析器以前称为 Tomcatprobe。
              【解决方案11】:

              RMI 是一个非常昂贵的协议。我会考虑更换它。

              【讨论】:

              • Java 的 RMI 非常昂贵。有许多更快的替代方案。
              • RMI 很慢,但 AFAIK 很少有替代方案可以减少往返次数。
              【解决方案12】:

              如果你不能改变协议,至少改变有效载荷:

              1) 这听起来像是一个封闭的系统。如果是,则不需要使用通用的 Serializable 协议。切换到 Externalizable 并写入捕获对象状态以进行电汇所需的最少数据。

              2) 压缩从服务器发送到客户端的数据。除了 (1) 中的对象状态之外,您还应该减少在网络上移动的数据块(“文件”)。

              除此之外(这显然取决于系统),您应该探索前向缓存节点。在许多应用程序中,都有一种域实体访问模式。如果存在可以利用的地理访问模式,您应该能够轻松地创建新的代理节点作为远程服务器的客户端,然后充当附近 (rmi) 客户端的 (rmi) 服务器。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-08-08
                • 1970-01-01
                • 1970-01-01
                • 2012-07-25
                • 1970-01-01
                相关资源
                最近更新 更多