I'm new to both J2EE and WebLogic. I'd trying to determine the best way to implement a non-distributed cache (one cache per application instance) in a Java Web Services application running on WebLogic 10.3. I need to cache several different POJO's.
There will be multiple WebLogic instances running on each server in a cluster. When reading about ServletContext and InitialContext, I was a bit confused. I believe ServletContext is instance specific, but I can only access it from a Servlet, correct? I will need to access to the cache in separate threads so I'm not sure if this is possible outside of a Servlet.
I was reading a bit about JNDI, but it seems to work at the server or cluster level and not for each WebLogic/application instance.
Can anyone provide me with a suggestion and a code example to initialize, access, and destroy a cache of Java POJO's?
Thanks!
Leon
Here is an example on how to implement a method cache with Spring and EHCache:
http://opensource.atlassian.com/confluence/spring/display/DISC/Caching+the+result+of+methods+using+Spring+and+EHCache
The cache will be local if configured as in the example.
I am using this method in a web service client library to cache the results of a frequently used service that has nearly no update to its data.
Related
I have a spring boot application which uses embedded tomcat. The app is hosted on multiple EC2 instances, which auto scale if required and some of which may be killed/restarted. So, effectively there are 3 instances of the app running , and requests are routed from the load balancer to any of these instances.
I am trying to track user sessions on my app. I started with implementing container level session management using tomcat HttpSession. But it is not able to track sessions across instances. On researching a bit, I got to know that i need something like session replication.
My app is not running a tomcat cluster, it has 3 independent instances of the API which do not talk to each other in anyway. I am not planning to change that and not sure if it is possible with AWS as it does not encourage multicast communication for this purpose.
Also, I do not want to setup/manage a separate DB (like redis with spring session) just for this purpose, because I only need session Ids for logging, and I need to do that in a lightweight manner.
Is there any other way to manage sessions across instances ? or for my purpose, would it be better to just implement some custom code which can check for session id/token passed to and fro between the frontend and backend.
The goal is to externalize the sessions from your application server so that you can autoscale, restart, load balance etc. without worrying about breaking a User's session.
Honestly on AWS using the Spring stack, I would recommend Spring Session + Redis. I've used it countless times and it is very easy to implement. You can leverage AWS Elasticache which manages the Redis cluster for you (like RDS does for relational DBs).
You could write your own custom implementation of Spring Session with a backing store of S3, Dynamo, etc. But is that really any better than the Redis implementation? I'd recommend the path of least resistance.
Currently I am developing module to display list of online user in my application. I am using comet streaming technology. When users log in I put data in map and then sending data in message queue. Now message queue is stored in servlet context.
Now problem I am facing is it is working in local environment but it is not working in production environment because in production environment i have set up tomcat cluster. so data set in servlet context for tomcat 1 is not accessible in tomcat 2.
I have already develop module but not getting any way to solve above issue. I google and found that tomcat doesn't support context replication.
I have one doubt that how many JVM instance will be created in tomcat cluster web application. e.g I have two tomcat cluster.
I would not use servlet context to store data for a cluster. The common pattern is to use a database for data that must be shared across different servers.
For your use case, it is no need persisting the values between different runs, so the database is not necessarily a nice solution, even if it is easy to setup. IMHO what you need it just a shared data cache or better a memory data grid. hazelcast should be easy to use for your requirements. If I correctly understand them, what you need is a distributed map, with a concatenation of node_id, session_id as key (or maybe simply session_id), and a user object as value.
In tomcat7 this requires writing a custom valve to force replication, the same is true in tomcat 6. Refer to Is there a useDirtyFlag option for Tomcat 6 cluster configuration? to see how to do this.
Is it possible to form a cluster in which there are different types of application servers? For instance, 1 JBoss, 1 Glassfish and 1 WebSphere? Lets assume we are using EJB3.0.
Stateless session beans should be relatively easy and simple load balancing among the instances should do the work, but what about SFSBs and session replication? Is it possible to utilize some cache storage like infinispan for it?
I would appreciate any comments or sharing your experience on this topic.
I assume it may be possible if you use some application server agnostic solution like Hazelcast. According to its documentation it's pretty easy to configure web session replication and the only requirements it has are
Target application or web server should support Java 1.5+
Target application or web server should support Servlet 2.4+ spec
Session objects that needs to be clustered have to be Serializable
I've not tried to configure a cluster the way you've described, however I think it may do the trick.
The responce is simply NO. Clusturing is a non standard feature, it is up to the Java EE implementation to provide clustoring keeping standard behaviour (with very litle constrains, as stickiness is expected and session object are expected to be serializable) and no interoperability is forseen.
You can of course made the cluster your self, setting up an external data grid to serve as session store and manage your self the cache, but then you will lose any framework functionality related to the session (you will need to do every thing by your self) and what the point any more to use a full Java EE application server. Yes you will then need to forget about SFSBs.
I am ready curous what issue you want to solve by this type of architecture. I don't see any that can over come the cost of maintining 3 differents apps (app server have slite difference on the dev side) and more importantly 3 differents infrastructure operation stack (on this side there is lot of difference, so you need to multiply the opperation team knowlages).
I am working on a desktop Java application that is supposed to connect to an Oracle database via a proxy which can be a Servlet or an EJB or something else that you can suggest.
My question is that what architecture should be used?
Simple Servlets as proxy between client and database, that connects to the database and sends results back to the client.
An enterprise application with EJBs and remote interfaces to access the database
Any other options that I haven't thought of.
Thanks
Depending on how scalable you want the solution to be, you can make a choice.
EJB (3) can make a good choice but then you need a full blown app server.
You can connect directly using jdbc but that will expose url of db (expose as in every client desktop app will make a connection to the DB. you can not pool, and lose lot of flexibilities). I would not recommend going this path unless your app is really a simple one.
You can create a servlet to act as proxy but its tedious and not as scalable. You will have to write lot of code at both ends
What i would recommend is creating a REST based service that performs desired operations on the DB and consume this in your desktop app.
Start off simple. I would begin with a simple servlet/JDBC-based solution and get the system working end-to-end. From that point, consider:
do you want to make use of conenction pooling (most likely). Consider C3P0 / Apache DBCP
do you want to embrace a framework like Spring ? You can migrate to this gradually, and start with using the servlet MVC capabilities, IoC etc. and use more complex solutions as you require
Do you want to use an ORM ? Do you have complex object graphs that you're persisting/querying, and will an ORM simplify your development ?
If you do decide to take this approach, make sure your architecture is well-layered, so you can swap out (say) raw JDBC in favour of an ORM, and that your development is test-driven, such that you have sufficient test cases to confirm that your solution works whilst you're performing the above migrations.
Note that you may never finalise on a solution. As your requirements change, and your application scales, you'll likely want to swap in/out the technology most suitable for your current requirements. Consequently the architecture of your app is more important than the particular toolset that you choose.
Direct usage of JDBC through some ORM (Hibernate for example) ?
If you're developing a stand-alone application, better keep it simple. In order to use ORM or other frameworks you don't need a J2EE App Server (and all the complexity it takes with it).
If you need to exchange huge amounts of data between the DB and the application, just forget about EJBs, Servlets and Web Services, and just go with Hibernate (or directly with plain old JDBC).
A REST based Web Services solution may be good, as long as you don't have complex data, and high numbers (try to profile how long does it takes to actually unmarshal SOAP messages back and to java objects).
I have had a great deal of success with using Spring-remoting and a servlet based approach. This is a great setup for development as well, since you can easily test your code without deploying to an web container.
You start by defining a service interface to retrieve/store your data (POJO's).
Create the implementation, which can use ORM, straight JDBC or some pooling library (container provided or 3rd party). This is irrelevant to the remote deployment.
Develop your application which uses this service directly (no deployment to a server).
When you are satisfied with everything, wrap your implementation in a war and deploy with the Spring DispatcherServlet. If you use maven, it can be done via the war plugin
Configure the desktop to use the service via Spring remoting.
I have found the ability to easily develop the code by running the service as part of the application to be a huge advantage over developing/debugging something running on a server. I have used this approach both with and without an EJB, although the EJB was still accessed via the servlet in our particular case. Only service to service calls used the EJB directly (also using Spring remoting).
I have been trying to figure out a way to create shared Hibernate session service on Tomcat 6.
basically, I need to have this service: 1. to be re-deployable (which exclude the JNDI service); 2. all the web applications can share the same Hibernate sessions (cache). The Tomcat class loading mechanism seems make sharing the db sessions impossible. I could create a web application with the Spring HttpInvoker which can be used by other web applications. Or I could go with the Spring dm-Server but it seems the complexity of the solution would comparable to that of an application server (JBoss or Glassfish).
What would be the viable solution?
You can use the 2nd level cache
Apart from that - let's assume you want to modularize you application and that's the reason for having two (or more) webapps. But if you want to cache entities from two different webapps, that means the same entity classes exist in both. Which by itself isn't that wrong, but having the same cache for these entities in different contexts seems wrong. Perhaps you don't need two web apps after all?
If you are certain that you need this, you can try implementing a custom Tomcat valve, but I can give you neither recommendations nor details about it.