2017-10-26 1 views
1

私はn個のメッセージリスナーを持つイベントキューを持っています。メッセージが到着すると、1つのメッセージリスナーがそれを取得し、対応するプールからステートマシンインスタンスを取得し、ステートマシンコンテキストを設定して開始します。 これは完璧に動作しますが、スレッドに問題があります。スプリングステートマシンのインスタンスが使用するスレッド数を制限するにはどうすればよいですか?

スタックトレースを分析
org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener method 'consume' threw exception 
at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:395) ~[spring-rabbit-1.7.4.RELEASE.jar!/:na] 
at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:298) ~[spring-rabbit-1.7.4.RELEASE.jar!/:na] 
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:848) ~[spring-rabbit-1.7.4.RELEASE.jar!/:na] 
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:771) ~[spring-rabbit-1.7.4.RELEASE.jar!/:na] 
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:102) [spring-rabbit-1.7.4.RELEASE.jar!/:na] 
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:198) ~[spring-rabbit-1.7.4.RELEASE.jar!/:na] 
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1311) [spring-rabbit-1.7.4.RELEASE.jar!/:na] 
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:752) ~[spring-rabbit-1.7.4.RELEASE.jar!/:na] 
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1254) [spring-rabbit-1.7.4.RELEASE.jar!/:na] 
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1224) [spring-rabbit-1.7.4.RELEASE.jar!/:na] 
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:102) [spring-rabbit-1.7.4.RELEASE.jar!/:na] 
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1470) [spring-rabbit-1.7.4.RELEASE.jar!/:na] 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_152] 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_152] 
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_152] 
Caused by: java.lang.OutOfMemoryError: unable to create new native thread 
at java.lang.Thread.start0(Native Method) [na:1.8.0_152] 
at java.lang.Thread.start(Thread.java:717) [na:1.8.0_152] 
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:957) [na:1.8.0_152] 
at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1603) [na:1.8.0_152] 
at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:334) ~[na:1.8.0_152] 
at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:533) ~[na:1.8.0_152] 
at java.util.concurrent.Executors$DelegatedScheduledExecutorService.schedule(Executors.java:729) ~[na:1.8.0_152] 
at org.springframework.scheduling.concurrent.ConcurrentTaskScheduler.schedule(ConcurrentTaskScheduler.java:182) ~[spring-context-4.3.11.RELEASE.jar!/:4.3.11.RELEASE] 
at org.springframework.statemachine.state.AbstractState.scheduleAction(AbstractState.java:415) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.state.AbstractState.scheduleStateActions(AbstractState.java:377) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.state.AbstractState.entry(AbstractState.java:208) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.state.ObjectState.entry(ObjectState.java:156) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.AbstractStateMachine.entryToState(AbstractStateMachine.java:1216) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.AbstractStateMachine.entryToState(AbstractStateMachine.java:1161) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentStateInternal(AbstractStateMachine.java:971) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentState(AbstractStateMachine.java:949) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.AbstractStateMachine.switchToState(AbstractStateMachine.java:841) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.AbstractStateMachine.access$400(AbstractStateMachine.java:77) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.AbstractStateMachine$2.transit(AbstractStateMachine.java:301) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.DefaultStateMachineExecutor.handleTriggerTrans(DefaultStateMachineExecutor.java:248) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.DefaultStateMachineExecutor.processTriggerQueue(DefaultStateMachineExecutor.java:395) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.DefaultStateMachineExecutor.access$100(DefaultStateMachineExecutor.java:61) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.DefaultStateMachineExecutor$1.run(DefaultStateMachineExecutor.java:281) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) ~[spring-core-4.3.11.RELEASE.jar!/:4.3.11.RELEASE] 
at org.springframework.statemachine.support.DefaultStateMachineExecutor.scheduleEventQueueProcessing(DefaultStateMachineExecutor.java:300) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.DefaultStateMachineExecutor.execute(DefaultStateMachineExecutor.java:144) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.AbstractStateMachine.sendEventInternal(AbstractStateMachine.java:559) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.AbstractStateMachine.sendEvent(AbstractStateMachine.java:211) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at org.springframework.statemachine.support.AbstractStateMachine.sendEvent(AbstractStateMachine.java:223) ~[spring-statemachine-core-1.2.6.RELEASE.jar!/:1.2.6.RELEASE] 
at io.botbit.backend.consumers.EventConsumer.consume(EventConsumer.java:39) ~[classes!/:0.0.1-SNAPSHOT] 
at sun.reflect.GeneratedMethodAccessor74.invoke(Unknown Source) ~[na:na] 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_152] 
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_152] 
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:269) ~[spring-core-4.3.11.RELEASE.jar!/:4.3.11.RELEASE] 
at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:387) ~[spring-rabbit-1.7.4.RELEASE.jar!/:na] 
... 14 common frames omitted 

、原因は次のとおりです:

Caused by: java.lang.OutOfMemoryError: unable to create new native thread 

ステート・マシン・インスタンスは、そのプールのサイズによって制限されているので、私は総スレッド数が制限を持っているだろうが、私が間違っていると思いましたスプリングステートマシンのインスタンスで使用されるスレッドの量を制限するにはどうすればよいですか?

ありがとうございます!

アップデート1

私は何@SpaceTrucker提案しました:

@Bean(name = "stateMachineTaskScheduler") 
public ConcurrentTaskScheduler stateMachineTaskScheduler() { 
    ScheduledThreadPoolExecutor threadPool = new ScheduledThreadPoolExecutor(10); 
    ConcurrentTaskScheduler taskScheduler = new ConcurrentTaskScheduler(threadPool); 
    return taskScheduler; 
} 

、その後

builder.configureConfiguration().withConfiguration().taskScheduler(stateMachineTaskScheduler());

今の状態マシンは、このプールを使用しています。問題は、すべてのステートマシンインスタンスが、自身のtaskSchedulerインスタンスを持つ各ステートマシンインスタンスではなく、このプールの同じインスタンスを使用していることです。あなたは自分のニーズに合わせて構成された豆でtaskSchedulerを交換する必要が

@Configuration 
@EnableStateMachine 
public class Config17 
     extends EnumStateMachineConfigurerAdapter<States, Events> { 

    @Override 
    public void configure(StateMachineConfigurationConfigurer<States, Events> config) 
      throws Exception { 
     config 
      .withConfiguration() 
       .autoStartup(true) 
       .beanFactory(new StaticListableBeanFactory()) 
       .taskExecutor(new SyncTaskExecutor()) 
       .taskScheduler(new ConcurrentTaskScheduler()) 
       .listener(new StateMachineListenerAdapter<States, Events>()); 
    } 
} 

spring docs

+0

しかし、すべてのステートマシンが独自のスケジューラを使用する場合、解決しようとしている同じ問題、つまりスレッドが多すぎるのでしょうか? – SpaceTrucker

+0

ステートマシンインスタンスはプールされているため、制限されています。各マシンに限定されたthreadPoolを持つタスクスケジューラがある場合は、必要に応じてスレッドを作成しているスレッドがないため、スレッド数の合計が制限されていると仮定します。私が間違っている? –

答えて

1

は、この構成例を提供します。例えば、限定された数のスレッドでscheduledExecutorを使用するConcurrentTaskSchedulerの別のインスタンス。

+0

クイック返信ありがとう!私はあなたが提案したことをしました。元の投稿の#Update 1をご覧ください。 –

関連する問題