如何提高客户端 - 服务器架构应用程序的性能?

时间:2022-04-03 03:46:32

We have a product built on the Client-Server architecture. Some details about the technology stack used.

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

  • Client - Java Swing
  • 客户端 - Java Swing

  • Server - RMI
  • 服务器 - RMI

  • Java Database - Oracle
  • Java数据库 - Oracle

The clients are located at different parts of the world but the java server & the oracle database are located on the same machine in Sweden. Because of this there is a lot of network latency. The clients located at distant locations have terrible performance. The application is used for processing files with the size over 50MB. Each operation in general requires about over 1000 Network calls.

客户端位于世界的不同地方,但java服务器和oracle数据库位于瑞典的同一台机器上。因此,存在大量网络延迟。位于偏远地区的客户表现糟糕。该应用程序用于处理大小超过50MB的文件。每项操作一般需要超过1000次网络呼叫。

Based on your experience, how do you tackle this problem and improve the performance?

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

EDIT: To answer a few questions

编辑:回答几个问题

  1. Files contains the actual business data which needs to be processed and updated to the database cannot be sent in part.
  2. 文件包含需要处理和更新到数据库的实际业务数据,不能部分发送。

  3. Some of the network calls could be batched but it would require major refactoring of the code. This is a very old application written way back in 2001. And the design of the application is such that, the server holds all the services and they are made reusable across the code and the business logic is written on the client side. So, this business logic calls server numerous times and hence the astronomical figure.
  4. 某些网络调用可能是批处理的,但需要对代码进行重大重构。这是一个非常古老的应用程序,写于2001年。应用程序的设计是这样的,服务器保存所有服务,它们可以在代码中重用,业务逻辑在客户端编写。因此,这种业务逻辑多次调用服务器,因而是天文数字。

-Snehal

12 个解决方案

#1


Decrease your number of round trips

减少往返次数

1000 round trips for a single operation is an astronomic figure. No way you should be seeing those numbers.

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

You still have a problem though with the 50MB files. In which case, you will either need to find a way to make the transfer more efficient (transfer only deltas between two similar files?), or employ caching of some sort.

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

The WAN traffic is killing your app, and it sounds like you have major refactoring to do.

广域网流量正在扼杀您的应用,听起来您有重大的重构要做。

#2


Sending big files and lot of requests over the net costs a lot of time. Period. Even if you could upgrade to gigabit Ethernet, the protocol still demands that your client idles a few milliseconds between two consecutive network packets (so other hosts get a chance to talk, too).

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

But gigabit Ethernet is not feasible since the clients are far away (probably connected via the Internet).

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

So the only path which will work is to move the business code closer to the server. The most simple solution will be to install the clients on little boxes in the same LAN as the server and use VNC or a similar protocol to access them remotely.

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

The next level would be to cut the clients into a business layer and a display layer. Turn the business layer into a service and install the display layer on the clients. This way, data is only pushed around on the (fast) intranet. When the results are ready for display, the clients get only the results (little data).

下一级是将客户端切割为业务层和显示层。将业务层转换为服务并在客户端上安装显示层。这样,数据仅在(快速)Intranet上推送。当结果准备好显示时,客户端只获得结果(少量数据)。

#3


-Make server stateless if it is not yet the case

- 如果不是这样的话,使服务器无状态

-Consider lighter remote protocols such as Hessian

- 更轻松的远程协议,如Hessian

-Latency is probably your bottle neck, consider using cache in clients and read bigger chunks of data, 1000 round trips is huge load.

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

-Consider refactoring the client to make it able to work locally and have it synchronized in the background

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

-Use a profiler to see where the application spends most time and optimize that

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

#4


Have you performed any measurements of the relative time consumption of different parts of the operation ? I wouldn't touch anything until you've measured how long individual processes take.

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

I suspect the latency issue is the key. But I would measure and determine this first, before looking at any solutions.

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

#5


