We are using Glassfish v2 (9.1_02) at work. Our servers are not set up in a clustered environment.
We would like to have one main server as a JNDI server that can serve DataSource objects, and possibly other objects in the future, and link other servers to this one server. This way, if we change the location of a database or change a password, we do not have to update multiple servers, but instead just one.
My questions are:
Is this even a good idea to do?
Is it possible to link JNDI trees in Glassfish?
How can I accomplish this?
Has anyone accomplished this?
Thank you
This is not a good idea, a virtual machine shouldn't use a database connection established on another machine. The overhead would be silly and how could it deal with a failover?
There are much better ways of ensuring all the servers in a cluster start up with the same configuration, it really comes down to what OS you're running on.
You might want to start by looking at an "application fabric" like terracotta. RedHat also has a system (called satellite) used to distribute config files. Other environments have equivalent solutions.
Related
Everyone seems to say that you should use Tomcat's JNDI contexts to manage your JDBC connections and drivers and so forth. And after reading over the documentation, I understand the draw. But if you use it, your application must use a Tomcat container from now until the end of time. Isn't it a bad programming practice to make your application rely on such an environment configuration (especially for Java, which is supposed to be "Write Once, Run Anywhere")? How is this not a dangerous development decision?
Isn't it a bad programming practice to make your application rely on
such an environment configuration (especially for Java, which is
supposed to be "Write Once, Run Anywhere")?
Yes, in general. However, this design provides several benefits, including managed connection pooling and abstracting the database connection configuration from your application. JNDI itself is a directory service abstraction which protects you from directory API differences.
How is this not a dangerous development decision?
Using JNDI to manage JDBC connections is not specific to Tomcat. Every Java application server (GlassFish, Oracle, WebSphere, etc.) does this. So you're not tying yourself to Tomcat, just to Java.
See also: Using JNDI for Database connections
I don't know which documentation you read, but if you use JNDI, the only thing which you specify in the application, is the JNDI name of the resource you want to use (e.g. for the DB connection). Everything else is configured in the container and not part of your application (like URL of the DB, username, password etc.).
I've heard the term "clustering" used for application servers like GlassFish, as well as with Terracotta; and I'm trying to understand what the word clustering implies when used in conjunction with application servers, and when used in conjunction with Terracotta.
My understanding is:
If a GlassFish server is clustered, then it means we have multiple physical/virtual machines, each with their own JRE/JVM running separate instances of GlassFish. However, since they are clustered, they will all communicate through their admin server ("DAS"), and have the same apps deployed to all of them. They will effectively act (to the end user) as if they are a single app server - but now with load balancing, failover/redundancy and scalability added into the mix.
Terracotta is, essentially, a product that makes multiple JVMs, running on different physical/virtual machines, act as if they are a single JVM.
Thus, if my understanding is correct, the following are implied:
You cluster app servers when you want load balancing and failover tolerance
You use Terracotta when any particular JVM is too small to contain your application and you need more "horsepower"
Thus, technically, if you have a GlassFish cluster of, say, 5 server instances; each of those 5 instances could actually be an array/cluster of Terracotta instances; meaning each GlassFish server instance is actually a GlassFish instance living across the JVMs of multiple machines itself
If any of these assertions/assumptions are untrue, please correct me! If I have gone way off-base and clearly don't understand clustering and/or the very purpose of Terracotta, please point me in the right direction!
Terracotta enables you to have a shared state across all your nodes (its stateful). Basically it creates a shared memory space between different JVM's. This is useful when nodes in a cluster all need access to the same objects.
If your application is stateless and you just need load balancing and fail over you can use a solution like JGroups. In this scenario each node just handles requests and has little idea about other nodes. Objects in memory are not shared across nodes and each JVM just runs on its own and has no idea about other JVM's. This often works nicely for request / response type applications. A webserver serving content (without sessions) does this for example.
Dealing with a stateless cluster is often simpler then dealing with a stateful cluster. This is because in a stateless cluster nodes know almost nothing about each other which results in less things that can go wrong.
GlassFish sits a bit in the middle of the above concepts. Objects in memory within GlassFish are visible to all nodes. However the frontend (HTTP connectors) work stateless.
So to answer your questions:
1) Yes, those are the two most obvious reasons. However sometimes people only want failover or only want load balancing or sometimes both. Not all clustering solutions fix both of these problems.
2) Yes. Altough technically speaking Terracotta only solves the shared memory part, not the CPU part. However by solving the memory part it automatically solves the CPU part since you can now just add JVM's to the shared memory space.
3) I don't know if thats practically possible but as a thought experiment; Yes.
Clustering can mean one of the following:
Multiple instances can be managed as one. Deploy an application to the cluster, it is deployed to all instances in the cluster. Make a configuration change, and that change will be pushed to all nodes in the cluster. GlassFish supports this out of the box.
Service Availability. If any one instance fails, the application is available on another instance. Without high availability enabled, any instance failure also results in session loss for any session being managed by that instance. GlassFish supports this out of the box.
High availability. If any one instance fails, the application is available on another instance, and there is no session loss because a session replica is also maintained on another instance. GlassFish supports this. You will have to choose either #2 or #3 in any one cluster.
What you are asking about IMHO is really #3, because it is the only real case where Terracotta - in the context of high availability clustering - will offer value w/GlassFish. GlassFish already offers built-in high availability, so there had better be a very good reason to add Terracotta to the solution because it will complicate the deployment architecture.
The primary reason I can think of adding Terracotta is that you may want to offload session management to a data grid and free up GlassFish to run business logic. This may be due to more frequent garbage collection or wanting to manage more users per GlassFish instance. However, I'm not sure that Terracotta can do this seamlessly. With GlassFish built-in HA clustering, replicating sessions is seamless (no application logic modifications). You may have to write code to put/get data from a Terracotta cache I'll let you research :-) Oracle GlassFish Server also integrates (seamlessly) with Coherence to solve this problem. You can separate session management into a Coherence data grid without modifying your application code.
Unless you know for a fact up front that your application must scale to a very large number of concurrent users, start with built-in HA clustering, run tests, and go from there.
Hope this helps.
Is there any easy way in a Java EE application (running on Websphere) to share an object in an application-wide scope across the entire cluster? Something maybe similar to Servlet Context parameters, but that is shared across the cluster.
For example, in a cluster of servers "A" and "B", if a value is set on server A (key=value), that value should immediately (or nearly so) be available to requests on server B.
(Note: Would like to avoid distributed caching solutions if possible. This really isn't a caching scenario as the objects being stored are fairly dynamic)
I'm watching this to see if any simple solutions appear, but I don't know of any myself. Last time I asked something like this, the answer was to use a distributed object store.
Our substitute was manual notification over HTTP to a configured list of URLs, one for each Web Container's direct server:port combination. (That is, bypassing any fronting proxy/web server/plugin.)
Try using the WebSphere workarea
We have Java Enterprise applications deployed on to multiple servers. There are replicated servers running same application to load-balance(let's call them J2EE servers).Note that this is not clustered.
There is a common server (let's call it props server) which hosts all properties files relevant to all applications. The folder containing properties files is NFS shared between all the other J2EE servers.
The issue is that you can see props server is a single point of failure. If it did not come up or if the NFS share gets corrupted, other servers wont be able to load properties.
What are the options to avoid this hard dependency ?
Given the constraint that we do not want to duplicate property files to all servers.
If you are having this problem, the more scalable solution would be to look into using this:
http://java.sun.com/j2se/1.4.2/docs/guide/lang/preferences.html
This abstracts away things like where they are located. You can then have these settings stored in an LDAP server, cloned properties, or whatever is best - you can even use different mechanisms for different environments.
One of approaches would be for every J2EE server to have a cloned set of configuration files. This implies a constraint that every time a config is changed for one server it should be rsync-ed among all others (after the change is known to be OK).
The positive aspect is clear, you really have N independently configurable servers and a config change kills (if kills) only one server.
The negative aspect is that sometimes someone will forget to do 'rsync' & 'bounce' after a config change on a single box.
Given the constraint that we do not
want to duplicate property files to
all servers.
If you are ok to copy properties to some servers, elect a leader and make sure any modification is propagated to backups, then Paxos is your friend. If the leader fails, a new leader can be elected. I have updated the wikipedia page. It contained errors regarding the description of the algorithm.
Take a look at the PAXOS algorithm. It is designed to bring multiple servers to consensus.
http://en.wikipedia.org/wiki/Paxos_algorithm
I have a problem. I need to host many (tens, hundreds) of small identical JAVA web applications that have different loads during one time. I want to use Glassfish V3. Do I need to use a load balancer and clusters or something else? Advise where can I find information about similar problems and their solutions...
I need to host many (tens, hundreds) of small identical JAVA web applications that have different loads during one time.
For hundreds of webapps, you will very likely need more than one app server instance. But this sounds odd to be honest.
I want to use Glassfish V3. Do I need to use a load balancer and clusters or something else?
Right now, GlassFish v3 offers only basic clustering support using mod_jk (i.e. no load balancer plugin, no centralized admin, no high availibility). If you are interested, have a look at this note that describes the configuration steps of GFv3 and mod_jk.
For centralized admin and clustering, you'll have to wait for GlassFish 3.1 (see the GlassFish Roadmap Community Update slides).
You could check out Gigaspaces. I have seen it used in conjunction with Mule for a somewhat similar project. ESBs tend to be overkill in my opinion, but it sounds like you have quite the task to conquer.
Based on your requirements, you cannot do load balancing since the load is predetermined by which client the request is for. Each request has to go to the app handling that client, so it cannot be distributed outside the set of apps dedicated to that client.
You can use multi-threading. you could set up the configuration so that different threads handle different clients. However, it might be better to simply have a server that can handle requests from different clients. Based on the client sent with the request, it would be dispatched to a different database etc.