>  기사  >  Java  >  Spring Boot의 두 가지 비동기 요청 방법에 대한 자세한 설명

Spring Boot의 두 가지 비동기 요청 방법에 대한 자세한 설명

Y2J
Y2J원래의
2017-05-08 15:54:073463검색

Spring 3.2 이후 버전에서는 요청의 비동기 처리가 추가되었습니다. 이 글에서는 비동기 요청을 구현하기 위한 Spring Boot(Servlet 3.0)를 주로 소개합니다.

요청 처리 속도를 높이고 서비스 성능 소비를 줄이기 위해 Spring 3.2 이상 버전에 요청 비동기 처리가 추가되었습니다.

동시 요청의 경우 웹 서버의 연결 풀을 장기간 점유하여 발생하는 성능 문제를 피하기 위해 시간이 많이 걸리는 요청 처리를 수행했습니다. 처리를 위해 호출이 이루어진 후에 생성되므로 웹 서버의 처리량이 늘어납니다.

이러한 이유로 Servlet 3.0에는 요청의 비동기 처리 기능이 추가되었으며 Spring도 이를 기반으로 이를 캡슐화했습니다.

이 기사에서는 여전히 코드 예제를 사용하여 Spring Boot에서 비동기 요청을 적용하는 방법을 설명합니다.

먼저 몇 가지 핵심 사항에 대해 이야기하겠습니다.

1. @WebFilter 및 @WebServlet 주석의 asyncSupported = true 속성

비동기 처리 서블릿에 filter가 있는 경우 필터의 @WebFilter 주석을 asyncSupported=true로 설정해야 하며, 그렇지 않은 경우

, 오류 필터 또는 현재 체인의 서블릿이 비동기 작업을 지원하지 않습니다.

2. @EnableAsync 주석

Spring Boot에서 일부 추가 기본적으로 /*를 차단하는 필터입니다. /*가 모든 요청을 차단하기 때문에 asyncSupported=true 속성도 설정해야 하는 이유가 됩니다. 이러한 필터는 Spring Boot에 의해 초기화되므로 통합 구성을 위한 @EnableAsync 주석을 제공합니다. 이 주석은 "@WebFilter가 아닌 주석 및 @WebServlet 주석"에만 유효하므로 우리가 정의하는 필터는 여전히 asyncSupported= true를 구성해야 합니다. .

3. AsyncContext 객체

비동기 요청의 컨텍스트 객체를 가져옵니다.

4. asyncContext.setTimeout(20 * 1000L);

비동기 요청을 무기한 대기시킬 수 없으며 setTimeout을 통해 최대 시간 초과를 설정할 수 있습니다.

두 가지 방법으로 비동기 작업을 테스트합니다.

먼저 SpringBootSampleApplication에 @EnableAsync 주석을 추가합니다.

모든 맞춤 필터를 다시 확인하세요. 아래 두 가지 상황이 있는 경우 asyncSupported=true를 구성해야 합니다.

1) 맞춤 필터 차단 /*

2) 특정 필터가 /shanhy/*를 가로채고 우리가 실행해야 하는 비동기 요청 서블릿은 /shanhy/testcomet

방법 1: 기본 서블릿 방법

package org.springboot.sample.servlet;

import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * HTTP长连接实现
 *
 * @author 单红宇(365384722)
 * @myblog http://blog.csdn.net/catoop/
 * @create 2016年3月29日
 */
@WebServlet(urlPatterns = "/xs/cometservlet", asyncSupported = true)
//异步处理的servlet若存在过滤器,则过滤器的注解@WebFilter应设置asyncSupported=true,
//否则会报错A filter or servlet of the current chain does not support asynchronous operations.
public class CometServlet extends HttpServlet {

 private static final long serialVersionUID = -8685285401859800066L;

 private final Queue<AsyncContext> asyncContexts = new LinkedBlockingQueue<>();

 private final Thread generator = new Thread("Async Event generator") {

  @Override
  public void run() {
   while (!generator.isInterrupted()) {// 线程有效
    try {
     while (!asyncContexts.isEmpty()) {// 不为空
      TimeUnit.SECONDS.sleep(10);// 秒,模拟耗时操作
      AsyncContext asyncContext = asyncContexts.poll();
      HttpServletResponse res = (HttpServletResponse) asyncContext.getResponse();
      res.getWriter().write("{\"result\":\"OK - "+System.currentTimeMillis()+"\"}");
      res.setStatus(HttpServletResponse.SC_OK);
      res.setContentType("application/json");
      asyncContext.complete();// 完成
     }
    } catch (InterruptedException e) {
     Thread.currentThread().interrupt();
     e.printStackTrace();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }

 };

 @Override
 public void init() throws ServletException {
  super.init();
  generator.start();
 }

 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  System.out.println(">>>>>>>>>>CometServlet Request<<<<<<<<<<<");
  doPost(req, resp);
 }

 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  AsyncContext asyncContext = req.startAsync();
  asyncContext.setTimeout(20 * 1000L);
  asyncContexts.offer(asyncContext);
 }

 @Override
 public void destroy() {
  super.destroy();
  generator.interrupt();
 }
}

방법 2: 컨트롤러 방법

@Controller
public class PageController {

 @RequestMapping("/async/test")
 @ResponseBody
 public Callable<String> callable() {
  // 这么做的好处避免web server的连接池被长期占用而引起性能问题,
  // 调用后生成一个非web的服务线程来处理,增加web服务器的吞吐量。
  return new Callable<String>() {
   @Override
   public String call() throws Exception {
    Thread.sleep(3 * 1000L);
    return "小单 - " + System.currentTimeMillis();
   }
  };
 }

}

마지막으로 Comet.jsp 페이지 테스트 작성:

<%@ page pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
 <title>长连接测试</title>
 <script type="text/javascript" src="${pageContext.request.contextPath }/webjarslocator/jquery/jquery.js"></script>
 <script type="text/javascript">
  $(function(){
   function longPolling(){
    $.getJSON(&#39;${pageContext.request.contextPath }/xs/cometservlet&#39;, function(data){
     console.log(data.result);
     $(&#39;#n1&#39;).html(data.result);
     longPolling();
    });
   }
   longPolling();

   function longPolling2(){
    $.get(&#39;${pageContext.request.contextPath }/async/test&#39;, function(data){
     console.log(data);
     $(&#39;#n2&#39;).html(data);
     longPolling2();
    });
   }
   longPolling2();
  });
 </script>
 </head>

 <body>
 <h1>长连接测试</h1>
 <h2 id="n1"></h2>
 <h2 id="n2"></h2>
 </body>
</html>

[관련 권장 사항]

Java 무료 동영상 튜토리얼
2.

이미지의 동일 비율 썸네일 구현에 대한 Java 동영상 튜토리얼

3. 🎜>

위 내용은 Spring Boot의 두 가지 비동기 요청 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.