I am working on a web application which is deployed in Tomcat. We are using Spring, Hibernate, GWT at the client side).
One of the functionality of this application is to send alerts ( emails ) to Users when any entity is created, updated or deleted. ( Alerts can be added by Users on the fly, so there is some processing involved - to decide which users should be notified by email ).
Alert mechanism ideally should be asynchronous and it should be affect the performance of CRUD operation.
First thing which came in my mind is to create a thread and have a blocking queue. Thread keeps polling blocking queue to see if it has got any events. But creating thread in web application is something which is discouraged by many Containers.
Can someone advice/ suggest - is this the correct way of doing it ? or There are better ways of doing the same thing .
Any pointers would be highly appreciated.
Thanks in advance,
Sachin
The restriction on creating threads in a container was really just a suggestion to keep inexperienced developers from shooting themselves in the foot. No container actually prohibits you from doing this. With java.util.concurrent classes, creating threads should be less error prone and I wouldn't worry about this restriction too much.
If your requirements are simple, it's easy enough to just create a single thread / runnable in a ServletContextListener. Create and start the thread in contextInitialized() and shut it down in contextDestroyed(). . Use a ScheduledExecutorService created by Executors.newSingleThreadScheduledExecutor(). The Runnable you pass to the Executor would read from a BlockingQueue.
If your requirements change and you need something more complicated, you probably want to looks at JMS / MDBs or a scheduler like Quartz.
You could use a scheduler to run jobs regularly or use the Spring equivalent of Message Driven Beans (some documentation on JMS and Spring) which are executed by the container which does the queue polling for you.
You can try using Spring 3.x asynchronous method invocation. Caller method will return immediately and the actual execution happens asynchronously
applicationContext:
<task:annotation-driven executor="asyncExecutor" mode="aspectj"/>
<task:executor id="asyncExecutor" pool-size="${executor.poolSize}"/>
On your bean:
#Async
public void sendEmail(...) {
// ...
}
please refer to Spring documentation for further details: Spring 3.x Task Execution and Scheduling
There are ways of doing it, the simplest (besides simply creating an unmanaged thread) is to use the commonj WorkManager. Certainly you can go the simple thread route, but it does have shortcomings in the environment you are operating in (as described in the link).
Related
I have a spring mvc implementation with hibernate. We have quartz to take care of scheduled jobs. I have been reading up on threads and Spring's recommendation that all spawning of threads in Spring should be done through a managed bean (TaskExecutor?) i.e spawning of thread should be spring managed rather than developer just spawning a random thread calling new Thread(new Runnable{})
My question is: I have a product where users log in to my system, Every request from the browser is a thread, Tomcat takes care of servicing them etc. if asynchronous work is required we spawn threads while the request can return to the user. KISS, isn't it?
what am I missing with the lack of TaskExecutor implementation in my system? If we never thought of implementing it yet, how would having a spring managed TaskExecutor change the game for us? I am unable to find some article that clearly explains why I need my own implementation of TaskExecutor/dangers of spawning your own threads/performance gains/Design gains of letting Spring manage it etc.
Any resource shared or explanation will be appreciated. Grateful to people who will share their experience
I have one java program which process some business data and have to return response. But as part of backing up those data, I want to implement another method where it delivers that data to that method and asynchonously back up so that client does not have to wait for that backup operation to finish. Can someone suggest the better way to implement this? We are hitting more then 100 req/s and all the data processed needs to be backed up too.
I guess you can make use of java.util.concurrent.ExecutorService
You should make use of java.util.concurrent.ExecutorService to implement such functionality. It will give you much finer control over thread pool size and other aspects like timeout and wait.
Spring 3.0 #Async allows you to run a task asynchronously. Follow this link to learn more about Spring Asynch task usage:
http://java-success.blogspot.in/2013/05/asynchronous-processiong-with-spring.html
It sounds like you need to seriously consider using some message queue technology like JMS (Hornet) or AMQP (RabbitMQ).
#Async is nice for small chores but it does not scale and neither does a plain ExecutorService. Not to mention your problem even sounds more like a message problem and not a simple task execution (backup and client notification). MQ theory/practice/implementation requires some reading so I recommend you look at Spring AMQP/JMS and general message queue documentation.
In terms of notifying the client take a look at the new spring mvc DeferredResult.
Hello everyone I am new to the forum and I just had a question about working with Spring's commonj WorkManagerTaskExecutor. I have been on a bunch of forums looking for better information on the subject but I haven't seen anything detailed on the subject. So here is my situation.
My application uses multiple threads which were being handled by ThreadPoolTaskExecutor which a friend told me he thought would not be the correct choice since we are using websphere 7.0 application server. I had everything working correctly and with some minor tweaking was able to replace the ThreadPoolTaskExecutor with a WorkManagerTaskExecutor. When I run the application the threads fire off via the default work manager on the websphere server. The problem that seems to be happening though is that even though I am using the workManagerTaskExecutor.waitForAll(collection,timeout); It never actually waits for the threads to complete. I know that it is working that is the threads are executing their respective methods because if you issue a lengthy for loop after all of this the data is there where as if you do not the data is not there. I was wondering the following two things.
Is the WorkManagerTaskExecutor the way to go? Or would using a ThreadPoolTaskExecutor be sufficient for handling multiple threads on a enterprise web application?
If the WorkManagerTaskExecutor is the way to go? Any ideas as to why the waitForAll method is completing as if the methods are done? When clearly they are not? After the page loads I can see in the logging that the methods are still running and eventually completeing.
Any help would be much appreciated. If I left anything out I will gladly try and give more information about the issue as I truly appreciate any help that might be given.
Thanks in Advance,
Bill
You should implement your concurrent class by extending the java.util.concurrent.Executor interface built into JavaSE, and then using the Spring IoC container, you can inject in an implementation class of WorkManagerTaskExecutor when running under Websphere.
This will give you flexibility if you ever want to run on another Java app server, and even works if you run outside a container directly on the JVM, since you could inject in a ThreadPoolTaskExecutor and not have to change any code.
You should avoid coding against the CommonJ WorkManager API (JSR 237) directly, such as using the waitForAll method, since it only works on IBM Websphere and Oracle WebLogic.
The final winning combination to this problem for me ended up being:
List<Callable<?>> callables = new ArrayList<Callable<?>>();
List<Future<?>> futures = new ArrayList<Future<?>>();
for (int i = 0; i<callers.length;i++){
callables.add(new MainTaskExecutor(this,entity,callers[i]));
}
for (Callable c:callables){
futures.add(workTaskExecutor.submit(c));
}
for (Future<?> f:futures){
do{}while(!f.isDone());
}
Probably a repeat! I am using Tomcat as my server and want to know what is best way to spawn threads in the servlet with deterministic outcomes. I am running some long running updates from a servlet action and would like for the request to complete and the updates to happen in the background. Instead of adding a messaging middleware like RabbitMQ, I thought I could spawn a thread that could run in the background and finish in its own time. I read in other SO threads that the server terminates threads spawned by the server in order for it to manage resources well.
Is there a recommended way of spawning threads, background jobs when using Tomcat. I also use Spring MVC for the application.
In a barebones servletcontainer like Tomcat or Jetty, your safest bet is using an applicaton wide thread pool with a max amount of threads, so that the tasks will be queued whenever necessary. The ExecutorService is very helpful in this.
Upon application startup or servlet initialization use the Executors class to create one:
executor = Executors.newFixedThreadPool(10); // Max 10 threads.
Then during servlet's service (you could ignore the result for the case that you aren't interested, or store it in the session for later access):
Future<ReturnType> result = executor.submit(new YourTask(yourData));
Where YourTask must implement Runnable or Callable and can look something like this, whereby yourData is just your data, e.g. populated with request parameter values (just keep in mind that you should absolutely not pass Servlet API artifacts such as HttpServletRequest or HttpServletResponse along!):
public class YourTask implements Runnable {
private YourData yourData;
public YourTask(YourData yourData) {
this.yourData = yourData;
}
#Override
public void run() {
// Do your task here based on your data.
}
}
Finally, during application's shutdown or servlet's destroy you need to explicitly shutdown it, else the threads may run forever and prevent the server from properly shutting down.
executor.shutdownNow(); // Returns list of undone tasks, for the case that.
In case you're actually using a normal JEE server such as WildFly, Payara, TomEE, etc, where EJB is normally available, then you can simply put #Asynchronous annotation on an EJB method which you invoke from the servlet. You can optionally let it return a Future<T> with AsyncResult<T> as concrete value.
#Asynchronous
public Future<ReturnType> submit() {
// ... Do your job here.
return new AsyncResult<ReturnType>(result);
}
see also:
Using special auto start servlet to initialize on startup and share application data
How to run a background task in a servlet based web application?
Is it safe to manually start a new thread in Java EE?
You could maybe use a CommonJ WorkManager (JSR 237) implementation like Foo-CommonJ:
CommonJ − JSR 237 Timer & WorkManager
Foo-CommonJ is a JSR 237 Timer and
WorkManager implementation. It is
designed to be used in containers that
do not come with their own
implementation – mainly plain servlet
containers like Tomcat. It can also be
used in fully blown Java EE applications
servers that do not have a WorkManager
API or have a non-standard API like
JBoss.
Why using WorkManagers?
The common use case is that a Servlet
or JSP needs to aggregate data from
multiple sources and display them in
one page. Doing your own threading a
managed environement like a J2EE
container is inappropriate and should
never be done in application level
code. In this case the WorkManager API
can be used to retrieve the data in
parallel.
Install/Deploy CommonJ
The deployment of JNDI resources
vendor dependant. This implementation
comes with a Factory class that
implements the
javax.naming.spi.ObjectFactory
interface with makes it easily
deployable in the most popular
containers. It is also available as a
JBoss service. more...
Update: Just to clarify, here is what the Concurrency Utilities for Java EE Preview (looks like this is the successor of JSR-236 & JSR-237) writes about unmanaged threads:
2.1 Container-Managed vs. Unmanaged Threads
Java EE application servers
require resource management in order
to centralize administration and
protect application components from
consuming unneeded resources. This can
be achieved through the pooling of
resources and managing a resource’s
lifecycle. Using Java SE concurrency
utilities such as the
java.util.concurrency API,
java.lang.Thread and
java.util.Timer in a server
application component such as a
servlet or EJB are problematic since
the container and server have no
knowledge of these resources.
By extending the
java.util.concurrent API,
application servers and Java EE
containers can become aware of the
resources that are used and provide
the proper execution context for the
asynchronous operations to run with.
This is largely achieved by providing
managed versions of the predominant
java.util.concurrent.ExecutorService
interfaces.
So nothing new IMO, the "old" problem is the same, unmanaged thread are still unmanaged threads:
They are unknown to the application server and do not have access to Java EE contextual information.
They can use resources on the back of the application server, and without any administration ability to control their number and resource usage, this can affect the application server's ability to recover resources from failure or to shutdown gracefully.
References
Concurrency Utilities for Java EE interest site
Concurrency Utilities for Java EE Preview (PDF)
I know it is an old question, but people keep asking it, trying to do this kind of thing (explicitly spawning threads while processing a servlet request) all the time... It is a very flawed approach - for more than one reason... Simply stating that Java EE containers frown upon such practice is not enough, although generally true...
Most importantly, one can never predict how many concurrent requests the servlet will be receiving at any given time. A web application, a servlet, by definition, is meant to be capable of processing multiple requests on the given endpoint at a time. If you are programming you request processing logic to explicitly launch a certain number of concurrent threads, you are risking to face an all but inevitable situation of running out of available threads and choking your application. Your task executor is always configured to work with a thread pool that is limited to a finite reasonable size. Most often, it is not larger than 10-20 (you don't want too many threads executing your logic - depending on the nature of the task, resources they compete for, the number of processors on your server, etc.) Let's say, your request handler (e.g. MVC controller method) invokes one or more #Async-annotated methods (in which case Spring abstracts the task executor and makes things easy for you) or uses the task executor explicitly. As your code executes it starts grabbing the available threads from the pool. That's fine if you are always processing one request at a time with no immediate follow-up requests. (In that case, you are probably trying to use the wrong technology to solve your problem.) However, if it is a web application that is exposed to arbitrary (or even known) clients who may be hammering the endpoint with requests, you will quickly deplete the thread pool, and the requests will start piling up, waiting for threads to be available. For that reason alone, you should realize that you may be on a wrong path - if you are considering such design.
A better solution may be to stage the data to be processed asynchronously (that could be a queue, or any other type of a temporary/staging data store) and return the response. Have an external, independent application or even multiple instances of it (deployed outside your web container) poll the staging endpoint(s) and process the data in the background, possibly using a finite number of concurrent threads. Not only such solution will give you the advantage of asynchronous/concurrent processing, but will also scale because you will be able to run as many instances of such poller as you need, and they can be distributed, pointing to the staging endpoint.
HTH
Spring supports asynchronous task (in your case long running) through spring-scheduling. Instead of using Java threads direct I suggest to use it with Quartz.
Recourses:
Spring reference: Chapter 23
Strictly speaking, you're not allowed to spawn threads according to the Java EE spec. I would also consider the possibility of a denial of service attack (deliberate or otherwise) if multiple requests come in at once.
A middleware solution would definitely be more robust and standards-compliant.
I'm refactoring a big piece of code atm where a long taking operation is executed in a servlet. Now sometimes I don't get a response after the operation has finished. (It has finished because it is printed into the logs)
What I wish to achieve would some "fire and forget" behavior by the servlet. I would pass my params to the action and the servlet would immediately return a status (something like: the operation has started, check your logs for further info)
Is this possible with servlet 2.5 spec? I think I could get such a behavior with JMS maybe any other solutions out there?
Asynchronous Servlets would serve your purpose but it is available only as part of Servlet 3.0 spec. You could read more about Async Servlets here
There are a couple of ways of doing this. Asynchronous servlets are part of the Servlet api 3.0. I've known a lot of people that would fire off a separate thread, usually a daemon thread. The drawback to spawning your own threads is that you lose any "container" advantages you might have, since the thread runs more or less independently within the JVM. What I've used most often is a message driven bean fed by JMS, it runs in the EJB container with all those attendant advantages and disadvantages. YMMV.
Instead of starting (and managing) your own treads you should consider using Java's ExecutorService abstraction (Executor/Future framework). If you're using Spring you can define Executor as just another bean in Spring's context and your servlet could just call it passing your task as instance of Runnable. There should be plenty of samples if you Google it.
If upgrading to Servlet 3.0 (part of Java EE 6, with as far Glassfish v3 as the only implementation; Tomcat 7 is still on its way and expected about next month) is not an option, then an alternative is Comet. Almost all Java servletcontainers has facilities for this. It's unclear which one you're using, so here's a Tomcat 6 targeted document: What is the Apache Tomcat Comet API.
Alternatively, you can fire a separate Thread in a servlet so that the servlet method can directly return. You can eventually store the Thread in the session so that the status can be retained in the subsequent requests. If necessary let it implement HttpSessionBindingListener as well so that you can interrupt it whenever the session expires.