2016-09-26 4 views
1

SQL 요청을 최적화하기 위해 불필요한 호출을 피하기 위해 다른 서비스 소비를 집계하는 서비스를 만들었습니다. (내 웹 애플리케이션의 일부 페이지는 수백만에게 하루 시간이라고, 그래서 데이터베이스 쿼리의 결과를 각 요청에 가능한 한 여러 번 재사용 할)스프링 4 @Service with @RequestScope

내가 만든 솔루션이 하나입니다

: 서비스 대신 기본 범위 (싱글)

내 컨트롤러에서

@Service 
@RequestScope 
public MyService { 

private int param; 

@Autowired 
private OtherService otherService; 

@Autowired 
private OtherService2 otherService2; 

private List<Elements> elements; 

private List<OtherElements> otherElements; 

public void init(int param) { 
    this.param = param; 
} 

public List<Elements> getElements() { 

    if(this.elements == null) { 
     //Init elements 
     this.elements = otherService.getElements(param); 
    } 

    return this.elements; 

} 

public List<OtherElements> getOtherElements() { 

    if(this.otherElements == null) { 
     //Init otherElements 
     this.otherElements = otherService2.getOtherElements(param); 
    } 

    return this.otherElements; 

} 

public String getMainTextPres() { 

    //Need to use lElements; 
    List<Elements> elts = this.getElements(); 

    .... 

    return myString; 

} 

public String getSecondTextPres() { 

    //Need to use lElements; 
    List<Elements> elts = this.getElements(); 
    //Also Need to use lElements; 
    List<OtherElements> otherElts = this.getOtherElements();   

    .... 

    return myString; 

} 
} 

이면 MyService에서의 @RequestScope있다 물론 833,

, 나는 다른 요소 때문에는 myService 사용을 많이 내 예를 단순화했습니다, 나는 그의 회원의 초기화가

이 방법은 속성의 게으른 로딩을하는 장점이있다 속성을 보호하는 경우에만 I 그것들이 필요하다. 내 프로젝트 (동일한 컨트롤러 또는 다른 컨트롤러)에서 SecondTextPres 만 필요한 경우 "getSecondTextPres"를 호출하면 내 예제 beacuse의 경우와 다른 두 목록이 초기화됩니다. 첫 번째 목록은 "getMainTextPres"가 호출 될 때 초기화되었습니다.

내 질문은 다음과 같습니다

  • 당신은 일을 이런 식으로 어떻게 생각하십니까?
  • 각 요청마다 서비스를 인스턴스화하기 때문에 성능 문제가 발생할 수 있습니까?

감사합니다.

줄리앙

+0

요청 범위 Bean으로 최적화 된 이유는 무엇입니까? 각 요청에는 자체 인스턴스가 있으며 재사용되는 것은 없습니다. 쿼리를 최적화하거나 캐시를 최적화하고 싶다면 Spring이 당신을 위해 할 수있는 일 (그리고 어떻게 결과를 캐싱 할 수 있는지)을 연구하는 것이 좋습니다. –

+0

같은 저수준 정보를 여러 번 사용하는 동일한 요청이 있기 때문에 최적화되었습니다.이 일을 수행하면 이미 서비스 계층에있는 데이터를 다시 사용할 수 있습니다. 2 가지 요청에 대해 최적화 할 생각이 없습니다 –

+0

단일 요청에서 이와 같은 최적화가 필요한 경우 흐름을 재검토해야 할 수 있습니다. 하나의 컨트롤러 만 조회하는 요청에서 다른 모든 요청은 새로운 요청입니다. 귀하의 설명을 보면, 측정하지도 않았거나 실제로 문제가있는 것을 최적화하려고 시도하는 것으로 보입니다. 최적화가 필요하지 않은 것들을 최적화하려고하는 것 같습니다. 기억하십시오 : * 조기 최적화는 모든 악의 근원입니다 *. 스코프를 도입하는 대신 사물을 향상시키는 방법이 더 쉽고 (그리고 더 쉽다)있을 수 있습니다. 그러나 먼저 측정, 측정, 측정. –

