0

스프링 부트 앱을 개발하려고합니다. 스프링 프레임 워크가없는 코어 자바에서 모든 핵심 구현을 작성했습니다. 나는이 봄의 부팅 응용 프로그램에서 그 항아리를 사용하고 있습니다. 나머지 컨트롤러의 동시성을 관리하고 싶습니다. 따라서 기본 클래스에서 ThreadPoolTaskExecutor를 적절히 구성하십시오. 이상적으로는 execute() 메소드에 들어가기위한 동시 요청이 2 개만 필요합니다. Async을 주석으로 추가했습니다. 한 번에 2 개의 동시 요청을 테스트했지만 로그에 내 요청이 모두 한 번에 execute()을 입력하는 것으로 나타났습니다. 모든 작업은 메모리 집약적입니다. 그래서 이들은 힙 메모리 문제로 실패하고 있습니다. 내가 이상적인 동시성 번호를 알아 내려고 노력 중입니다. 제 구성이 맞는지 또는 뭔가 빠졌는지 알고 싶습니다. 고맙습니다.스프링 부트 REST - ThreadPoolTaskExecutor 구성으로 요청을 실행하지 않습니다.

@RestController 
@RequestMapping("/end2end") 
public class End2EndRestController { 

    /** 
    * The log. 
    */ 
    private final Logger log = LoggerFactory.getLogger(this.getClass()); 

    @RequestMapping(method = RequestMethod.POST) 
    public JSONObjectPOJO process(@RequestBody String end2EndScenarioString) throws InterruptedException, ExecutionException { 

     final JSONObjectPOJO jsonObjectPOJO = convertToJavaObject(end2EndScenarioString); 
     final ExecutorService executor = Executors.newSingleThreadExecutor(); 
     executor.execute(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        execute(jsonObjectPOJO); 
       } catch (Exception e) { 
        e.getMessage(); 
       } 
      }}); 
      executor.shutdown(); 
      return jsonObjectPOJO; 
     }  
} 
을 : 지금 다음에 코드를 변경

:

여기 내 주요 클래스의 :

@SpringBootApplication 
@EnableAsync 
public class RestapiApplication implements AsyncConfigurer { 

    public static void main(String[] args) { 
     ApplicationContext ctx = SpringApplication.run(RestapiApplication.class, args); 
     System.out.println("Rightdata Middleware ready to accept requests:"); 
    } 

    @Bean(name = "executor1") 
    public Executor getAsyncExecutor() { 
     ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); 
     taskExecutor.setMaxPoolSize(2); 
     taskExecutor.setCorePoolSize(2); 
     taskExecutor.setThreadNamePrefix("LULExecutor-"); 
     taskExecutor.setQueueCapacity(100); 
     taskExecutor.initialize(); 
     return taskExecutor; 
    } 

    @Override 
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 
     return new SimpleAsyncUncaughtExceptionHandler(); 
    } 
} 

그리고 여기 내 REST 컨트롤러 :

@RestController 
@RequestMapping("/end2end") 
public class End2EndRestController { 

    /** 
    * The log. 
    */ 
    private final Logger log = LoggerFactory.getLogger(this.getClass()); 

