• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

How to serve static resource via one instance of a web application in a clustered environment

 
Ranch Hand
Posts: 56
Android Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All,

Apologies if this is not the right forum but this seems to be the best fit for my question. So please feel free to move it around.

I am working on an application that is deployed on a cluster of JBoss servers accessible via a load balancer. There is a set of data originating from another external service that I would like to expose as part of my application. But since this service is load sensitive, I would like to call this service from a separate standalone Java application only from one instance on regular intervals and put the data in a file which will be statically accessible over HTTP by the container itself. However, since this file will exist only one instance, if a request is routed to any other instance in that cluster, it will result in a 404 File Not Found. So this means that I need to make this file accessible on all instances.

One approach that I was considering was to have a servlet with the servlet mapping url pattern match exactly as the file name that will hold the data. If the instance on which a request lands is the one instance where the file exists, it should serve the file or else the request goes to the servlet with the same url pattern as the file, which will then fetch the file from the one instance where the file exists and return that in response.

However, when I use the same url pattern for a servlet as a static file, the servlet is picked up first and the static resource is not looked up at all. Is there a way I can tell the container to look for the static resource first before looking up the servlet?

Second approach that I could think of was to use a filter with the same url pattern that will check for the existence of the file and if the file exists, let the container handle it or else get the file from instance where this file exists and return the same back in the response.

Can you think of any other approaches and the pros and cons of each before I decide which approach to take forward?

Regards
Dinkar
 
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't see this as JBoss-specific - the same issue could arise with any app server.

One approach that I was considering was to have a servlet with the servlet mapping url pattern match exactly as the file name that will hold the data. If the instance on which a request lands is the one instance where the file exists, it should serve the file or else the request goes to the servlet with the same url pattern as the file, which will then fetch the file from the one instance where the file exists and return that in response.


Sounds complicated. Why does it matter whether the file is served by a servlet or directly? Why not always serve it via the servlet? If performance is of utmost concern, the file contents can be cached in memory after it has been fetched initially, thereby avoiding disk access on all instances.

If you have an Apache in front of the app server, you could put the file into a directory that is handled by Apache, thus avoiding the cluster issue altogether.
 
Bartender
Posts: 2292
3
Eclipse IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ulf Dittmer wrote:Sounds complicated.



Agreed. Whenever I feel a solution is too complicated, I wonder if it is the right path to follow.

So the problem is that there is some data that is generated externally, and since your application is in a clustered environment, it might be handled more than one time (i.e. the number of servers in the cluster), and if you save this set of data as a file, then it would exist in only one of the servers, and if a server different from the one the file is saved in handles a request, then the file won't be found.

Well, what you can do is, since this set of data is handled on regular intervals, you could create a Quartz job and configure it to work in a clustered environment, it's pretty easy (you can find how to do it here). Then, regarding the file, you could save it in a database and retrieve its content from there. Then, no matter what is the server handling the request, the file would always be found.
 
Dinkar Chaturvedi
Ranch Hand
Posts: 56
Android Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ulf Dittmer wrote:Sounds complicated. Why does it matter whether the file is served by a servlet or directly? Why not always serve it via the servlet? If performance is of utmost concern, the file contents can be cached in memory after it has been fetched initially, thereby avoiding disk access on all instances.
If you have an Apache in front of the app server, you could put the file into a directory that is handled by Apache, thus avoiding the cluster issue altogether.



The data in the file changes every minute and we would like to serve the latest content always. So caching is not an option. Performance is not a big concern however, I was just exploring if it is possible to serve the content directly by the container instead of having my servlet streaming the content in the response. Though in this case also, (please correct me if I am wrong) the content will be served by the container's default servlet so I guess I wont gain much here.

Unfortunately, we dont have Apache but we have a load balancer before the cluster so the file has to be there on one of the cluster instances.

Roberto Perillo wrote:So the problem is that there is some data that is generated externally, and since your application is in a clustered environment, it might be handled more than one time (i.e. the number of servers in the cluster), and if you save this set of data as a file, then it would exist in only one of the servers, and if a server different from the one the file is saved in handles a request, then the file won't be found.


Exactly!

Roberto Perillo wrote:Well, what you can do is, since this set of data is handled on regular intervals, you could create a Quartz job and configure it to work in a clustered environment


The file contents are going to be a JSON format text which I would like to serve as is. Can Quartz be configured to fire the job to write a file instead of a database?
 
Roberto Perillo
Bartender
Posts: 2292
3
Eclipse IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Dinkar Chaturvedi wrote:The file contents are going to be a JSON format text which I would like to serve as is. Can Quartz be configured to fire the job to write a file instead of a database?



Hum... you mean, if it is possible to get the content generated externally and save it as a file rather than saving it in a database? It's just that, if you do this, then the file will only exist in the server where the job was triggered, and if another server handles a request for the file, it won't exist there, so your problem will still be the same.

The idea of saving the content in a database is that you will be able to retrieve it from any server. You just have to save it as a byte array in the database (in a column of type BLOB). Then, you retrieve it as a byte array and you will be able to write it to any OutputStream. So, with it, you will be able to write it to a file, write it to the console (System.out), write it to a HttpServletResponse.getOuputStream() object, etc.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic