How is that instance pooling with EJBs can improve performance? - performance

How is that instance pooling with EJBs can improve performance? Wouldn't you be able to accomplish the same performance just with threads like a java servlet?
Or perhaps instance pooling with EJBs happens for another reason?

Instance pooling not only helps because you can re-use objects (and avoid costly object creation), but also allows the app. server to manage the load correctly. It's app. server specific, but you can normally specify max-pool-size, min-pool-size, pool-resize and the timeout.
When the pool has reached its max-pool-size capacity, requests are served using the existing instances, and will time out if no instance is available within the expected time frame. That may degrade the quality of service of the application, but at least it doesn't blow the app. server itself. That's the same as with a web server.
A few notes about thread-safety:
Sect. 4.3.13 "Serializing Session Bean Methods"
The container serializes calls to each session bean instance. Most containers will support many
instances of a session bean executing concurrently; however, each instance sees only a serialized
sequence of method calls. Therefore, a session bean does not have to be coded as reentrant.
As per the EJB spec, all requests to a specific instance of a bean are synchronized by the app. server. This is, for instance, to allow a stateless session bean (SLSB) to store a database connection in one of its fields. The fields of an SLSB should be transient, though. (The bean instance can be destroyed/re-created any time.) With the synchronization, the app. server ensures the SLSB is thread-safe. Without the synchronization by the app. server, the developer should ensure that the SLSB is thread-safe, that is, it should have no fields.
Note: It's rare to have fields in an SLSB. Most SLSB are thread-safe by nature. I would not recommend storing the connection in field for instance. Better obtain one in the method, and release it in the method asap.

I think instance pooling is used when the beans are expensive to construct. By letting the next request reuse the same bean you don't have to construct another instance.
If the bean itself is cheap to construct and the cost is in the work that it's doing, then instance pooling isn't worth the hassle.

I think the advantages would be similar to those of connection pooling. Having instances ready in a pool avoids the overhead of creating a new instance every time the EJB is requested.
Another advantage, depending on how you look at it, is that by using a maximum pool size you can limit the damage a runaway application can do by forcing it to wait for an instance to become available. This can help prevent poorly written apps from monopolizing server resources.

AFAIK the fundamental reason is the different threading model compared to the servlet's one. In case of servlet, there is only one instance and many threads can operate on this intstance at the same time. It is the developers responsibility to ensure proper synchronisation.
In contrast to this, ejb container allows only one thread at the same time to operate on the bean instance (including necessary synchronisation at the background). Thanks to this, developer does not have to care about synchronisation, and what's more using synchronisation in the bean's code is forbidden by the spec (in fact you can do it, but you have to consider the performance consequences).
So to enable concurrent processing, you need to pool multiple bean instances so that multiple threads can access them simultaneously. The size of the pool can be tuned depending on what kind of work is done inside the bean. The basic rule is:if the task is I/O bound, you need big pool so that the cpu time is not wasted when waiting for i/o response. If the task is cpu bound, the pool should be as big as much processors/cores the machine does have. But the tuning should be based on measuring.
One more note on the servlets: you can enforce the same behaviour as ejb when using SingleThreadModel interface. But in fact this is not much used I guess.

Related

Spring Boot Actuator to run in separate thread pool

