|[ Team LiB ]|
JNDI Best Practices
In this section, we look at some tips that can be useful in improving performance while using JNDI.
Avoiding Storing Application Data in the JNDI Tree
The JNDI tree should normally be used only to store objects when WebLogic Server starts up. Like any other naming service, the JNDI tree should not be used for frequent updates because it isn't designed for such tasks. You must use Session objects, cookies, or even databases to store temporary application data. Any updates to the JNDI tree and the objects within it have to be propagated to the other servers in the cluster. This can be expensive, especially if the object is heavy.
Optimizing Lookups from Remote Clients
While inside the JVM of WebLogic Server, making JNDI lookups are highly optimized. This amounts to making a direct method call inside the JVM. Hence, you need not be too concerned about optimizing your code in this scenario. However, performing JNDI lookups from a remote client is another story. Consider each lookup operation as a round-trip between the client and the server over the network. You should therefore keep JNDI lookups from remote clients to the bare minimum because they can negatively affect performance.
So, how do you achieve this? One alternative is to cache the results of a lookup locally and reuse the cached contents rather than going back to the server every time. Such lookups can be performed in the initialization routines of the application.
However, you should understand that caching results isn't a viable solution all the time. In cases where data can change often, you usually won't want to use a cached copy because you can't be sure whether you have the latest data. In such cases, one option might be to group operations that require JNDI lookups within your application. However, consider that JNDI values are not supposed to change that often, so such a situation should rarely arise.
In cases where lookups cannot be performed in the initialization routine, consider caching the InitialContext locally. Looking up the InitialContext is a very expensive operation. You can cache the initial context locally and reuse it. It's normally a good idea to provide for a re-lookup of the initial context (refresh), if you encounter any errors while looking up an object using the cached InitialContext object.
Considering the Use of a Service Locator Pattern
An extension of the caching strategy discussed in the previous section is the Service Locator pattern. A service locator object gets rid of redundant and expensive JNDI lookups by caching the service objects after a first lookup. This technique maintains a cache of service objects and provides methods to access them. Different portions of your client application can use this service locator object to obtain the service objects as and when they need it. They don't make direct JNDI lookups; rather, they go through the service locator object. Therefore, the service locator serves as an interceptor object between the client and the JNDI tree. Service locator objects can be programmed to refresh the service objects at regular intervals. Streamlining JNDI lookups using a service locator object helps to reduce network traffic, and hence it increases performance. Figure 8.5 shows this pattern in use.
Trying to Avoid Nonreplicated Bindings
As discussed earlier, using nonreplicated bindings increases the possibility of conflicts within the JNDI tree. By not replicating the binding, you're also essentially reducing the effectiveness of the cluster; clients must connect to that server to be able to get hold of the bound object. This can be a performance bottleneck, and effectively nullifies the advantages of having a cluster. You must therefore avoid using nonreplicated bindings unless you're absolutely convinced about the need for them.
|[ Team LiB ]|