2011-08-04 2 views
3

Spring TaskExecutor를 사용하여 메모리 부족 예외가 발생하지 않도록 작업을 생성하는 방법은 무엇입니까?Spring TaskExecutor를 사용하는 응용 프로그램에 대한 모든 요청에서 단일 작업 풀을 사용하는 방법

현재 작업 풀 구성 :

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> 
    <property name="corePoolSize" value="56" /> 
    <property name="maxPoolSize" value="112" /> 
    <property name="queueCapacity" value="100" /> 
</bean> 
<bean id="threadExecutor" class="com.content.ThreadHandler.ThreadExecutor"> 
    <constructor-arg ref="taskExecutor" /> 
</bean> 
</beans> 

와 내가 같이 부하 콩을 사용하여 내 요청 처리기에서 콩을 사용하고 있습니다 :

ApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"ThreadPoolConfig.xml"}); 
      BeanFactory factory=context; 

      ThreadExecutor myBean=(ThreadExecutor)factory.getBean("threadExecutor"); 

하고 난 mybean.execute로 된 TaskExecutor를 사용 (태스크);

이 구성이 요청마다 새 풀을 생성합니까?

답변

1

SUGGESTION 1

당신은 인스턴스화해서는 안 SPR을 참조하십시오 각 요청에 대한 응용 프로그램 컨텍스트. SpringContext라는 이름의 싱글 톤 클래스가 있어야하며, 스프링 애플리케이션 컨텍스트를 한 번만 인스턴스화해야한다. 따라서 클라이언트 코드는 단지

ThreadExecutor myBean=(ThreadExecutor)SpringContext.getInstance().getBean("threadExecutor"); 

이어야합니다. 앞서 언급했듯이 SpringContext는 일반 싱글 톤 클래스 여야합니다. 초기화 메소드에서 스프링 applicationcontext를 인스턴스화합니다.

public class SpringContext { 

    public ClassPathXmlApplicationContext context; 

    private static SpringContext _instance = new SpringContext(); 

    private SpringContext() { 
     context = new ClassPathXmlApplicationContext(new String[]{"ThreadPoolConfig.xml"}); 
    } 

    public static SpringContext getInstance() { 
     return _instance; 
    } 


    public Object getBean(String bean) { 
     Object beanObj = (context != null) ? context.getBean(bean) : null; 
     return beanObj; 
    } 

} 

2

이 경우이 작동하지 않습니다 SUGGESTION, 당신은 다음에 표시되어야합니다

스프링 빈 요소는 범위 속성이 있습니다. 지정할 수있는 값 중 두 개는 HTTPRequest 및 HTTPSession에 해당하는 요청 및 세션입니다. 귀하의 경우에 그들 중 하나를 사용해보십시오. http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-factory-scopes

그래서 여러분의 빈 정의는 사용 context.destroy() 메소드 내가 어떤 메모리 누수를 야기하고 .I 400 요청의 부하 함께 일하고 성능에 영향을 미칠 것입니다 무슨 경우

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" scope="session"> 
+0

내 코드에 대해 어떻게 할 수 있는지 예를 들어 주시겠습니까? 큰 도움이 될 것입니다 – San

+1

내 게시물을 읽었습니까? –

+0

예 읽기 ...하지만 세션과 같은 혼란 스러웠다. 내 응용 프로그램은 JVM이 재부 팅되기 전에 일주일 동안 실행되므로 세션 범위가 작동합니다. 즉, 모든 요청이 동일한 풀을 세션으로 범위를 사용하여 사용합니다. ... 답장을 주셔서 감사합니다 – San

0

모든 요청에 ​​대해 새 ClassPathXmlApplicationContext를 만들고 있습니까? 이 경우 모든 요청에 ​​대해 새 풀을 만들므로 매우 비효율적입니다.

OutOfMemory 오류가 발생하고있는 것으로 판단 할 때 나는 당신이라고 생각할 것입니다. 컨텍스트 사용을 마친 후에는 context.destroy()를 호출해야합니다. 그렇지 않으면 가비지 수집이 빈에서 사용하는 모든 메모리를 수집하지 않으므로 요청마다 응용 프로그램이 누출됩니다.

일반적으로 (웹 응용 프로그램에 대해 이야기하는 경우) web.xml의 ContextLoaderListener을 사용하여 하나의 풀만 사용한다는 단일 WebApplicationContext를 만들 수 있습니다.

웹 응용 프로그램에 대해 이야기하는 경우 일반적으로 자체 스레드 풀을 만드는 것이 좋지 않습니다. 이러한 스레드는 응용 프로그램 서버에서 관리하지 않으므로 두 개의 스레드가 많아 성능에 부정적인 영향을 줄 수 있습니다 서버 인스턴스에

편집 (당신은 Work Manager을 사용하지 않는 경우)의 ContextLoaderListener에 대한 자세한 정보는 Here

+0

처럼 보일 것이다 각 요청마다 8 스레드를 생성하는 초당 .... 또한 ContextLoaderListner를 사용하는 방법에 대한 자세한 정보를 제공 할 수 있습니다. – San

+0

스프링 컨텍스트를 초기화하는 데 상당한 오버 헤드가 있으므로 모든 요청에 ​​대해 컨텍스트를 다시 만들지는 않을 것입니다. . context.destroy를 사용하면 메모리 누수를 막을 수 있지만 모든 요청에 ​​대해 스레드 풀을 생성 - 파괴하면 모든 요청에 ​​대해 새 스레드를 생성하므로 오버 헤드가 발생할 수 있으므로 400 요청/초에서 8 스레드를 생성 할 가능성이 가장 높습니다 이 스레드의 대부분을 대기 상태로 둡니다. 결국 서버에는 몇 개의 코어/CPU가 있습니까? 아마 1000s의 스레드를 처리하기에 충분하지 않을 것입니다. – beny23

관련 문제