Improve performance by less server calls

Hi,

I have a problem with an application that are to slow. One of the

problems is that the client calls the server alot of times. What I would

like to do (what I should have done from the start) is minimize the calls

to the server. But the calls are scattered around the client code so I

can磘 see an easy way of doing this.

(Every server call go through a class called ServerInteractor.)

I think this might be a very common newbie mistake, so I hope there is

someone out there who knows a way to solve this.

Thanks!

[582 byte] By [Lisa_Ra] at [2007-10-2 1:19:04]
# 1

> Hi,

> I have a problem with an application that are to

> slow. One of the

> problems is that the client calls the server alot of

> times.

how do you know that? have you profiled the app to get hard numbers, or is this your gut feel?

>What I would

> like to do (what I should have done from the start)

> is minimize the calls

> to the server.

what kind of calls are we talking about?

>But the calls are scattered around

> the client code so I

> can磘 see an easy way of doing this.

> (Every server call go through a class called

> ServerInteractor.)

maybe you need a front controller servlet. all calls go through that

>

> I think this might be a very common newbie mistake,

> so I hope there is

> someone out there who knows a way to solve this.

>

> Thanks!

duffymoa at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

>

> I think this might be a very common newbie mistake,

> so I hope there is

> someone out there who knows a way to solve this.

Do you actually have to move all of the data? Or are you moving large blocks just to get small pieces?

And is this a GUI or something else?

And does the back end have a way to return all of the data at once or can you add that?

jschella at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

Thanks for your replies! :-)

I will try to explain what the app does.

It is a Swing application that pressent data in windows that are build

at runtime. So when the the application opens a window it calls the

server to get information on how the window should look. What kind of

controlls it should display (textfields, buttons, comboboxes or checkboxes...), where they should be displayd, what databasefield

they represent and conection to other windows and so forth.

>how do you know that? have you profiled the app to get hard numbers, or is this your gut feel?

We used a tool to monitor the server calls, so I know that there are alot

of comunication going on between the client and the server. When we

opened a window the client called the server 100 times. This was the largest window in the app, so this is an extreme case, but even with a

smaller window it calls the server alot of times.

>maybe you need a front controller servlet. all calls go through that

Could you plesase explain how this works?

>Do you actually have to move all of the data? Or are you moving large >blocks just to get small pieces?

When the application builds the windows it requires alot of data, so I

think it really needs all the data.

>And is this a GUI or something else?

Yes, it is a GUI.

>And does the back end have a way to return all of the data at once or >can you add that?

Yes, the back end should be able to return, maybe not all at once, but

larger blocks then it does today.

Lisa_Ra at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 4

> (Every server call go through a class called ServerInteractor.)

Given your second response it is likely that you would benefit from rewritting your ServerInteractor class to agregatete the data into a single network transaction.

Assuming you instantiate this Class for each window, you could make it request all of the data at once when it is constructed and store it in a cache inside the ServerInteractor object.

If you reuse a single instance for all dialog windows then you may need to implement a new method to prime the cache with the setup data. Then modify the individual calls to ServerInteractor to take the data from the Cache.

If the application reuses the same dialog windows repeatedly you may also want to consider reusing the new cachable ServerInteractor objects through the use of a resource pool so that the traffic is further reduced.

Alternatively dont dispose of the dialogs, just hide them and they could also be reused.

MartinS.a at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 5
Thanks for your good ideas, Martin!
Lisa_Ra at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 6

My experience is that if your app is taking too long to load, it's likely the amount of data you are retrieving, not the number of times you call the server.

I would suggest updating the gui code to start displaying data before it is all retrieved. This is not going to be feasible if you make one big RMI call. I'm going to guess you will attempt to try as one call. Keep the current code somewhere because you might find that the one big call doesn't really help. I was on a project where the 'one big call' methodology caused most of our problems. We used this methodology based on the theory that less calls to the server was better. It did not pan out. What the user saw was a wait message while we serialized a large chunk of data across the network.

dubwaia at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 7

Sounds like the problem is building all those screens at runtime from scratch ever time.