    @RequestMapping(method = RequestMethod.POST) 
    public JSONObjectPOJO process(@RequestBody String end2EndScenarioString) throws InterruptedException, ExecutionException { 

     final JSONObjectPOJO jsonObjectPOJO = convertToJavaObject(end2EndScenarioString); 
     final ExecutorService executor = Executors.newSingleThreadExecutor(); 
     executor.execute(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        execute(jsonObjectPOJO); 
       } catch (Exception e) { 
        e.getMessage(); 
       } 
      }}); 
      executor.shutdown(); 
      return jsonObjectPOJO; 
     } 

    @Async("executor1") 
    private void execute(JSONObjectPOJO jsonObjectPOJO) throws Exception { 
     ExecutorService executorService = Executors.newFixedThreadPool(2); 
     Future<?> futureTarget; 
     Future<?> futureSource; 
     futureSource = processSource(executorService); 
     futureTarget = processTarget(executorService); 
     manageSourceProcessingResults(futureSource); 
     manageTargetProcessingResults(futureTarget); 
     executorService.shutdown(); 
     //Do rest of the tasks. 
    } 

    @SuppressWarnings({"unchecked", "rawtypes"}) 
    protected Future<?> processSource(executorService){ 
     //Get appropriate class instance with call() - coreActionClass. 
     Future<?> futureSource = executorService.submit(coreActionClass); 
     return futureSource; 
    } 

    @SuppressWarnings({"unchecked", "rawtypes"}) 
    protected Future<?> processTarget(executorService){ 
     //Get appropriate class instance with call() - coreActionClass. 
     Future<?> futureTarget = executorService.submit(coreActionClass); //callable method in core. 
     return futureTarget; 
    } 

    private void manageSourceProcessingResults(Future<?> futureSource) { 
     try{ 
      futureSource.get(); 
     } catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    private void manageTargetProcessingResults(Future<?> futureTarget) { 
     try{ 
      futureTarget.get(); 
     } catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 

UPDATE- 1

및 다른 이름 yncService 클래스 :

public class AsyncService { 

    @Async("executor1") 
    public void execute(JSONObjectPOJO jsonObjectPOJO) throws Exception { 
     ExecutorService executorService = Executors.newFixedThreadPool(2); 
     Future<?> futureTarget; 
     Future<?> futureSource; 
     futureSource = processSource(executorService); 
     futureTarget = processTarget(executorService); 
     manageSourceProcessingResults(futureSource); 
     manageTargetProcessingResults(futureTarget); 
     executorService.shutdown(); 
     //Do rest of the tasks. 
    } 

    @SuppressWarnings({"unchecked", "rawtypes"}) 
    protected Future<?> processSource(executorService){ 
     //Get appropriate class instance with call() - coreActionClass. 
     Future<?> futureSource = executorService.submit(coreActionClass); 
     return futureSource; 
    } 

    @SuppressWarnings({"unchecked", "rawtypes"}) 
    protected Future<?> processTarget(executorService){ 
     //Get appropriate class instance with call() - coreActionClass. 
     Future<?> futureTarget = executorService.submit(coreActionClass); //callable method in core. 
     return futureTarget; 
    } 

    private void manageSourceProcessingResults(Future<?> futureSource) { 
     try{ 
      futureSource.get(); 
     } catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    private void manageTargetProcessingResults(Future<?> futureTarget) { 
     try{ 
      futureTarget.get(); 
     } catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 
  1. 나의 이해는 내가 maxpoolsize(2)를 구성 할 때 더 이상 2 이상의 요청이 한 번에 실행() 메소드에있을 것입니다. 새 요청을 입력하려면 이전 요청 중 하나가 실행을 완료해야합니다. 내 이해가 맞습니까? async은 내부 실행자 서비스에 을 적용하겠습니까?
  2. 한 번에 2 개의 요청 만 처리되고 이러한 요청은 각각 2 개의 다른 스레드를 생성하고 작업을 완료 할 수 있다는 견해를 가지고 있습니다. 명확히하십시오.

답변

0

두 가지 문제점이 있습니다.

1) process 메서드에서 새 ExecutorService를 만듭니다. 이것은 필요하지 않습니다. 대신 jsonObjectPOJO을 검색 한 후 execute 메서드를 호출하면됩니다.

2) 구현 된 것과 동일한 클래스 인 @Async을 사용할 수 없습니다. 새 클래스를 만들어야하는데 MyAsyncService@Async 메서드가 포함되도록 호출해야합니다. 이것은 커버 아래에서 진행되는 애스펙트 지향 프로그래밍 때문입니다.

자세한 내용은 this link을 확인하십시오. 아래는 링크의 견적입니다.

첫째 -의 규칙을 통해 가자 - @Async는 두 가지 제한이 있습니다

는 public 메소드 만 자기 호출에 적용해야합니다

- 같은 클래스 내에서 비동기 메서드를 호출은 -하지 않습니다 work 이유는 간단합니다.이 방법은 공개되어 프록시 될 수 있어야합니다. 자체 호출은 프록시를 우회하여 기본 메소드를 직접 호출하기 때문에 작동하지 않습니다.

@RestController 
@RequestMapping("/end2end") 
public class End2EndRestController { 

@AutoWired 
AsyncService asyncService; 

private final Logger log = LoggerFactory.getLogger(this.getClass()); 
@RequestMapping(method = RequestMethod.POST) 
public JSONObjectPOJO process(@RequestBody String end2EndScenarioString) throws InterruptedException, ExecutionException { 
    final JSONObjectPOJO jsonObjectPOJO = convertToJavaObject(end2EndScenarioString); 
    asyncService.execute(jsonObjectPOJO); 
    return jsonObjectPOJO; 
} 




public class AsyncService { 

    @Async("executor1") 
    public void execute(JSONObjectPOJO jsonObjectPOJO) throws Exception { 
     //No Futures, no ExecutorServices, just process that request. 
    } 

} 

단지 2 개의 스레드를 사용하기위한 ThreadPoolTaskExecutor를 생성하고 구성함으로써, 당신은 당신의 목표를 달성했다 : EDIT 1

.

EDIT2 : Spring @Async limit number of threads

+0

감사합니다. 나는 당신이 말한 것을 따랐고 제 코드를 약간 변경했지만 실행자 서비스는'프로세스 '가되었습니다. update-1을보십시오. 다시 한번 감사드립니다. – manoman

+0

모든 ExecutorServices를 제거하십시오. @Async는 요청을 처리해야합니다. 이렇게 많은 수준의 병렬 실행을 수행하지 않아도됩니다. –

관련 문제