Springboot 의 비동기 요청 과 비동기 호출 (op 동적 생 성 에이전트 대상)
특징: 시스템 서비스의 압력 을 줄 이 고 동시 다발 요 구 량 이 많은 경우 저 희 는 nginx 를 통 해 클 러 스 터 서비스의 각 노드 에 요청 을 부하 하여 요청 압력 을 분담 할 것 입 니 다. 물론 메시지 큐 를 통 해 요청 한 버퍼 도 할 수 있 습 니 다.
비동기 호출
일반적으로 개발 과정 에서 실제 업무 와 무관 하고 긴밀 성 이 없 는 방법 을 만 날 수 있다.예 를 들 어 로그 정 보 를 기록 하 는 등 업무.이때 정상 적 인 것 은 새로운 스 레 드 를 열 어 업무 처 리 를 하고 메 인 스 레 드 가 다른 업 무 를 수행 하도록 하 는 것 이다.
사용 방식
시작 클래스 에 @ EnableAsync 를 추가 하여 비동기 호출 @ Async 주 해 를 적용 해 야 합 니 다. 비동기 실행 이 필요 한 방법 에 이 주 해 를 추가 하면 @ Async ("threadPool"), threadPool 은 사용자 정의 스 레 드 풀 입 니 다.
주의 사항
기본 적 인 상황 에서 TaskExecutor 를 설정 하지 않 았 을 때 기본 값 은 Simple AsyncTaskExecutor 라 는 스 레 드 풀 을 사용 합 니 다. 그러나 이 스 레 드 는 진정한 의미 의 스 레 드 풀 이 아 닙 니 다. 스 레 드 가 다시 사용 되 지 않 기 때문에 호출 할 때마다 새로운 스 레 드 를 만 듭 니 다 (jvm 은 스 레 드 를 만 들 고 라인 을 없 앨 때마다 자원 을 특별히 소모 합 니 다).콘 솔 로그 출력 을 통 해 매번 출력 스 레 드 이름 이 증가 하고 있 음 을 알 수 있 습 니 다.그래서 우 리 는 스 레 드 탱크 를 정의 하 는 것 이 좋 습 니 다.호출 된 비동기 방법 은 같은 종류의 방법 (같은 종류의 내부 클래스 포함) 을 만 들 수 없습니다. 쉽게 말 하면 Spring 은 스 캔 을 시작 할 때 프 록 시 클래스 를 만 들 고 같은 종류의 프 록 시 클래스 를 호출 할 때 그 자체 의 프 록 시 클래스 를 호출 하기 때문에 일반적인 호출 과 같 습 니 다.다른 주석, 예 를 들 어 @ Cache 등 도 마찬가지 입 니 다. 말하자면 Spring 의 대리 체제 가 만 든 것 입 니 다.따라서 개발 에 있어 서 비동기 서 비 스 를 따로 하나의 종 류 를 추출 하여 관리 하 는 것 이 좋 습 니 다 (이 종류 에 @ component 를 추가 하 는 것 을 기억 하 세 요).다음은 중점적으로 말씀 드 리 겠 습 니 다.
어떤 경우 @ Async 비동기 방법 이 효력 을 잃 을 수 있 습 니까?
a. 같은 종류의 베 팅 을 호출 할 때 @ Async 비동기 방법 이 있 습 니 다. spring 에서 @ Async 와 @ Transactional, cache 등 주 해 는 본질 적 으로 동적 대 리 를 사용 합 니 다. 사실 Spring 용 기 는 초기 화 할 때 Spring 용기 가 AOP 주 해 를 포함 한 클래스 대상 을 대리 대상 으로 '교체' 합 니 다 (간단하게 이해). 그러면 주해 가 효력 을 잃 는 원인 이 뚜렷 합 니 다.대리 대상 이 아 닌 대상 자 체 를 호출 하 는 것 이기 때문이다. Spring 용 기 를 거치 지 않 았 기 때문에 해결 방법 도 이 를 따라 해결 된다.b. 정적 (static) 방법 c. 호출 (private) 사유 화 방법
지난 문제 해결 중 a 방식
비동기 적 으로 실행 할 방법 을 단독으로 하나의 클래스 로 추출 합 니 다. 원 리 는 비동기 적 으로 실행 하 는 방법 을 단독으로 하나의 클래스 로 추출 할 때 이 종 류 는 반드시 Spring 에 의 해 관리 되 고 다른 Spring 구성 요소 가 호출 되 어야 할 때 반드시 주입 되 는 것 입 니 다. 이때 실제로 주입 되 는 것 은 대리 류 입 니 다.사실 우리 의 주입 대상 은 모두 Spring 용기 에서 현재 Spring 구성 요소 에 구성원 변 수 를 할당 하 는 것 입 니 다. 어떤 종 류 는 AOP 주 해 를 사 용 했 기 때문에 실제 Spring 용기 에 존재 하 는 것 은 대리 대상 입 니 다.그러면 우 리 는 문맥 을 통 해 자신의 대리 대상 이 비동기 적 인 방법 을 호출 할 수 있다.
@Controller
@RequestMapping("/app")
public class EmailController {
// ApplicationContext , ,
@Autowired
private ApplicationContext applicationContext;
@RequestMapping(value = "/email/asyncCall", method = GET)
@ResponseBody
public Map<String, Object> asyncCall () {
Map<String, Object> resMap = new HashMap<String, Object>();
try{
//
//this.testAsyncTask();
//
EmailController emailController = (EmailController)applicationContext.getBean(EmailController.class);
emailController.testAsyncTask();
resMap.put("code",200);
}catch (Exception e) {
resMap.put("code",400);
logger.error("error!",e);
}
return resMap;
}
// public, static
@Async
public void testAsyncTask() throws InterruptedException {
Thread.sleep(10000);
System.out.println(" !");
}
}
cglib 대 리 를 열 고 Spring 대리 류 를 수 동 으로 가 져 와 같은 비동기 방법 을 사용 합 니 다.
우선, 시작 클래스 에 @ EnableAspectJAutoProxy (exposeProxy = true) 주 해 를 추가 합 니 다.코드 구현, 다음 과 같 음:
@Service
@Transactional(value = "transactionManager", readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
public class EmailService {
@Autowired
private ApplicationContext applicationContext;
@Async
public void testSyncTask() throws InterruptedException {
Thread.sleep(10000);
System.out.println(" !");
}
public void asyncCallTwo() throws InterruptedException {
//this.testSyncTask();
// EmailService emailService = (EmailService)applicationContext.getBean(EmailService.class);
// emailService.testSyncTask();
boolean isAop = AopUtils.isAopProxy(EmailController.class);// ;
boolean isCglib = AopUtils.isCglibProxy(EmailController.class); // CGLIB ;
boolean isJdk = AopUtils.isJdkDynamicProxy(EmailController.class); // JDK ;
// !!!
EmailService emailService = (EmailService)applicationContext.getBean(EmailService.class);
EmailService proxy = (EmailService) AopContext.currentProxy();
System.out.println(emailService == proxy ? true : false);
proxy.testSyncTask();
System.out.println("end!!!");
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.