Most likely caching the screen after the first time you get the information about it and reusing that cached version will yield better performance (less network/database calls as well as less object creation), but without experimenting it's impossible to be certain.

Run a profiler (or put in some timing statements where you expect the problems to be) to figure out where the slowdown is and hope it's not a general problem but rather focussed in a single place :)

I've a somewhat similar problem and that strategy reduced the likely cause to just a few method calls to a method I knew in advance would be expensive (but hadn't realised would be THAT expensive).

Now I just have to find the time to restructure that method, the performance problem having been reduced in status by the project owner in favour of other things).

jwentinga at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 8

Thanks for your replies!

>My experience is that if your app is taking too long to load, it's likely the amount of data you are retrieving, not the number of times you call the server.

Do you think this might vary if you have a slow or fast network-connection?

>Most likely caching the screen after the first time you get the information about it and reusing that cached version will yield better performance

I have implemented a client cache that caches information about the

windows. This improves performence alot! The second time you open

a window it takes 4 seconds instead of 25.

But now I am facing another problem. After runing the app for a while I

get an outOfMemoryError. Before the client cache I never got this error,

but now it always comes after I run the app for a while. So this makes

me think that the cache "is to be blamed". Is this a sign for a bug in my

caching code? I have read that you can increase the memory when you

start the app, but is that a guarantee for this never to happen?

Lisa_Ra at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 9

> Thanks for your replies!

>

> >My experience is that if your app is taking too long

> to load, it's likely the amount of data you are

> retrieving, not the number of times you call the

> server

> Do you think this might vary if you have a slow or

> fast network-connection?

We had this problem on a local network. A slow network would just be worse. Actually, we had to support slow connections (56K) so we ended up compressing the messages.

> >Most likely caching the screen after the first time

> you get the information about it and reusing that

> cached version will yield better performance

>

> I have implemented a client cache that caches

> information about the

> windows.

This was the solution we came up with for the 'big spit-ball' message pattern. We cached as much information as possible. On shutdown of the app, we serialized the cache to disk. We implemented a small message that would report when parts of the cache items were no longer valid. By making the cache block the client, we were able to do this seamlessly.

> This improves performence alot! The second

> time you open

> a window it takes 4 seconds instead of 25.

> But now I am facing another problem. After runing the

> app for a while I

> get an outOfMemoryError. Before the client cache I

> never got this error,

> but now it always comes after I run the app for a

> while. So this makes

> me think that the cache "is to be blamed". Is this a

> sign for a bug in my

> caching code? I have read that you can increase the

> memory when you

> start the app, but is that a guarantee for this never

> to happen?

From your description, it sounds like increasing the max heap size will merely delay the error.

You've got two options at this point: 1. Start looking through the code for the cache and make sure you are not holding onto expired information. 2. Get a profiling tool and use it to figure out where the leak is.

I would attempt 1. since you just wrote the cache but I find that guis are the worst for sneaky leaks.Watch out for inner classes (not static nested classes) because they contain a hidden reference to the outer instance.

dubwaia at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 10

Hi,

I do not understand your problem. You make a Client - Server App, but you use java and TCP/IP.

The problem is that you make a Client-Server Architecture.

I have tow ideas:

I use Citrix or similar (depend you system),

You must use a painter of Swing (send a XML with the data to a Swing client that paint the data).

The 1st ideas, is very simple, if you have a client-server architecture Citrix enable this program easy.

the second need more develop.

barbywarea at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 11

> Hi,

> I do not understand your problem. You make a Client -

> Server App, but you use java and TCP/IP.

>

What? You statement seems to suggest that you confusing terms some how.

> The problem is that you make a Client-Server

> Architecture.

>

> I have tow ideas:

>

> I use Citrix or similar (depend you system),

>

> You must use a painter of Swing (send a XML with the

> data to a Swing client that paint the data).

>

What again? That is a very limited solution and doesn't have much at all to do with the general classification of a client server architecture.

> The 1st ideas, is very simple, if you have a

> client-server architecture Citrix enable this program

> easy.

I doubt it.

jschella at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 12