Perhaps the best thing to do would be to get a better understanding of how the infrastrucure works

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

  1. Why are the files so large?
  2. 为什么文件这么大?

  3. Must the entire files be sent, or could you get by with sending just the required parts for processing
  4. 必须发送整个文件,或者您只需发送所需的部分进行处理即可

  5. What are these network calls? Are they all necessary? If so, can the calls be batched into one call?
  6. 这些网络电话是什么?它们都是必要的吗?如果是这样,可以将呼叫分成一个呼叫吗?

#6


Not sure but looks like you have some data in the 50 MB file which you want to validate/process and store in database. Is it correct?

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

Why can the client simply pass the file to server and the server do the validate/process task and store in the database? This will there are no network calls except passing the file data to server.

为什么客户端只是将文件传递给服务器,服务器执行validate / process任务并存储在数据库中?除了将文件数据传递给服务器之外,没有网络调用。

Other possibility is if you can club multiple operations in one call i.e. a session facade pattern.

其他可能性是,如果您可以在一个呼叫中进行多个操作,即会话外观模式。

#7


"High Performance Web Sites: Essential Knowledge for Front-End Engineers" by Steve Souders is a really good book on this. See here.

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

Steve's website is here.

史蒂夫的网站就在这里。

#8


I would suggest looking to making as much of this process asynchronous as possible. Do the clients need to have real time response to the processing? If not, you could move to a MOM (Messaging Oriented Middleware) concept and place JMS queues/topics in between the client and the server.

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

The client could post records to be processed onto a queue that the server is monitoring. Once processing is complete, the server would place the results to a reply-to queue that a client would be listening on. This would force a refactor, but assuming your code is loosely coupled, it should not be terribly invasive.

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

#9


Either refactor the code in a major way or rewrite the entire app. If your manager says that will take to long add a progress bar so the user thinks it goes faster.

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

#10


Each operation requires 1000 requests is a lot! This will kill any server. This is typically a problem which cannot be solved by adding more hardware or adding more bandwith. This is a design problem. Anyway I would install a profiler in order to see the server status (memory consumption, cpu, etc). Take a look at lambda probe (http://www.lambdaprobe.org)

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

#11


RMI is a very expensive protocol. I would look at replacing it.

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

#12


If you can not change the protocol, at least change the payloads:

如果您无法更改协议,请至少更改有效负载:

1) This sounds like a closed system. If yes, there is no need to use generalized Serializable protocol. Switch to Externalizable and write the minimal data required to capture object state for wire transfer.

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

2) Compress the data that is sent from server to client. Beyond object state in (1), you should also reduce the data blobs ("files") that you are moving around the net.

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

Beyond that (and this obviously depends on the system) you should explore forward caching nodes. In many applications there is a pattern to domain entity access. If there is geographic access patterns that can be exploited, you should be able to trivially create new proxy nodes that are clients to the remote server and then act as a (rmi) server to nearby (rmi) clients.

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

#1


Decrease your number of round trips

减少往返次数

1000 round trips for a single operation is an astronomic figure. No way you should be seeing those numbers.

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

You still have a problem though with the 50MB files. In which case, you will either need to find a way to make the transfer more efficient (transfer only deltas between two similar files?), or employ caching of some sort.

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

The WAN traffic is killing your app, and it sounds like you have major refactoring to do.

广域网流量正在扼杀您的应用,听起来您有重大的重构要做。

#2


Sending big files and lot of requests over the net costs a lot of time. Period. Even if you could upgrade to gigabit Ethernet, the protocol still demands that your client idles a few milliseconds between two consecutive network packets (so other hosts get a chance to talk, too).

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

But gigabit Ethernet is not feasible since the clients are far away (probably connected via the Internet).

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

So the only path which will work is to move the business code closer to the server. The most simple solution will be to install the clients on little boxes in the same LAN as the server and use VNC or a similar protocol to access them remotely.

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