Is it possible to handle actuator requests like health within a separate thread pool from the "main" application?
Why am I asking?
I've got an application that might sometimes use up all available threads, and the Kubernetes health check is failing due to the unavailability of a thread to compute the health endpoint request.
I want to make sure that every health request is processed no matter how much load the application is under.
I was thinking about maybe defining a separate thread pool for the actuators to operate with, but I am not sure how to do this.
We had a similar problem with some of our apps when running in Kubernetes. We looked at different ways of creating multiple tomcat connectors and changing the spring management port to get the desired affect, but never quite got it.
In the end, we attacked the root of the problem, which was resource starvation within the pod. We found that the apps experiencing the health check timeouts had lots of extra threads for various 3rd party thread pools. In some cases we had apps with close to 500 threads, so even under what we considered moderate load, the tomcat pools would get starved and couldn't handle new requests.
FWIW, the biggest culprit we found was the effect of CPU request on a pod and the JDK. When we didn't set any request, the JDK would see every CPU on the node when it queried for numbers of processors. We found there are lots of places in the Java ecosystem where number of processors is used to initialize different thread pools.
In our case, each node had 36 processors, and we found around 10-12 thread pools using this number to determine size...not hard to see to how an app could quickly grow to 500 threads.
I believe that switching to the nonblocking stack (Webflux) could solve your issue, should this be an option for you. If you rely on some blocking API (e.g. JDBC) you can publish it on a separate thread pool (e.g. Schedulers.elastic()). Thus, the HTTP request threads should always be available for processing the incoming trafic (including health check) and the long-running, blocking operations would be processed in a dedicated thread pool. I believe that similar effect should be possible using the asynchronous servlets API or anything that builds on top of it.
If you are using Spring Boot >= 2.2, you can use the separate library spring-boot-async-health-indicator to run your healthchecks on a separate thread pool.
Simply annotate your HealthIndicator with #AsyncHealth:
#AsyncHealth
#Component
public class AsynchronousHealthCheck implements HealthIndicator {
#Override
public Health health() { //will be executed on a separate thread pool
actualCheck();
return Health.up().build();
}
}
Disclaimer: I created this library for this exact purpose

Recover session EJB

I was checking EJB stateful beans, the typical example for using this bean is in a shopping cart.
So in the example what is done is check in HttpSession if the EJB exists, if not, one EJB instance is called and then upload to session using the HttpSessionId as identifier.
So, what is the advantage of using a stateful EJB when I could use a simple POJO to do exactly the same?
I guess the typical answer is that even if the HttpSession goes down the EJB still lives in the server container. If this is true, how can I recover that EJB from the EJB pool? given I don't have the HttpSessionID anymore.
Is there another approach to recover EJB's that are living in a container?
The shopping cart of a Stateful EJB hosted within an http session is in my opinion the typical example of something that shouldn't be done for a very simple reason: a shop online purpose is to increase traffic and number of (paying) users. A Stateful bean on the opposite is not recommended with this kind of web site, it doesn't scale.
Stateful Bean are something that should belong to the realm of desktop applications i.e. Swing, JavaFX etc... it has little to do with an www shop online.
Of course keeping things in a session is much lighter than having a Stateful bean holding data.
I cannot think of any trick to recover a Stateful EJB once you loose its reference.
Also, what do you mean with "if the session goes down" ? If you mean because of a server crash, keep in mind that if the EJB resides in the same server then an EJB (Stateless, Stateful, Singleton, etc...) cannot survive a server crash.

Can I use separate non connection pool data source for long running but infrequent tasks?

My application stack consists of Spring MVC, Hibernate and MySQL hosted on Apache tomcat 7.
I have set up Spring to manage transactions and Hibernate session factory is utilizing the tomcat dbcp connection pool backed datasource for getting the connection.
I have a use case in my application in which I have a run a long running task which is initiated through the web UI (say a button click). This task runs for let’s say 10 minutes then my connection pool starts to throw connection closed exceptions. This is obviously because of connection pool setting in which if the connection is not returned to pool after a specific time, it is marked as abandoned and later removed. I could solve this by tinkering with the timeout settings and increasing it to a large enough value. But I may have several other use cases like this and may not currently have idea how long those will run.
So I am thinking of another approach here.
This use case will be initiated not very often, so I may use a separate datasource definition without using connection pool. Of course I can set two transaction managers in Spring with different names “abc” and “xyz” and use the #Transactional(name=”abc”) and #Transactional(name=”xyz)”. Both these transaction managers would use their respective datasources – one with connection pool to support common use cases and one without connection pool to support long running transaction. This way I won’t have to worry about changing the timeout configurations.
Will this be a generally accepted solution or should I take the timeout configuration approach?
Avoiding to use the connection pool will cause problems if you don't have another way to limit the number of connections that your application can initiate. For example (trivial example of cours) if your going to launch your batch process each time a user clicks a button, make sure you limit the times they can do this task.
Another way would be to define a new jdbc resource in your application server (jdbc/batchprocess) and configure in this resource a longer timeout. Then change from one to another using dynamic datasource routing.
You can open Hibernate Sessions, supplying your own Connection:
sessionFactory.withOptions().connection( yourConnection ).openSession();

