Introduction
- A standardized Java API that allows web servers to execute Java code for HTTP requests.
- When web server receives request:
- servlet processes the request
- servlet sends back HTTP response (HTML / JSON / etc.)
- Spring is built on top of Servlets.
- so it is foundation of Spring MVC/ Spring Boot
- Tomcat use thread to execute the DispatcherServlet, which then delegates to Spring MVC to handle the real business logic.
How Servlet work on request:
-
Servlet container creates and manage threads, and the thread execute the single servlet instance.
- There is ONE DispatcherServlet object
- There are MANY threads
- Each thread calls the same servlet instance
// so same single servlet instances handles all concurrent requests using multiple threads
-
So controller must be stateless, since multiple threads are accessing instance var concurrently
-
If the shared state is mutable, will cause race condition
Request 1 → Thread-1 → DispatcherServlet instance
Request 2 → Thread-2 → DispatcherServlet instance
Request 3 → Thread-3 → DispatcherServlet instance
- Each request runs on a separate thread (one request one thread)
-
Thread will wait during:
- DB call
- External API call
- File I/O
// traditional Servlet model, I/O operations are blocking instead of wating
-
Many slow requests (long wait):
- Thread pool can be exhausted
- Server stops accepting new requests
-
Example:
- If thread pool size = 200
- There is 200 slow request (like DB calls) same time
- So 200 threads are currently all occupied
- The 201st request will wait in request queue
- If queue is full, the request will be rejected
- Timeout / degraded performance
- Hence, must avoid mutable shared state
Servlet run inside Servlet Container
- One Tomcat instance creates one servlet instance.
- Tomcat’s thread pool uses multiple threads to execute that single servlet instance concurrently for different requests.
Servlet Container (Tomcat)
This is the real HTTP engine: