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.
Related
I want to build a standalone global audit trail application which can trace all the audit(events) logs sent to it from different applications through webservice call or any other channel.
The issue i see here is i don't want to hamper the performance of the calling application to wait for the response as ideally not expecting any response back to calling app.
If i go with webservice approach then the caller application will wait for the response (both case synchronized /asynchronized call) are there any other best approach for this solution.
There will be n no of application which will be sending their audit logger to this application so need idea which i can scale up parallel if required.
Thanks for going through my request!!!
We would be using Kafka for this approach.
Hopefully it is having good performance and scalable.
Best Architecture for implementing a WebService that takes requests from one side, save and enhance that and then call another service with new parameters.
is there any special Design Pattern for this?
There's not a lot to go on, but from what you've said it sounds like a job for "pipes and filters"!
To get a more precise answer, you might want to ask yourself some more detailed questions:
If you need to do any validation or transformation of the incoming message? Will you want to handle all requests the same way, or are there different types? Are the external services likely to change, and if so, will they do this frequently? What do you want to do if the final web service call fails (should you rollback the database record?)? How do you want to report failures/responses - do you need to report these back? Do you need a mechanism to track the progress of a particular request?
Since you are looking for a design pattern, I think you might want to compare the pros and cons of using microservices orchestration vs choreography in the context of your project.
If you do not need an immediate response to the calling system I would suggest to you to use event-driven approach if that's feasible. So instead of REST services, you will have a message broker and your services will be subscribed for certain events. This will hide your consumers behind the message broker which will make your system less coupled.
This can be implemented via Spring Cloud Stream, where you will have a Sink (microservice producing events, transformer - microservice that makes intermediate transformations possible and a source - microservice that receives a final result for further processing).
Another possible case could be Camel. It has basically all the integration patterns built in, so it should not be a problem to implement the solution either based on REST APIs or events.
Requirement: Log events like Page Views and form Submits. Each page has ~1 second SLA. The application can have 100's of concurrent users at a time.
Log events are stored into the Database.
Solution: My initial thought was to use an async logging approach where the control returns back to the application and the logging happens in a different thread (via Spring's Thread pool task executor).
However someone suggested using JMS would be a more robust approach. Is the added work(Setting-up queue(s), writing to the queue(s), reading from the queue(s)) required when using this approach worthwhile?
What are some of the best practices / things to look out for (in a production environment) when implementing something like this?
Both approaches are valid, but one is vulnerable if you app unexpectedly stops. In your first scenario, events yet to be written to the database will be lost. Using a persistent JMS queue will mean that those events will be read from the queue and persisted to the database upon restart.
Of course, if your DB writes are so much slower than placing a message of similar size on to a JMS queue, you may be solving the wrong problem?
Using JMS for logging is a complete mismatch. JMS is a Java Abstraction for a Middleware Tool like MQ Series. That is complete overkill, and will let you go through a setup and configuration hell. JMS also lets you place messages in a transactional context, so you already get quickly the idea that JMS might be not much better than Database writes as #rjsang suggested.
This is not that JMS is not a nice technolgy. It is a good technology where it is applied properly.
For Assynchronous logging, you better just depend on a Logging API that directly supports it like Log4j2. In your case, you might be looking to configure a AsyncAppender with a JDBCAppender. Log4j2 has many more appenders as additional options, including one for JMS. However, by at least using a Logging abstraction, you make that all configurable and will make it possible to change your mind at a later time.
In the future we might have something similar to Asynchronous CDI Events, which should work similar to JMS, but would be much more lightweight. Maybe you can get something similar to work by combining CDI Events with EJB Asynchronous Methods. As long as you don't use EJB's with a remote interface, it should also be pretty lightweight.
You could give it a try using fully async and external tooling if you want to. If you have to stick to your SLA at any price and resilience is important for you, you could try using either logstash or process your logs offline. With doing so, you decouple your application from the database and you are no longer depending on the database performance. If the database is slow and you're using async loggers, queues might run full.
With logstash using GELF the whole log processing is handled within a different (or even remote) JVM. Offline processing (e.g. you write CSV logs) allows you to load the log data afterwards into the database.
In my current work, for a use case we are making several remote service calls (SOAP over HTTP) in sequence. These are independent calls and I have to collate the data from each call and finally prepare my response. I want to parallelize these calls.
Sounds like you should use an ExecutorService.
Make a class that performs your query and implements Runnable. You can then submit instances of this class to an Executor and it will look after running this in multiple threads (pooling etc. - all configurable). You get given back a Future object for each submission and you simply call get() on that to get your result.
The framework means you don't have to worry about instantiating threads, setting up pooling, determining what's run etc.
Here's the tutorial.
Spawning threads in Java EE is a no-go we're told. However, the OP doesn't say whether Java EE or Java SE is used.
For Java EE the WorkManager API may be useful.
Other than that yes, ExecutorService or Spring TaskScheduler (rather unlikely if I got the problem right).
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).