When multiple access Spring Singleton instance at same time

If you define your service in singleton scope in your spring config, what would happen if more than one user try to access it (ie as dependency injected into your controller) at the same time? Should it cause any conflict? Or the IoC container will hold the later call until the first one finish? If so it should slow down the performance in large applications, which sounds not right to me. Could any one give me a correct answer?
BTW, as I can remember, if it is not a singleton one, IoC container will pool few instances based on the number of requests. Could some one confirm it?
what would happen if more than one user try to access it (ie as dependency injected into your controller) at the same time?
A singleton bean can be accessed many times concurrently. That's why it always has to be thread-safe
Should it cause any conflict?
Only if you fail to make it thread-safe
Or the IoC container will hold the later call until the first one finish?
No, that would be awful
BTW, as I can remember, if it is not a singleton one, IoC container will pool few instances based on the number of requests. Could some one confirm it?
Spring has the following scopes (see Bean Scopes reference):
singleton (only one instance is managed per application)
prototype (a new instance for every injection)
session (one instance per HTTP session, only in Spring MVC)
request (one instance per HTTP request, only in Spring MVC)
global session (one instance per global HTTP session, only in portlet-based Spring MVC)
Also:
As of Spring 3.0, a thread scope is available, but is not registered by default. For more information, see the documentation for SimpleThreadScope.
What you describe is an Object Pool. In Spring that would be implemented as a Prototype-scoped FactoryBean. And internally it would use a library like Apache Commons / Pool.
Singletons are just that - singletons. One instance is managed by the Spring context, and all requests go through that one instance concurrently. It's up to you to make that thread-safe.
If your bean isn't thread-safe, then consider using non-singleton-scoped beans. Spring lets you use request, session and prototype scopes.

EJB stateless session beans and stateful session bean

I have gone through various books on stateful and stateless session bean and how they work. I want to know the real usage of these ejbs and advantages over using plain java classes. Basically when do you go for stateless ejbs and when do you go for stateful ejbs. I want a real time application.
the usage of these type of ejbs are usually in service layer as service classes.
EJB3 stateless and stateful bean are actually POJO (with some annotations) and they don't have any big difference with normal classes.
but in term of usage, they have some abilities that you can't find in normal classes like:
they can be called remotely (e.g. RMI protocol).
they can use application server context resources like DB Connection and Transactions.
stateless or stateful:
- if a task or process can be done in a single step (by a single method call) stateless is the right option
like a authentication process
- if a task needs a series of method calls (more than one) and you need to keep previous results to use them in next call, then go for stateful.
like a shipping process (select items, add/remove and then do the transaction)
http session or stateful?
ejbs can be served in application server and they may have different type of clients like a normal swing application or ..., so you can't relay on http session in these cases.
if your appserver and webserver are different (distributed) its not good idea keep data in http session and pass/getback it to/from app server (network overhead).
Stateless session bean are lightweight: they do not store information about a specific user. They are usually used in a static way. For example a client ask for a product information will communicate with a stateless session bean. ("You want the price of product 'YXZ', here you go!")
Stateful session bean however remember's the client information. They contains data about the user actions. For example, let's say a user go through a shopping cart. The steps will be stored in a stateful session bean (for example, user it at the payment step).
You really need both type of session bean in any website. Unless you web site is so basic that anything can be done with stateless session bean (a read-only web site really).
Any web site that track a user through cookies, will need a stateful session bean. Be aware however that you can decide to put very little session information in a session bean and store that information in a database. But you still need some session management.
Developers prefer to maintain state in web layer in modern enterprise applications. I have never seen a real world web application using Stateful Session Bean. It is a scalability issue also.
An example is a shopping cart stateful session bean that tracks a client's product choices and can execute a sale when requested.

Resources