exhuma
exhuma

Reputation: 21727

Application Client <-> EJB calls round-trip seems slow

UPDATE: As Preston pointed out, the following problem may well be related to (de)serialisation of objects. Any ideas on how to optimize this?


I am currently fixing some things in an old JavaEE application. It's using an EJB module and an application client module. The EJB deals with all database queries. For this example consider a method getEnterprises(int year), which returns "Enterprise" entities for a given year. Currently, that's about 2500 entries.

Note: I am using the word "Enterprises" for illustrative purpose only. The real entity classes would probably not make much sense to most here ;)

Now, let's assume for this example that an Enterprise entity only has two fields: code and name. The method inside the remote bean looks like this:

public List<Enterprise> getEnterprises(int year){
    return em.createQuery("SELECT e FROM Enterprise e WHERE e.year=:year")
        .setParameter("year", year)
        .getResultList();
}

In the application client, there's a line like this:

List<Enterprise> result = requestBean.getEnterprises(1996);

This seems correct to me. What is bizarre to me, it that the call on the client takes about 15 seconds to complete! So I added some logging:

public List<Enterprise> getEnterprises(int year){
    logger.finest("Begin fetch on remote");
    List<Enterprise> output = em.createQuery("SELECT e FROM Enterprise e WHERE e.year=:year")
        .setParameter("year", year)
        .getResultList();
    logger.finest("End fetch on remote");
    return output;
}

and...

logger.finest("Begin fetch on client");
List<Enterprise> result = requestBean.getEnterprises(1996);
logger.finest("End fetch on client");

From the resulting timestamps, I realized that the call on the server completes in less than a second, while on the client it takes more that 15 secs.

Example hand-written trace:

2011-01-04 12:00 | FINEST | Begin fetch on client
2011-01-04 12:00 | FINEST | Begin fetch on remote
2011-01-04 12:01 | FINEST | End fetch on remote
2011-01-04 12:17 | FINEST | End fetch on client

So I'm guessing that the problem lies in the client/server communication. Note, that for the above example, I did not check whether the client->server communication is slow or the server->client communication. What I realized, is that the server logs show an "expected" execution time, whereas on the client it's sluggish. In other words, it might as well be something like this as well:

2011-01-04 12:00 | FINEST | Begin fetch on client
2011-01-04 12:15 | FINEST | Begin fetch on remote
2011-01-04 12:16 | FINEST | End fetch on remote
2011-01-04 12:17 | FINEST | End fetch on client

Or even:

2011-01-04 12:00 | FINEST | Begin fetch on client
2011-01-04 12:07 | FINEST | Begin fetch on remote
2011-01-04 12:08 | FINEST | End fetch on remote
2011-01-04 12:17 | FINEST | End fetch on client

I haven't dug into it that much.

As I have not that much experience with JavaEE I am a bit lost in a jungle. There are so many settings, components, that I have to look through that I do not know where to start. Can it be a server setting? A problem with the bean itself? The way I call the bean? I don't know...

... oh... it runs on glassfish, and for testing, on localhost. So the network itself is not the problem...

Upvotes: 1

Views: 1296

Answers (3)

Preston
Preston

Reputation: 3271

In order for the client to receive the list it needs to be serialized before it is sent. Try serializing it on the server to see how long it takes. Then deduct that time from your 15 seconds and see if you still have a problem.

Upvotes: 1

richj
richj

Reputation: 7529

If the profile looks something like your second hand-written trace (slow connection, fast return) it could be related to the DNS lookup. I had a similar problem recently - fast ping, very slow connection (45s) to localhost. Adding name entries into /etc/hosts gave me a fast lookup to the fully qualified host name.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500755

For anything network-related like this, my first port of call is to work out where the time is actually going: Wireshark is your friend. Try to map the log statements to network traffic. If there's a huge delay between the server logging that it's finished and the data being delivered on the network, then you should look further at the server-side configuration etc. If the data has been delivered to the client but it's taking ages for the method call to complete, look at the client. If the data is being transferred between server and client slowly across those 15 seconds, that could be something else entirely (and you may well need to look at both sides).

To make this easier to diagnose you may want to run the server and client on different machines - it can make network tracing easier if you know it has to go through a physical interface.

Upvotes: 2

Related Questions