How are asynchronous requests handled by servlets? - java

I apologize in advance if this is a bad question.
I'm new to backend development and I'm trying to build an instant messaging service with GAE using java servlets.
And I assume the process for sending a message will be like this:
1. Client send JSON file to servlet.
2. Servlet parses the JSON file and archives the message to the database.
So my question is:
what's going to happen if the next user attempts to send another message while the servlet is in the middle of the process of saving the previous message to the database?
Because the arrival of user requests are not synchronized with the servlet cycle, will the new request just get lost?
Is there going to be some mechanism that queues the request or it's something that I'll have to implement myself?
I think I'm really confused about how the asynchronous request between different functions in a distributed system works.
And, if there any readings that you would recommend for backend design pattern? or just a general introduction?
Thanks a lot!

Please read the official tutorial on the subject that talks in depth about the java web technologies , web containers and servlets:
http://docs.oracle.com/javaee/6/tutorial/doc/bnafd.html
But to answer your questions :
When another HTTP request comes in , a new thread will be created by
the web container and will run your servlet concurrently.
The new request will be processed concurrently
The answer depends on your specific problem , performance and SLA requirements. The simplest solution would be to parse and write each request to the database. If you are dealing with a very large number of simultaneous requests coming in , i'd suggest starting a whole new discussion on the subject.

You need to know exactly what the 'Thread' is? When another request sent to Servlet. The container like tomcat will assign another thread for this request. Every thread is independent from another.

Server requests will run in parallel and your code might access/edit the same data concurrently. You should use Datastore transactions to prevent data corruption.
No, requests are independent and they run in parallel.
You could use Task Queues in your code to make updates run sequentially, but I'd advise highly against it: first Task Queue will double your requests, second it will force a distributed parallel system to run sequentially, basically negating the whole purpose of AppEngine.
Parallel processing are essential in server programming - they enable servers to process high amount of requests. You should write code that takes this into account - use datastore transactions to prevent possible data corruption in those cases.

in a servlet lifecycle the init() and destroy() methods are called only once - but the service() will be called each time a new request comes and hit the application and a new instance of the servlet will be shared with the request through a different thread . Therefore one of the most basic rules for creating a servlet is not to create global variable in a servlet class.
Your variable is readable/writeable by any other class. You have no control to ensure that they all do sensible things with it. One of them could overwrite it/incorrectly increment it, etc
The is one instance of a servlet, per JVM. So may threads may try to access it concurrently. Because it is global, and you are not providing any synchronization/access control, it will not be thread-safe. Also, if you ever run the servlet in some kind of cluster with different JVMs, then the variable will not be shared between them and you will have multiple loginAttempt variables.

Related

A single servlet for all server request types vs multiple servlets -- one for each request type

Suppose on a high-traffic web-server, there are different types of requests from the client side. Eg.: user-requests vs internal/administrative types.
And, among the user-requests,
there's those you want to serve more promptly
(because they are more time-critical, are more frequent, etc).
The single servlet to handle these requests is "light"-- it sees
what each request is about and invokes right away the back-end process to handle it.
So, if you'd like to prioritize these requests, you prioritize these back-end processes on the server-- give them more CPU time, allocate them multiple server instances, etc.
The question here is: whether doing the same thing
to the servlets as well as these backend processes is an issue or not.
I'm aware that the servlet container (Tomcat in this case)
has some mechanisms-- although I don't know what/how exactly.
On one side of this discussion-- yes: code different servlets
for different client requests so that you can
manage their priorities/execution time at the server level.
On the other side-- no, not at all:
The servlet(s) are handling the requests and dispatching them
to the corresponding processes without burning execution time.
It's the back-end processes that are time-critical.
In fact, this is exactly what Spring is doing--
has the DispatcherServlet as the front-controller for all incoming requests.
A single servlet as the front-controller for all requests is the sound architecture.
This discussion came up few days back. up until then,
i was on the "no" side-- the paragraph right above.
however, i'm not as clear right now.
I'm wondering what would be a sound counter-argument to the claim that
"managing the priorities of the servlets for their types
improves the time performance on serving the client requests."
TIA.
//==================================================
EDIT:
If the case "yes" above,then how does Spring tell
the servlet container about the different types of requests so that the s.container can prioritize them?
I don't think the requests prioritization will have a huge effect on thread time execution unless were talking about a huge traffic like millions of thread on a single web server.But if that is what you want you can configure tomcat to prioritize threads. Tomcat allows you to specify the priority of each thread in an executor's thread pool: tomcat thread pool

How to properly implement RabbitMQ RPC from Java servlet web container?

I'd like for incoming Java servlet web requests to invoke RabbitMQ using the RPC approach as described here.
However, I'm not sure how to properly reuse callback queues between requests, as per the RabbitMQ tutorial linked above creating a new callback queue per every request is inefficient (RabbitMQ may not cope even if using the Queue TTL feature).
There would generally be only 1-2 RPC calls per every servlet request, but obviously a lot of servlet requests per second.
I don't think I can share the callback queues between threads, so I'd want at least one per each web worker thread.
My first idea was to store the callback queue in a ThreadLocal, but that can lead to memory leaks.
My second idea was to store them in a session, but I am not sure they will serialize properly and my sessions are currently not replicated/shared between web servers, so it is IMHO not a good solution.
My infrastructure is Tomcat / Guice / Stripes Framework.
Any ideas what the most robust/simple solution is?
Am I missing something in this whole approach, and thus over-complicating things?
Note 1- This question relates to the overall business case described here - see option 1.
Note 2 - There is a seemingly related question How to setup RabbitMQ RPC in a web context, but it is mostly concerned with proper shutdown of threads created by the RabbitMQ client.

