Syncing of files in a filesystem on a clustered environment - java

I have a Java based CRUD service which allows creation, retrieval, update and delete of files on/from the filesystem. This service can be deployed in a clustered environment.
Are there any design patterns or solutions which can help sync these files between the nodes in a cluster?
Can the folders be configured for sync?
Is there a chance (e.g. in case of an update) that a user on one node will not get the updated file?
I am fine with solutions that are tomcat, websphere or weblogic specific.
Thank you.

Unless you specifically want to code this yourself, why not use a distributed file system like NFS or, if you would like something Java-based, the Hadoop Distributed File System (HDFS) instead. More information can be found here.

Related

What is a better way to change variable in runtime server?

We maintain our server once a week.
Sometimes, the customer wishes that we change some settings which is already cached in server.
My colleague always write some JSP code to change these settings which are stored in the memory.
Is it a good method to use this kind of methodology?
If our project is not a Web container, which tools can help me?
Usually, in my experience, the server configuration is not stored only in memory of server:
What happens that after a configuration change, the server has been restarted / just went down for some system reason?
What happens if you have more than one instance of the same server to work on (a cluster of servers in other words)?
So, usually, people opt for various "externalized configuration" options that can range from "file-based" configuration + redeploy the whole cluster upon each configuration change, to configuration management servers (like Consul, etc.d, etc). There are also some solutions that came from (and used in) a java world: Apache Zookeeper, Spring cloud config server to name a few, there are others. In addition, sometimes, it's convenient to store the configurations in a database.
Now to your question: If your project is not a web container and you don't care that configuration will "disappear" after a server restart and you're not running a distributed cluster of servers, then, using JSP indeed doesn't seem appropriate in this case.
Maybe you should take a look at JMX - Java management extensions, that have a built-in solution so that you probably will be able to get rid of a web container (which seems to be not used by your team anyway other than for JSP modifications that you've described).
You basically need in memory cache, there are multiple solutions found in answers which include creating your own implementation or using existing java library. You can also get data from database and add cache over the database layer.

Configuration management server for java enterprice application

We have an java enterprise application that is supposed to run on cluster of servers. The application consists of different WARs hosted by some web containers running on these servers.
Now we have a lot of different configurations for this application, to name a few:
Relational DB host/port, credentials and so forth
Non Relational DB configurations - stuff like mongo, redis and so forth
Internal lookup configurations (how to obtain a web service in SOA architecture, stuff like that).
Logging related configuration, log4j.xml
Connection pooling configurations
Maybe in future some internal settings for smart load balancing, maybe Multi Tenancy support
Add to this multiple environments, test/staging/production/development and what not, having different hosts/ports for all aforementioned examples and we and up with a dozen of configuration files.
As I see it, all these things are not something related directly to the business layer of the application, but rather can be considered "generic" for all applications, at least in the java enterprise world.
So I'm wondering whether exists some solution for dealing with configuration management of this kind???
Basically I'm looking for the following abilities:
Start my war on any of my servers in cluster with a host/port of this configuration server.
The war will "register" itself and "download" all the needed configurations. Of course it will have adapters to apply this configuration.
This way, all my N wars in different JVMs in cluster start (they're all share-nothing architecture, so I consider them as independent pieces of deployment)
Now, if I want to change some setting, like, setting the log level of some logger to DEBUG, I go to the management console UI of this configuration server and apply the change.
Since this management center knows about all the wars (as they were registered), it should notify them about the setting change. I want to be able to change settings for one specific WAR or cluster wide. If one of the web servers that hosts the application gets restarted it will again ask for configuration and will get the configuration including the DEBUG level of that logger.
I'm not looking for solution based on deployment systems like puppet, chef and so forth since I want to change my settings during the runtime as well.
So far I couldn't find any descent ready solution for this. Of course I can craft something like that by myself, but I don't want to reinvent the wheel, So I'm asking for advice here, any help will be appreciated.
Thanks in advance

How to hold data for jar as library with cluster awareness

I am creating a library (java jar file ) to provide a solution of a problem. Library is mainly targeted for web application (j2ee application) can be used with spring and other framework.
Targeted j2ee application will be deployed in clustered environment.User will use this library by adding it in application class path.
Library has a dependency of some configuration which is packaged itself in library (jar) which will be used at run time.
At run time configuration can be modified.
As it is targeted for clustered environment, In case of any modification to configuration , updated configuration must be replicated to all of nodes of clustered environment.
As per my understanding there can be two ways to hold configuration to use at run time (I am not sure correct me if I am wrong)
1.Store configuration in file
2.Store configuration in database
In first approach (store configuration in file)
There will a property file in library to hold initial configuration .
At server start up time configuration from property file will be copied to some file (abc.xml) at server physical location.
There will be set of APIs to perform CRUD action in abc.xml file from user home location.
And every time abc.xml file will be used.
In this approach holding data is possible but for clustered environment I am not getting how it will update all the nodes of cluster in case of modification.
In second appraoch (store configuration in database table)
While publishing toolkit (jar file) sql table queries also published with jar.
User have to create table using that queries.
There will a property file in library to hold initial configuration .
At server start up time configuration from property file will be copied to database.
There will be set of APIs to perform CRUD action on database.
As there is any modification to configuration all nodes of cluster can updated with latest data using some third party tool (Hazel cast or any thing else.)
In analysis I found Quartz uses database approach to hold its configuration.
So when one download quartz distribution, it also have sql queries to create required tables in database, that will be used by quartz it self.
I want to know what are the standard design pratices to hold configuration in library (jar) form and what are the factor need to be noticed in such cases.
There are other solutions as well. Use a cluster aware caching technologies like EhCache or Apache JCS or Hazelcast. Use the cache API to retrieve configuration data from the library. You could add in a listener within your library to poll on to the configuration file and update the cache.
If you are planning to use solution 1 which you mentioned, you could set up a listener within your library which listens to the configuration file and updates the server copy whenever there is a change. Similarly for Solution 2 as well but if I were in your similar situation, I would rather use a caching technology for frequently accessed data(configurations). The advantage it would give me is that I would not have to update the configuration in all the nodes because it self replicates.

Coordinated save in database and disk in java

In my task I need to save file on disk and update info about in database.
Exception can happen when saving file and when updating info in database.
Do exist some ready open source solutions for it or it need write from scratch?
Thanks.
There's XADisk which provides transactional access to file systems. From their web site:
XADisk (pronounced 'x-a-disk') enables transactional access to
existing file systems by providing APIs to perform file/directory
operations. With simple steps, it can be deployed over any JVM and can
then start serving all kinds of Java/JavaEE application running
anywhere.
In Java, enterprise transactions management is ruled by the JTA spec wich is used in Java EE.
JTA allows to create several TransactionManager with differents implementations (one for database, one for file) and make them work together to define a cross-transaction
I think this could be a way for you to do what you want
Outside of a container, there are possibility to integrate JTA. You should have a look at Spring or JBoss implementations
Look at this blog post for more information about Spring and transactions usage
The file system isn't directly supported by Java EE, but you could implement/ search for a resource adapter for the file system.
http://docs.oracle.com/javaee/6/tutorial/doc/gipgl.html
http://docs.oracle.com/javaee/6/tutorial/doc/giqjk.html

How do I save server state between webapp deployments not relying on a database?

We have a utility spring-mvc application that doesn't use a database, it is just a soap/rest wrapper. We would like to store an arbitrary message for display to users that persists between deployments. The application must be able to both read and write this data. Are there any best practices for this?
Multiple options.
Write something to the file system - Great for persistence. A little slow. Primary drawback is that it would probably have to be a shared file system, as any type of clustering wouldn't deal well with this. Then you get into file locking issues. Very easy implementation
Embedded DB - Similar benefits and pitfalls as just writing to the file system, but probably deals better with locking/transactional issues. Somewhat more difficult implementation.
Distributed Cache - Like Memcached - A bit faster than file, though not much. Deals with the clustering and locking issues. However, it's not persistent. Fairly reliable for a short webapp restart, but definitely not 100%. More difficult implementation, plus you need another server.
Why not use an embedded database? Options are:
H2
HSQL
Derby
Just include the jar file in the webapps classdir and configure the JDBC URL as normal.
Perfect for demos and easy to substitute when you want to switch to a bigger database server
I would simple store that in a file on a filesystem. It's possible to use an embedded database, or something like that, but for 1 message, a file will be fine.
I'd recommend you store the file outside of the application directory.
It might be alongside (next to) it, but don't go storing it inside your "webapps/" directory, or anything like that.
You'll probably also need to manage concurrency. A global (static) read/write lock should do fine.
I would use JNDI. Why over-complicate?

Categories

Resources