0

私はスプリングブートアプリケーションを開発しようとしています。私は春のフレームワークなしでコアJavaのすべてのコア実装を書いています。私はこの春のブートアプリでその瓶を使用しています。私は、残りのコントローラの同時性を管理したいと思います。したがって、メインクラスでThreadPoolTask​​Executorを設定してください。理想的には、私は​​メソッドに入るために2つの同時リクエストしか必要としません。これはAsyncというアノテートです。一度に2つの同時リクエストをテストしていましたが、ログには私のリクエストが一度に​​と入力されています。すべてのタスクはメモリを大量に消費します。だから彼らはヒープメモリの問題で失敗している。私は理想的な並行性の数を把握しようとしています。私の設定が正しいか、何か不足しているかどうかを知りたいですか?ありがとうございました。ここでSpringブートREST - ThreadPoolTask​​Executorコンフィグレーションでリクエストが実行されない

は私のメインクラスです:私は今、次のようにコードを変更した

@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:

@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; 
     }  
} 

およびAs 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以上の要求を設定する際に、一度にexecute()メソッドになることです。 新しい要求を入力するには、以前の要求の1つが の実行を完了する必要があります。私の理解は正しいのですか? asyncは内部実行者サービスに を適用しますか?
  2. 私は一度に2つの要求しか処理されず、 これらの要求のそれぞれが2つの異なるスレッドを生成し、 のタスクを完了できるという見解です。どうか明らかにしてください。

答えて

0

2つの問題があります。

1)processメソッドでは、新しいExecutorServiceを作成しています。これは必要ではありません。代わりに、jsonObjectPOJOが取得された後にexecuteメソッドを呼び出すだけです。

2)実装されているのと同じクラスの@Asyncを使用することはできません。新しいクラスを作成する必要があります。MyAsyncService@Asyncメソッドを含めることができます。これは、カバーの下で進行中のアスペクト指向プログラミングのためです。

詳細はthis linkをご覧ください。以下はリンクからの引用です。

ファースト - のルールの上に行きましょう - @Asyncは、2つの制限があります。

それはpublicメソッドにのみ 自己呼び出しを適用する必要があります - 同じクラス内から非同期メソッドを呼び出す - しませんwork 理由は簡単です。メソッドを公開してプロキシできる必要があります。プロキシをバイパスし、基礎となるメソッドを直接呼び出すため、自己呼び出しは機能しません。

EDIT 1:

@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つのスレッドを使用するようにThreadPoolTask​​Executorを作成して構成することにより、あなたはあなたの目標を達成しました。

EDIT2:Spring @Async limit number of threads

+0

お寄せいただきありがとうございます。私はあなたが言ったことに従って、私のコードにいくつかの変更を加えましたが、executorサービスは 'process'にしました。 update-1を見てください。再度、感謝します。 – manoman

+0

すべてのExecutorServicesを削除します。 @Asyncはリクエストを処理するだけです。あまりにも多くのレベルの並列実行をしないでください。 –

関連する問題