Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the asynchronous request mode of Servelt3 in Java

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces the knowledge of "what is the asynchronous request mode of Servelt3 in Java". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

With the synchronous request model, all actions are handed over to the same Tomcat thread, and all actions are processed before the thread is released back to the thread pool.

Imagine that if the business takes a long time to process, then this Tomcat thread is actually occupied all the time, and as there are more and more requests, there are fewer and fewer available Ibino threads until they are exhausted. At this point, subsequent requests can only wait for idle Tomcat threads, which will increase the request execution time.

If the client doesn't care about returning business results, we can customize the thread pool, submit the request task to the thread pool, and return immediately.

You can also use the Spring Async task. If you are interested, you can look up the information on your own.

But in many scenarios, the client needs to process the returned results, and we cannot use the above solution. In the era of Servlet2, there is no way to optimize the above solution.

However, when Servlet3 introduces new features of asynchronous Servlet, the above requirements can be perfectly addressed.

Asynchronous Servlet executes the request process:

Parse the request information to HttpServletRequest

Distribute to specific Servlet processing, submit the business to the custom business thread pool, the request is immediately returned, and the Tomcat thread is immediately released.

When the business thread finishes executing the task, it will transfer the result to the Tomcat thread

Return the response result to the waiting client through HttpServletResponse

The overall process of introducing asynchronous Servlet3 is as follows:

Using asynchronous Servelt,Tomcat threads only handles request parsing actions, and all time-consuming business operations are handed over to the business thread pool, so Tomcat threads can handle more requests than synchronous requests.

Although we hand over the business processing to the business thread pool for asynchronous processing, for the client, it is still waiting for the response result synchronously.

Some students may think that asynchronous requests will get faster response time, but it is not, on the contrary, it may be due to the introduction of more threads, increasing thread context switching time.

Although there is no reduction in response time, there are other obvious advantages through request asynchronization:

Can handle a higher number of concurrent connections and improve the overall throughput of the system

Request parsing is completely separated from business processing, and the responsibility is single.

Custom business thread pool, which can be easily monitored, degraded, etc.

Different thread pools can be customized according to different businesses. They are isolated from each other and do not have to influence each other.

So the specific use process, we also need to carry out the corresponding pressure test, observe the response time and throughput and other indicators, comprehensive selection.

How asynchronous Servelt is used

The use of asynchronous Servelt is not very difficult. Ah Fan's summary is as follows:

HttpServletRequest#startAsync gets the AsyncContext asynchronous context object

Use a custom business thread pool to handle business logic

The business thread processing ends, and the response result is returned through AsyncContext#complete

The following example will use SpringBoot, Web container to select Tomcat

The sample code is as follows:

ExecutorService executorService = Executors.newFixedThreadPool (10); @ RequestMapping ("/ hello") public void hello (HttpServletRequest request) {AsyncContext asyncContext = request.startAsync (); / / timeout asyncContext.setTimeout (10000); executorService.submit (()-> {try {/ / dormant 5s, simulated business operation TimeUnit.SECONDS.sleep (5) / / output response result asyncContext.getResponse () .getWriter () .println ("hello world"); log.info ("end of asynchronous thread processing");} catch (Exception e) {e.printStackTrace ();} finally {asyncContext.complete ();}}) Log.info ("servlet threading ends");}

The browser accesses the request and waits for 5 seconds to get the output response. The output result of the application log is as follows:

2020-03-24 07 INFO 27 INFO 79257-[nio-8087-exec-4] com.xxxx: servlet threading ends 2020-03-24 07 com.xxxx 27purl 13.998 INFO 79257-[pool-1-thread-3] com.xxxx: end of asynchronous threading

Here we need to pay attention to setting a reasonable timeout to prevent the client from waiting for a long time.

SpringMVC

Servlet3 API, can not use the features provided for us by SpringMVC, we need to deal with the response information ourselves, which is relatively cumbersome.

SpringMVC 3.2 introduces asynchronous request processing based on Servelt3, which makes it as convenient to use asynchronous requests as synchronous requests.

SpringMVC provides two asynchronous methods. You only need to modify the return value of the Controller method to the following classes:

