2

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

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

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

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

编辑:回答几个问题

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

-斯内哈尔

4

12 回答 12

4

减少往返次数

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

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

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

于 2009-04-27T09:28:47.220 回答
2

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

但是千兆以太网是不可行的,因为客户端很远(可能通过互联网连接)。

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

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

于 2009-04-27T11:54:05.717 回答
1

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

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

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

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

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

于 2009-04-27T09:32:59.677 回答
1

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

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

于 2009-04-27T09:37:25.453 回答
1

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

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

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

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

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

于 2009-04-27T10:26:26.303 回答
1

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

史蒂夫的网站在这里

于 2009-04-27T10:34:46.703 回答
1

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

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

于 2009-04-27T14:49:39.930 回答
1

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

于 2009-04-27T19:56:05.090 回答
0

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

于 2009-04-27T09:39:44.573 回答
0

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

于 2009-04-27T19:41:55.173 回答
0

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

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

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

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

于 2009-05-10T11:48:31.470 回答