How to work with asynchronous process from external client? - java

please give me some advice about the best pattern of the task solution. My task is this:
User makes a request to the Camunda processor through own rest
controller
BPMN schema on a backend side consists of a chain of
several asynchronous services
Data will be ready for response to
the User only when one final service on BPMN makes it.
Every chain works not greater than 10-15 secs. And users sessions count is less than 500 an hour.
How to organize the work of the rest controller? Is it acceptable to force controller waiting of result in the same call? Where a bottleneck?

Can you use some server push technology? If it were just a couple of seconds, I'd say go for waiting in the rest controller.
Being 15 seconds and thinking about scalability, I'd say to follow some kind of asynchronous pattern with the client to.
Client sends a request to do something
The controller delegates the work to some external process and returns to the client ok
The process ends and a response is ready.
If the other side is a browser, use some kind of server push technology to notify it. If it is an application use some kind of rpc, polling or any other inter process mechanism to communicate.
Note that depending on the hosting technology, there are different limits on concurrent connections. Check Spring Boot - Limit on number of connections created for tomcat.

Related

SpringBoot Process Runtime Performance issue

I have below code which formats the files from one form to another. Process takes some time so we have wait time of 5 mins in case file takes time to process we destroy it.
The application flow is a http call is made from browser which hits spring boot #Controller class and lastly executes below code which is into #Service class of springboot application.
On load test I see in task manager many formatter.exe present even after springboot application is closed. My question is it correct way to implement in multi user concurrent environment. Also can some help me how can I increase performance executing "exe" when multiple request are made simultaneously
process = Runtime.getRuntime().exec(runtime.exec("c:\\modifier\\formatter.exe"););
if (!process.waitFor(5, TimeUnit.MINUTES)) {
process.destroyForcibly();
process = null;
}
This is not a good practice to wait for http request to complete in 5 minutes as well as waiting for separate process to complete. I assume, your endpoint is synchronized (not async request mapping) since you have not provided mapping details.
If you start a separate process and until you explicitly shutdown or kill it, that certain process will be running (if that process hanged). Refer this question to get an understand how to terminate a process and refer this document as well.
As I said, keeping a http request waiting for 5 minutes is not a good practice. I suggest a different approach for this solution as you use Spring Boot. You can simply make your endpoint asynchronous using #Async annotation for not to wait the request till process to complete. (How To Do #Async in Spring is a good document to see in this case)
Now you can change the controller implementation to use a message broker (RabbitMQ, ActiveMQ, JMS and so forth) queue requests and immediately respond back to the client (Messaging with RabbitMQ). So, your client (browser) see the response immediately even without process is started. You can handle the response at client side as you want then.
Now you can write a different program to dequeue messages from the broker and start the separate process. It doesn't matter how long that process takes as we have already given the response to the client and you don't need to destroy the process until that process is completed (if it hanged, just kill the process and re-queue message to the queue. This way we can ensure that every request will be processed).
After the process is done, you can notify the client by a push notification or Websocket implementation with resulted data.
I know this could be overdoing a simple task. But if you want to keep your feature's reliability and usability, this is worth doing. Also, you can use this in Microservice architecture. In fact this is a concept of Microserivces. Here is a good read to learn some about this approach.

How to avoid Response error: 429 Too Many Requests

One Spring boot application sends many calls in parallel to another and in one time i faced with 29 Too Many Requests
How can avoid it?
You should stop spamming your server and rethink your architecture. The 429 status is not an error. It is more a hint to stop spamming:
The 429 status code indicates that the user has sent too many
requests in a given amount of time ("rate limiting").
https://www.rfc-editor.org/rfc/rfc6585#page-3
You need K8s with clustering of your micro service and to think how you want
to scale your pods horizontally.
On top of that you need to use a load balancer and maybe to use the ribbon + Hysterix + Feign client out of the stack of spring cloud solution.
And you also have too check that you don't receive too many auto-retry technical requests of your underlying HTTP client.
Your application sends many calls in parallel to another, I unable to get what is another?,
If another is db call then you can increase connection size in db then you wouldn't be get in future.
or else if another is API call then you should go with batch statement it will helpful instead of parallel call.
This is standard use case for Pub-Sub pattern. Use any message queue like, SQS, Kafka etc.
First spring boot instance should push messages to this queue. Another spring application (or any application) should poll messages at the rate suitable for it self.
Messages will be hold in the queue until app2 picks it up.

Is this the best architecture/design to handle requests with large payload and heavy time-consuming process to handle each request in Java Ecosystem?

Which is the best architecture to handle multiple http requests sending a list of ids (with more than 1000 ids in each request) and each request will be a heavy time-consuming process that communicate with other systems (that uses SOAP or REST) and saves data into a RDBMS?
Should I send the ids in a POST HTTP request?
Should I use Spring Framework Async/Futures (without return) in a Resource/Controller REST to handle the Time-consuming process and return HTTP 202 Accepted (and maybe an ID to query the status of the process or the resource)?
Or Is it good if my Resources/Controllers REST only put the messages in a JMS Queue (maybe a persistent queue for each REST method) and Message-Driven Beans (for each method) consume the messages and process the request?
It is a good idea if my Resources/Controllers REST or a class acting like a proxy save the requests for my system and other systems responses in a database for logging purposes and to fix problems? Or should I use the retry feature in JMS for example?
I agree with dunni; however, your general requirements sound like JMS would be a good place to start. That would allow clients to drop off requests and allow back end components to work on the requests as they are able. Of course, you need enough back end power to get all the requests completed in a reasonable time frame.

