Although this question concerns EhCache primarily, it really applies to caching frameworks (and plain old caching) in general.
EhCache allows you to create a singleton CacheManager for managing all of the Caches in your application, or it allows you to create "instance" CacheManager, which means exactly what it sounds like: multiple managers in use throughout your application.
What are the pros/cons of each? At first glimpse it seems like it would be cleaner to just have a singleton manager.
The only conceivable reason I can think of for why one would want multiple instance managers is the fact that all caches living inside a CacheManager must share the same configurations: same size, usage strategies, capacities, etc. So if you wanted multiple caches, each configured differently, the singleton CacheManager would not be able to provided the different cache configurations to each cache.
Is this the only criteria for determining singleton vs instance managers? If not, what are some other considerations? Is there a noticeable performance cost associated with either? Thanks in advance!
What about automated testing? Maybe it can be useful for unit testing if you can enable/disable/configure caching on a smaller level? Just a thought.
Related
I understand how ApplicationScoped and CDI javax.inject.Singleton work, and I understand the difference between these two scopes. My app has a lot of beans that don't need serialization, proxies, or decorations, so I am considering switching those from ApplicationScoped (which works) to javax.inject.Singleton to improve performance by avoiding proxies.
My question is: Should I in fact make such a change?
Of course you can do that refactoring on scope annotation, but you will need to take care of serialization on beans calling those singleton managed beans. See http://docs.jboss.org/weld/reference/latest-2.2/en-US/html_single/#_the_singleton_pseudo_scope
I would investigate first how much performance gaining I'll get from this move and if it really worth the time I'll need to invest on it. Usually performance bottleneck comes from database query/indexing performance, I/O, network, thread-locks, inefficient algorithms (and more) before a Java proxy overhead, so I would stick to standard #ApplicationScoped.
See:
http://ordinaryjava.blogspot.com/2008/08/benchmarking-cost-of-dynamic-proxies.html
https://spring.io/blog/2007/07/19/debunking-myths-proxies-impact-performance/
In an technical discussion, I had this question of how to maintain a Single instance across nodes,
then I answered the below approaches
1) DB based solution
2) Distributed Cache
3) Sharding
4)Maintain the Singleton single Instance in load balancer
Interviewer was expecting something more, since he replied
DB based and Cache will work and sharding will not work and no comments on load balancer approach, then further he added that let us assume that DB and Cache approach are not allowed in your application, give me another option
I was stuck at this point.
Then I googled and found the following
How to create singleton java class for multiple jvm support?
Singleton in Cluster environment
https://javaarchitectforum.com/2013/02/19/singleton-design-pattern-with-example/
Also found some support from the application servers
http://www.onjava.com/pub/a/onjava/2003/08/20/jboss_clustering.html
http://docs.oracle.com/cd/E12840_01/wls/docs103/cluster/service_migration.html#wp1051458
http://docs.oracle.com/cd/E24152_01/Platform.10-1/ATGPlatformProgGuide/html/s1005runningthesameschedulableservice01.html
Kindly help me with your thoughts which would be the best approach to implement single instance(singleton) across nodes
All options will fail if you do not know what you are doing. I'd like to call the singleton an anti-pattern rather than a design pattern, because the way it is often used, is usually recipe for disaster.
Now, lets get to the answer. You should ask the interviewer: why is a singleton really needed? What state really needs to be stored at one specific location? Is this state mutable? What is the concurrency strategy? Will there be mostly writes? Or mostly reads? Does all access have to be synchronised?
You are thinking in the wrong direction because you think a solution to this problem actually exists. Well, you will find a way, but it will be a compromise between concurrent performance and absolute synchronous access.
Now, let us quickly walk through the options you have provided yourself:
1) DB based solution
This could work, but you have to ensure your locking strategy is supported by the database, and that you use it wisely.
2) Distributed Cache
This is essentially the same as a DB based solution. You could even write your own microservice to do this job. You should realise that a distributed cache is exactly the same as a database, only one that is optimised for concurrent reads on the same data (that has an expiration strategy). Keep in mind that if not well-explained, a caching solution may sound as if you are not aware that a cache usually invalidates/expires, and has a just-in-time generation fallback. This may sound as if you did not understood the problem of wanting to have a singleton instance "alive" at all time.
3) Sharding
Sharding is a technique you can you use if your singleton is too big to fit into one database based solution mentioned before. I highly doubt that your singleton will get so big.
4) Maintain the Singleton single Instance in load balancer
This makes your load balancer schizophrenic and is a bad idea. Load balancers are really simple components, and should stay that way.
It is possible that you might benefit from http://sw1nn.com/blog/2012/04/11/clojure-stm-what-why-how/ STM, which is a technique in Clojure and thus should work on the JVM. I furthermore agree with anything Jan-Willem Gmelig Meyling has said above. This is an anti pattern you should avoid. My STM suggestion is specifically in a language that does not allow you to mutate state, which is a predicate for such things not to become dangerous (it would prevent the schizofrenic issue JWGM talks about.)
I am learning Spring, and I know that bean will be by default singleton in one application context.But what if we deploy the applications in distributed system? What will be the practical way to achieve singleton since every time a request comes in, it may be routed to a different machines with a different application context?
I have read Singleton in Cluster environment but the answer is about cache.
I guess we can do something like putting the singleton into a central place(like memcached) , and every time we need this bean and serialize and deserialize it from IO, Does this work? But, in my opinion, this will be cost a lot since some object is very "expensive" to transfer.
Thank you!
Either your singleton is stateless: then you just re-create the same thing in each node, with no communication between nodes needed;
or your singleton is stateful: then you need to distribute its state. This is where memcached or any other of a slew of available distributed caches must be applied. You will still be re-creating the singleton itself in each node independently, but you'll make its internal state reside in the distributed cache.
You can set up your web/app server to make sessions "sticky": once a request is routed to a particular server, all requests in that session go to the same server.
The larger question is: why are you designing and implementing a distributed system this way? A singleton for all can't scale. There's no sense in clustering anything if you insist on this path.
A better solution would be stateless, immutable, functional. Create stateless REST services that model your system.
It depends, if you are going to use the Singleton instance just like a service and you won't store any global variable in it, you won't need to make it distributed.
In some cases that you require the distribution and, therefore, use a cache solution; you may try to optimize your implementation to store minimum data to make it distibuted less costly
When should an object (i.e. an application-wide properties file) be kept in the session, as opposed to creating a singleton to keep it? When should each of these approaches be used?
Note: I am working on a clustered environment, if that makes any difference.
If it's supposed to be application-wide, then you should not store it in the session scope, but in the application scope. With storing in the session scope, you're unnecessarily duplicating the same data for every visitor. A singleton is also not needed at all, just instantiate once during server startup with help of a ServletContextListener and store it in the application scope using ServletContext#setAttribute().
+1 to BalusC, but I suspect that was just a typo on your part.
As for singletons, it depends on what you mean by singleton. If you have an EJB annotated with #Singleton, then that's fine (other dependency-injection providers may also support this pattern).
If you're talking about the standard singleton pattern, where you keep the instance in a static variable, then that's a bad idea. You should generally avoid static variables in Java EE or servlet containers, because the class loading can be a bit tricky - you may wind up with multiple copies when you don't expect it, or you may be sharing a single copy between different applications, or you may be keeping stuff in memory when you redeploy your application. You can make an exception in cases where the variable isn't exposed outside the class, and you don't really care how many copies of it you have (for example, logger objects).
Note: I am working on a clustered environment, if that makes any difference.
I don't disagree with what Mike and BalusC have already written, but I feel you're entering territory where implementation details matter. What you do and how you do it will depend on the back-end services, what sort of clustering, and what the application requirements are. I think the question is too broad to give specific answers.
Furthermore...
All Java EE profiles share a set of common features, such as naming and resource injection, packaging rules, security requirements, etc. This guarantees a degree of uniformity across all products, and indirectly applications, that fall under the “Java EE platform” umbrella. This also ensures that developers who are familiar with a certain profile, or with the full platform, can move easily to other profiles, avoiding excessive compartmentalization of skills and experience.
Java EE specifications define a certain level of compliance but the goal isn't to make every infrastructure heterogeneous. This sort of thing adds complexity to an already nebulous problem domain.
We have a project with a pretty considerable number of EJB 2 stateless session beans which were created quite a long time ago. These are not the first-line beans which are accessed from our client via RMI, rather they are used by that code to perform specific functions. However, I've come to believe that there's nothing to be gained by having them as session beans at all.
They do not need to be accessed via
RMI.
They do not retain any state,
they are just code that was factored
out of the first set of beans to
reduce their complexity.
They don't
have multiple different
implementations which we are swapping
out, each one has been as it was for
years (barring bug fixes and feature
additions).
None of them alter the
transaction that comes into them from the bean calling them
(that is they don't require a new
transaction, not participate in the
existing one, or otherwise change
things).
Why should these not all just be classes with a couple of static functions and no EJB trappings at all?
The only reason I can see is for clustering purposes (if you are doing clustering). That is the hand off to those beans could be on another VM on another machine if clustering is being done right to spread the load around.
That is likely not the case, and the movement to EJB's was just over-engineering. I'm suffering with that too.
Even transactions aren't really enough to justify it, you can have a single EJB that handles the transactions and call the different code through it via a Command type pattern.
There seems to be no reason why they shouldn't just be simple POJO's rather than stateless session beans. I think this is the conclusion that people came to after using EJB 1.x in this manner as well.
It's also the reason why frameworks such as Spring exist as an alternative to EJB's.
I'd say change them over to be just standard POJO's, but make sure you have a safety net of unit and functional tests (which might be a little bit harder with EJB's) to help you.