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
Related
I am maintaining/developing a web application which is deployed in multiple nodes of a websphere cell. There are two nodes in a WAS cell. Each node has a web server in which my web application is deployed. So there are two instances of web application.
I can use the URL provider to read the property file from the web application. (Reference)
But I have to maintain an identical property file on each server. When I need to change I have to change it on both servers.
Is there anyway I can maintain a single property file and access it from web application deployed on different places? Or any other better way to do this?
If you read your property files using a URL resource (a good practice), then you can host your property file on a single internal web server. The URL resource reference in each of your web containers would point to this internal web server. Then you would only have to change the property file in your internal web server document root.
This practice has several drawbacks.
Security - By externalizing your configuration, you now have another attack vector. You could apply mutual-auth SSL to this scenario, but that gets more complicated than simply maintaining two property files.
Availability - Now your internal web server is a single point of failure. You could cluster it; but then you have more servers to manage, precisely what you were trying to avoid.
Latency - Reading configuration off box involves more latency than the file system.
I believe the property file per node is going to work best. If copying a file twice is so much more onerous than copying it once, just script it. That will scale to however many nodes you opt to deploy.
CAVEAT: This is a bit outside my experience, but if I'm understanding your question correctly...
If you have federated the servers as a single cluster, I believe the Intelligent Management tools can take care of copying an equivalent configuration out to all of them. Each would then read the configuration information from their own local copy.
We're trying to design a new addition to our application. Basically we need to submit very basic queries to various remote databases accessed over the internet and not owned or controlled by us.
Our proposal is to install a small client app on each of the foreign systems, tiered in 2 basic layers, 1 that is tailored to the particular database its talking to, to handle the actual query in SQL or whatever, the other tier would be the communication tier to handle incoming requests and send back responses. This communication interface would be the same over all of the foreign systems, ie all requests and responses have the same structure.
In terms of java remoting I guess this small client app would be the 'server' and our webapp (normally referred to as the server) is the 'client'.
I've looked at various java remoting solutions (Hessian, Burlap, RMI, SOAP/REST WebServices). However am I correct in thinking that with all of these the 'server' must run in a container, ie in a tomcat/jetty etc instance?
I was really hoping to avoid having to battle all the IT departments controlling the foreign systems to get them to install very much. The whole idea is that its thin/small/easy to install/pain free. Are there any solutions that do not require running in a container / webserver?
The communication really is the smallest part of this design, no more than 10 string input params (that have no meaning other than to the db) and one true/false output. There are no complex object models required. The only complexity would be from security/encryption etc.
I wamly suggest somethig based on Jetty, the embedded HTTP server. You package a simple runnable JAR with dependency JARs into a ZIP file, add a startup script, and you have your product. See for example here.
I often use Sprint-Remoting in my projects and here you find a description how to use without a container. The guy is starting the jetty from within his application:
http://forum.springsource.org/showthread.php?12852-HttpInvoker-without-web-container
http://static.springsource.org/spring/docs/2.0.x/reference/remoting.html
Regards,
Boskop
Yes, most of them runs a standard servlet container. But containers like Jetty have very low footprint and you may configure and run Jetty completely out of your code while you stay with servlet standards.
Do not fail to estimate initial minimal requirements that may grow with project enhancement over time. Then have a standard container makes things much more easier.
As you have tagged this question with [rmi], RMI does not require any form of container. All you need is the appropriate TCP ports to be open.
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 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.
I have heard that this is what JavaRebel does but is there any other good way to deploy a new version of an EAR while allowing users to remain active on the previous version? We use JBoss for the application server...
It's not what JavaRebel does. JavaRebel (according to description) hot-replaces the classes in memory. It's not acceptable in the case of existing connections to the system, since the updated classes may break the client's logic.
Once a company I was working for had a similar problem, and it was solved this way:
a smart router was used as a load-balancer
the new version was deployed to 50% of the nodes of the (new) cluster
new connections were delivered strictly to these updated nodes, old ones were balanced between old nodes
old nodes were took off-line (one-by-one, to keep number of clients per node within limits)
at the same time, new version was deployed to off-line "old" nodes and they were brought up as new nodes
due to EJB clustering, the sessions and beans were picked up by other old nodes
eventually (in a few hours), only one old node left, having a single instance of old version and all clients using old version were connected to it
when the last old client got disconnected, that node was too brought down
Now, I'm not a networking guy, and cannot give you many details (like what was the router hardware and such). My understanding this can be set up pretty easy, except, if I remember right, we had to setup an additional Weblogic domain to deploy new versions of the application (otherwise it would be conflicting with the old one on JNDI names).
Hope that helps.
P.S. Ichorus provided a comment saying that the app is deployed on clients' servers. So the router trick may be not feasible. Now, I see only one viable solution right now ( it's 21:52 now, I may overlook things :) ) --
Develop new version with "versioned" JNDI names; e.g. if Customer bean was under ejb/Customer in version 1, in version 2 it would be under ejb/Customer2
Have a business facade in the application with a stable basic interface (Factory-style) which, when asked for Customer bean, tries to find the highest-versioned JNDI name (not on every call, of course, can cache for a hour or so). That facade could (and should) be deployed as a separate application -- and never or very rarely updated
Now every new client would get access to the latest application deployed, and the applications won't conflict.
This approach takes a careful planning and testing, but should work IMHO.
I recently modified a few applications in a similar way to let them coexist in the same domain (before they used the same JNDI name for different data sources).
As I understand WebLogic has a feature called parallel deployment to eliminate downtime during EAR version upgrade. You can deploy the new version without stopping the existing application and once the new version deployed successfully you can switch over transparently from the old one to new one.
I am not sure if other application server supports this.
Ref: http://edocs.bea.com/wls/docs100/deployment/redeploy.html#wp1022490
Vladimir's suggestion around using a load balancer is a pretty sure way of achieving what you want. Keep in mind, it need not necessarily be a high-end hardware load balancer. Rather, if you front your JBoss server with a native web server (Apache or IIS) and mod_jk or mod_proxy, you can maintain one common web facade and implement the applicable loading and routing routines at EAR upgrade time.
//Nicholas
I think you might want to look into Spring using OSGI framework.
http://www.springframework.org/osgi