답변

0

나는 당신의 생각이 날지 않을 것이라고 생각합니다. 이 요청은 다른 요청 일 것입니다.이 경우 새 빈이 작성됩니다 (요소 및 기타 요소가 다시 비어 있음).

캐싱에 대해 생각 해본 적 있으십니까? Spring은 캐시 만료 등을 정의 할 수있는 좋은 지원을합니다.

+0

답장을 보내 주셔서 감사합니다. 실제로 각 요청이 다르므로 여러 인스턴스가 필요합니다 (매개 변수에 따라 다름) –

+0

캐시 정보 : 다른 소스에서 가져온 예제 beacause 데이터를 단순화했습니다. 내가 사용하는 주요 데이터는 수백만 개의 레코드가있는 데이터베이스에서 가져온 것이므로 충분한 캐시 (메모리가 충분하지 않음)를 가질 수 있는지 확신 할 수 없다. –

+0

"매개 변수에 의존"합니다. 이는 아마도 잘못된 가정입니다. 다른 매개 변수에 대해 다른 대답을 제공 할 수 있고 내부 상태를 유지하지 않는 서비스 만 있으면됩니다. – Observer

0

요청 범위에서 인스턴스화 서비스를 정확히 최적화하기를 원하는 것이 명확하지 않습니다. 메모리 풋 프린트가 마음에 들면 JMX 또는 VisualVM으로 쉽게 측정 할 수 있습니다.

한편 서비스 매개 변수와 (ofc) 데이터베이스 상태에 따라 모든 서비스 호출을 순수하게 만들 수 있으며 기본 범위 인 서비스를 Singleton으로 인스턴스화 할 수 있습니다.

이 결정은 각 호출마다 가능한 큰 개체 그래프를 인스턴스화하지 않고 요청이 완료된 후에도 GC로 정리할 필요가 없기 때문에 합리적인 금액의 리소스를 절약합니다.

엄밀히 말하자면 모든 호출에서 특정 클래스를 인스턴스화해야하는 이유와 호출에 특정 상태를 유지하지 않는 이유를 생각하는 것입니다.이를 싱글 톤으로 만듭니다.

지연로드에 대해 말하면 항상 100 번 반복되는 최악의 경우에 대해 생각하는 것이 좋습니다. 한 번로드되는 것과 전체 컨테이너 수명 동안 비교되는 무언가를 실제로 저장할 수 있습니까?

+0

감사. 나는 내가 충분히 명확하지 않았다고 생각한다. 매일 같은 "템플릿"페이지가 수백만 번로드되지만 다른 데이터가로드됩니다. 페이지가로드 될 때마다 클라이언트에 반환 된 정보를 생성하는 데 사용하는 약 10 개의 출력 정보가 ​​있습니다. 이 서비스를 만들 때 나의 목적은 데이터베이스 (또는 다른 소스)에서 같은 데이터를 여러 번 가져 와서 출력 정보를 만드는 것을 피하는 것이 었습니다. –

+0

또한 정보를 얻기 위해 때때로이 서비스를 사용할 수있는 다른 페이지 (및 다른 컨트롤러)가 있습니다. 예를 들어 secondTextPres 만 인쇄해야하는 다른 컨트롤러가있을 수 있습니다. –

+0

@JulienO이 서비스를 캐시와 실제 서비스라는 두 가지 분리 된 서비스로 분리해야한다고 말하고 싶습니다. 첫 번째 버전은 다양한 수준 (DB, HTTP, 서비스)으로 제공 될 수 있으며 응용 프로그램을 잘 모르고 사용해야하는 버전을 제안 할 수는 없습니다. 캐시 유형을 확인하고 어느 것이 가장 적합한 지 결정하십시오. 두 번째 것은 순수하게 만들어야하며 싱글 톤으로 제공되어야합니다. – Observer