The next level would be to cut the clients into a business layer and a display layer. Turn the business layer into a service and install the display layer on the clients. This way, data is only pushed around on the (fast) intranet. When the results are ready for display, the clients get only the results (little data).

下一级是将客户端切割为业务层和显示层。将业务层转换为服务并在客户端上安装显示层。这样,数据仅在(快速)Intranet上推送。当结果准备好显示时,客户端只获得结果(少量数据)。

#3


-Make server stateless if it is not yet the case

- 如果不是这样的话,使服务器无状态

-Consider lighter remote protocols such as Hessian

- 更轻松的远程协议,如Hessian

-Latency is probably your bottle neck, consider using cache in clients and read bigger chunks of data, 1000 round trips is huge load.

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

-Consider refactoring the client to make it able to work locally and have it synchronized in the background

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

-Use a profiler to see where the application spends most time and optimize that

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

#4


Have you performed any measurements of the relative time consumption of different parts of the operation ? I wouldn't touch anything until you've measured how long individual processes take.

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

I suspect the latency issue is the key. But I would measure and determine this first, before looking at any solutions.

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

#5


Perhaps the best thing to do would be to get a better understanding of how the infrastrucure works

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

  1. Why are the files so large?
  2. 为什么文件这么大?

  3. Must the entire files be sent, or could you get by with sending just the required parts for processing
  4. 必须发送整个文件,或者您只需发送所需的部分进行处理即可

  5. What are these network calls? Are they all necessary? If so, can the calls be batched into one call?
  6. 这些网络电话是什么?它们都是必要的吗?如果是这样,可以将呼叫分成一个呼叫吗?

#6


Not sure but looks like you have some data in the 50 MB file which you want to validate/process and store in database. Is it correct?

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

Why can the client simply pass the file to server and the server do the validate/process task and store in the database? This will there are no network calls except passing the file data to server.

为什么客户端只是将文件传递给服务器,服务器执行validate / process任务并存储在数据库中?除了将文件数据传递给服务器之外,没有网络调用。

Other possibility is if you can club multiple operations in one call i.e. a session facade pattern.

其他可能性是,如果您可以在一个呼叫中进行多个操作,即会话外观模式。

#7


"High Performance Web Sites: Essential Knowledge for Front-End Engineers" by Steve Souders is a really good book on this. See here.

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

Steve's website is here.

史蒂夫的网站就在这里。

#8


I would suggest looking to making as much of this process asynchronous as possible. Do the clients need to have real time response to the processing? If not, you could move to a MOM (Messaging Oriented Middleware) concept and place JMS queues/topics in between the client and the server.

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

The client could post records to be processed onto a queue that the server is monitoring. Once processing is complete, the server would place the results to a reply-to queue that a client would be listening on. This would force a refactor, but assuming your code is loosely coupled, it should not be terribly invasive.

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

#9


Either refactor the code in a major way or rewrite the entire app. If your manager says that will take to long add a progress bar so the user thinks it goes faster.

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

#10


Each operation requires 1000 requests is a lot! This will kill any server. This is typically a problem which cannot be solved by adding more hardware or adding more bandwith. This is a design problem. Anyway I would install a profiler in order to see the server status (memory consumption, cpu, etc). Take a look at lambda probe (http://www.lambdaprobe.org)

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

#11


RMI is a very expensive protocol. I would look at replacing it.

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

#12


If you can not change the protocol, at least change the payloads:

如果您无法更改协议,请至少更改有效负载:

1) This sounds like a closed system. If yes, there is no need to use generalized Serializable protocol. Switch to Externalizable and write the minimal data required to capture object state for wire transfer.

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

2) Compress the data that is sent from server to client. Beyond object state in (1), you should also reduce the data blobs ("files") that you are moving around the net.

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

Beyond that (and this obviously depends on the system) you should explore forward caching nodes. In many applications there is a pattern to domain entity access. If there is geographic access patterns that can be exploited, you should be able to trivially create new proxy nodes that are clients to the remote server and then act as a (rmi) server to nearby (rmi) clients.

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