You have make an application that use a lot of call to server, this is a typicall client-server application for an intranet or for a net with 100Mb of band.

We have some apps that use this implementation, I use Citrix or Terminal Server for run the client in the intranet net, this software enable use an intranet app via internet.

thanks you.

barbywarea at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 13

> You have make an application that use a lot of call

> to server, this is a typicall client-server

> application for an intranet or for a net with 100Mb

> of band.

>

> We have some apps that use this implementation, I use

> Citrix or Terminal Server for run the client in the

> intranet net, this software enable use an intranet

> app via internet.

>

And I used Apache and JBoss and Tomcat and Spring and perl and C all to create client-server apps. And there are many other ways to do it as well.

jschella at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 14

> We have some apps that use this implementation, I use

> Citrix or Terminal Server for run the client in the

> intranet net, this software enable use an intranet

> app via internet.

IMO Citrix is what you use when your app was designed poorly and with too little forsight.

dubwaia at 2007-7-15 18:40:21 > top of Java-index,Other Topics,Patterns & OO Design...
# 15
Yes, I think the same.But, I to belong to production division. When I receive an apps, I do not change It, I only could enable it.When I have a Web Developper, I develop for a modem not for a T1.Thanks
barbywarea at 2007-7-20 14:51:18 > top of Java-index,Other Topics,Patterns & OO Design...
# 16

>On shutdown of the app, we serialized the cache to disk. We

>implemented a small message that would report when parts of the

>cache items were no longer valid. By making the cache block the >client, we were able to do this seamlessly

This sounds very interesting. How did you implement the message

that reported when the cached items were no longer valid?

Thanks!

Lisa_Ra at 2007-7-20 14:51:18 > top of Java-index,Other Topics,Patterns & OO Design...
# 17

> >On shutdown of the app, we serialized the cache to

> disk. We

> >implemented a small message that would report when

> parts of the

> >cache items were no longer valid. By making the

> cache block the >client, we were able to do this

> seamlessly

>

> This sounds very interesting. How did you implement

> the message

> that reported when the cached items were no longer

> valid?

It was a bit ugly but it worked.

We created a table with keys and modification dates. The keys referred to the cached data group. Then we had the DB add a trigger to each of the tables that was was associated with the cached data. When an update occured, it would set the modification date in table mentioned above for any key related to the table.

We then had a thread that polled the table looking for changes in modification date. When it saw a 'hit', it would rebuild the cached data for the key and replace it in the cache.

The client had a similar process that where it would also check the modification dates of the keys and when any were changed, retrieve them from the server side cache.

With polling intervals of 30 seconds, we were able propagate all changes to cached data to all clients in around a minute of the update.

This solved two problems. It eliminated a lot of cache loading on startup of the application (most important) and during the application life-cycle. It also solved an issue where uses were complaining about stale data. The original caching was only time-based. Unless we reloaded a lot of the caches almost constantly, the users were unhappy. Running the caches at full reload every 30 seconds was extremely inefficient.

Be forewarned, this did not go off easily. The main reason was that the cache was originally designed against the JCache spec (I was told) and was competely one-dimensional in that it did not support anything but time-based reloads. So I was forced to gut the classes and redesign while on a 'death-march', 80-hour week push. If you want to attempt something like this, I strongly suggest approaching the cache design on a clean sheet of paper and then seeing whether any existing cache framework can help. I may be that newer frameworks (Spring?) support this kind of model.

dubwaia at 2007-7-20 14:51:18 > top of Java-index,Other Topics,Patterns & OO Design...
# 18
Thanks for your reply!
Lisa_Ra at 2007-7-20 14:51:18 > top of Java-index,Other Topics,Patterns & OO Design...
# 19

Hi,

I review the problem, and I see in the past a page that could solve your problem. I attach the page

http://www.javaworld.com/javaworld/jw-07-2002/jw-0712-jdbcdriver3-p2.html

I seems that is possible make a JDBC that use Chunk in order to minimize the server call.

You could use the driver for caching and another strategies.

Thanks

barbywarea at 2007-7-20 14:51:18 > top of Java-index,Other Topics,Patterns & OO Design...