How is multi-threading different in a Java based Web Application vs Stand-alone Java Application

I am fairly new to Java and my experience is limited to Web Based Applications running on a Web Container (Jboss in my case).
Am I correct in saying that for Web Applications the web container takes care of multi-threading? If so, can I introduce new treads in a Web Based applications? Is there any advantage in doing so and in what scenario one would need to do that?
Thanks
Most web containers make application they run multi-threaded, since containers implement 'multi-threaded servlet model'. So, your application (code of your servlets) already being run by several threads, therefore, it must be thread-safe (you must use proper synchronization when accessing shared data, such as your servlet class' instance fields, etc.)
It's perfectly legal to launch new threads from within your web applications. For example, you may need it to launch some long-running task (registration of user in database which ends in email sending, or calculation of PI up to 100000th decimal place) and close user HTTP request immediately after that, making user's browser finish loading given URL.
The web application server tends to create a new thread for each request. As such if two suers are filling the form and submitting it at the same time, you can be rest assured that both request are sent to the server using separate threads. The number of concurrent users accessing any particular page will actually determine the load the page can handle.
As far as creating new threads are concerned. You can certainly create new threads inside the application using the conventional java methods to create a new thread.
Generally you would like to create a new thread in case you want to perform an async task and does not want the user to wait for the output. Say suppose insertion of large data in DB which is nowhere related to user will generally be written in thread.
Also, in case where you intend to perform long running task in the background, the code is generally written inside a thread.
At times, there are requirement that the user accessing the page and requesting for something also needs to be inside a thread at your server end. E.g. trying to access a printer. IN that case you also need to ensure that your code is written inside a thread and you have properly synchronized the method.
Am I correct in saying that for Web Applications the web container takes care of multi-threading?
Most of the Severs are multithreaded to handle multiple request concurrently.
can I introduce new treads in a Web Based applications?
Yes you can. It depends on your requirement .
Is there any advantage in doing so and in what scenario one would need to do that?
If there is a time taking job which can be done asynchronously in to parts then use multiple threads.
e.g. on a request you have to read a huge file and dump in to database. In such case you can use multiple threads to read line by line and insert in to DB.
As I said it depends.
Most web application servers handle incoming requests on their own thread. That means if your server handles 5 requests concurrently it's running 5 threads.
That's usually enough multithreading to sufficiently exercise a medium-to-big server.
If, however, you've got an atypical workload (for example few requests, but each requests includes heavy computation), then introducing your own multi-threading on top of this may be worth the investment.

Java patterns for long running process in a web service

I'm building a web service that executes a database process (SQL code to run several queries , then move data between two really large tables), I'm assuming some processes might take 2 to 10 hours to execute.
What are the best practices for executing a long running database process from within a Java web service (it's actually REST-based using JAX-RS and Spring)? The process would be executed upon 1 web service call. It is expected that this execution would be done once a week.
Thanks in advance!
It's gotta be asynchronous.
Since your web service call is an RPC, best to have the implementation validate the request, put it on a queue for processing, and immediately send back a response that has a token or URL to check on progress.
Set up a JMS queue and register a listener that takes the message off the queue and persists it.
If this is really taking 2-10 hours, I'd recommend looking at your schema and queries to see if you can speed it up. There's an index missing somewhere, I'd bet.
Where I work, I am currently evaluating different strategies for this exact situation, only times are different.
With the times you state, you may be better served by using Publish/Subscribe message queuing (ActiveMQ).

How to implement asynchronous processing with J2EE application

I have an enterprise application with around 2k concurrent users every day. These users handle customer calls so application speed is of vital importance.
When a user is wrapping up a call they commit all the information they captured. This commit can take anywhere from 10-45 seconds.
I am looking into ways to take the delay away from the user.
We have a web front end running in I.E. the backend is heavy java running on a single EJB.
I wanted to make this commit process asynchronous in that once the user submits the request they don't have to wait for the commit to finish before going on to the next customer. This is what is currently implemented.
Originally I was thinking of just spawning another thread to handle the commit but that's a no no with EJB's.
Other options I can think of would be using JMS or SIB,
What would the best solution be? Is there another alternative I am missing?
There are actually two alternatives for cases like that.
The first one will be to use JMS. It has the advantage that the server provides all required infrastructure and you haven't to implement much yourself.
Another way will be to register the request in a database and have a scheduled event to process all of them.
What you select depends on your requirements. If you need to serve the requests as soon as they arrive, then you need to go with JMS. In both cases you need to persist the outcome of the request in a database and design a web service at the top of it. The front end could use this (through pollling) to present the result to the user.
Would have liked to leave a comment, but don't have the ability.
Another possibility:
Wrap the heavy EJB's in a queue mechanism, and expose a different bean with the same API so your client-facing communications talk to the new bean and are quick. They accept the request, add the job to the queue and return to the client immediately. You don't need to change the heavy EJB's or the client communications, just put a mediator in the way, and add a layer of wrapping.

Categories