How to handle thousands of request in REST based web service at a time?

Is making REST based web service (POST) asynchronous is the best way to handle thousands of requests at one time (Keeping in mind that I have only single instance of server serving the request)?
Edited:
Jersey is wrongly tagged.
For eg: I have a rest based web service, which is supposed to be consumed by 100 thousand clients within a very short span of time (~60 seconds). I understand that if I am allowed to deploy multiple instance of the server, then I can use a load balancer to handle all my incoming request and delegate them accordingly. But I am restricted to use only single instance. What design could I opt within this restriction?
I could think of making the request asynchronous( which will not respond to client immediately ) in order to be able to let the server be free from this load and handle the requests at it's own pace.
For now we can ignore memory limitations.
Please let me know if this clarifies your doubt?
The term asynchronous could have different meanings in different places. For a web application code, it could refer to a Nonblocking I/O server such as Node or Netty/Akka which is a way for HTTP Requests to time multiplex on the same worker threads. If you're writing callbacks or using async or future constructs, it probably is non-blocking I/O which people sometimes refer to as asynchronous.
However, I could have REST API running on Node which implements non-blocking I/O, but the API or the overall architecture is still fully synchronous. For example, let's say I have an API endpoint POST /photos, which takes in a photo, creates image thumbnails, stores the URLs of the photo in a SQL Db and then stores the images in S3. The REST API could still block from the initial POST until after the image is processed and stored.
A second way is for the server to accept the photo process as a job and return immediately. Then the server could store the photo in a in memory or network based queue to be processed later by some other worker thread. In fact, I could even implement this async architecture even with a blocking server like some good old Java 7 and Jetty.

Server-side performing multiple requests against cloud services

I am in the process of writing a web-app that uses multiple web APIs.
For a single request of a single user, my app may need to perform up to 30 HTTP requests to other sites. The site housing the web-app can have hundreds of concurrent users.
I've been looking around trying to figure out which library should I use. I'm looking for a mature project that has detailed documentation and tested code, one that will still be around in years to come. Not sure if something like that exists (!)
Couple of questions :
In a case such as described above, should I be using an asynchronous HTTP client (without threading), or a regular (possibly pooled) HTTP client (with threading)? Asynchronicity relieves my app from using threads, but makes the code more scattered - will the above mentioned number of requests burden my server too much? (it says here that asynchronous is more scalable)
Which library is the common one to use? Is it Apache HttpComponenets HttpClient or its asynch couterpart HttpAsynchClient - which is in Alpha...)? How about jfarcand's AsyncHttpClient?
Okay, let's say I will use threads.
After digging around I realize that spawning threads from within a servlet (in my case - a Struts action), may be a big No No :
related questions:
What is recommended way for spawning threads from a servlet in Tomcat
Need help with java web app design to perform background tasks
Can i spawn a thread from a servlet ?
The way I see it, these are my options:
use my own thread pool (container doesn't manage my threads)
use a WorkManager such as CommonJ (seems like an inactive product)
use a 3rd party scheduler such as Quartz (may be an overkill ... ?)
I would appreciate any recommendations for this specific use case - aggregating lotsa data from different web services (this aggregation is invoked by a single user's single request).
Good question. I would try an asynchronous solution first to see how everything works. The asynchronous solution would be the simplest to implement.
If that doesn't work, try a more threaded model.
I would use HttpClient for making your requests. I've worked with it a lot and use it for any http work that I have to do.
A single thread for each remote http connection, and using a synchronous http client will probably be easier. I would try this approach first, and see if it is fast/scalable enough. For the synchronous approach, apache http client is a good choice.
If a synchronous solution is not good enough, something like netty may be a good fit. It uses NIO so you won't get thousands of threads.
I do not know of any existing software to do this for you that will not be overkill. But you might try splitting things up. That is, separate the fetching of the data of the showing of the result. Since you do not provide no further details on the problem at hand I cannot say for you whether that would be feasible or not.
Basically the idea is to create a service that will fetch those 30 subsequent requests for you and if possible process it into a request. The client of this service is the service that is running on the web. It will receive a request from a user and subsequently put it's own request trough to your data service. When the data service is ready it will return it's response. Either synchronously or asynchronously.
You could program your data service in any language you want, even Java, without being bound to servlets ensuring that fetching the subsequent 30 request and combining them in a response isn't being done by the webserver. This could also enhance the responsiveness of your web server itself.
Nutshell: branch of the ``difficult" tasks to a specialised service where you can transparently handle parallelism.
I would use Jetty and in the servlets I'd use the continuation mechanism to free up the thread while waiting for the third party web request to complete. This will allow maximum concurrency on your server, as you can have a lot more suspended requests than threads.
You can use either continuations or the servlet 3.0 asynchronous API, the end result is the same.

Categories

Resources