DeferredResult

Callable

DeferredResult

DeferredResult is a new class introduced after SpringMVC 3.2.As long as you let the request method return DeferredResult, you can quickly use asynchronous requests. The sample code is as follows:

ExecutorService executorService = Executors.newFixedThreadPool (10); @ RequestMapping ("/ hello_v1") public DeferredResult hello_v1 () {/ / set the timeout DeferredResult deferredResult = new DeferredResult (7000L); / / when the asynchronous thread processing ends, the callback method deferredResult.onCompletion (()-> {log.info ("asynchronous thread processing ends");}) / / if the execution time of the asynchronous thread exceeds the set timeout, the callback method deferredResult.onTimeout (()-> {log.info ("asynchronous thread timeout"); / / sets the returned result deferredResult.setErrorResult ("timeout error");}); deferredResult.onError (throwable-> {log.error ("exception", throwable) / / set the returned result deferredResult.setErrorResult ("other error");}); executorService.submit (()-> {try {TimeUnit.SECONDS.sleep (5); deferredResult.setResult ("hello_v1"); / / set the returned result} catch (Exception e) {e.printStackTrace () / / if the internal exception of the asynchronous method is deferredResult.setErrorResult ("error");}}); log.info ("servlet threading ends"); return deferredResult;}

You can pass a specific timeout when creating a DeferredResult instance. In addition, we can set the default timeout:

# Asynchronous request timeout spring.mvc.async.request-timeout=2000

If the execution of the asynchronous program is complete, you can call DeferredResult#setResult to return the response result. If the DeferredResult#onCompletion callback method is set, the callback method will be triggered.

At the same time, we can also set the timeout callback method DeferredResult#onTimeout, which will be triggered once the asynchronous thread executes a timeout.

Finally, DeferredResult also provides other abnormal callback methods onError. At first, A Fan thought that whenever an exception occurred in the asynchronous thread, the callback method would be triggered. An attempt was made to throw an exception within an asynchronous thread, but failed to trigger it.

After that, A Fan checks the doc of this method, and an exception occurs when the web container thread processes the asynchronous request.

Callable

Spring also provides a way to use asynchronous requests, using JDK Callable directly. The sample code is as follows:

@ RequestMapping ("/ hello_v2") public Callable hello_v2 () {return new Callable () {@ Override public String call () throws Exception {TimeUnit.SECONDS.sleep (5); log.info ("Asynchronous method end"); return "hello_v2";}};}

By default, direct execution will output WARN logs

This is because asynchronous requests are executed using SimpleAsyncTaskExecutor by default, and a new thread is created for each call execution. Since this method does not reuse threads, it is not recommended for production, so we need to use thread pools instead.

We can customize the thread pool in the following ways:

@ Bean (TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME) public AsyncTaskExecutor executor () {ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor (); threadPoolTaskExecutor.setThreadNamePrefix ("test-"); threadPoolTaskExecutor.setCorePoolSize (10); threadPoolTaskExecutor.setMaxPoolSize (20); return threadPoolTaskExecutor;}

Note that the Bean name must be applicationTaskExecutor. If it is inconsistent, Spring will not use a custom thread pool.

Or you can directly use the SpringBoot configuration file instead of:

# number of core threads spring.task.execution.pool.core-size=10 # maximum number of threads spring.task.execution.pool.max-size=20 # thread name prefix spring.task.execution.thread-name-prefix=test # there are other configurations that readers can configure on their own

The timeout for asynchronous requests in this way can only be configured through a configuration file.

Spring.mvc.async.request-timeout=10000

If we need to configure a specific timeout for individual requests, we need to wrap the Callable with WebAsyncTask.

@ RequestMapping ("/ hello_v3") public WebAsyncTask hello_v3 () {System.out.println ("asdas"); Callable callable=new Callable () {@ Override public String call () throws Exception {TimeUnit.SECONDS.sleep (5); log.info ("Asynchronous method end"); return "hello_v3";}} / / Unit ms WebAsyncTask webAsyncTask=new WebAsyncTask; return webAsyncTask;} "what is the asynchronous request mode of Servelt3 in Java"? thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report