brunch

You can make anything
by writing

C.S.Lewis

by 에디의 기술블로그 Sep 12. 2018

[자문자답]1번째 퍼즐

- 자바/스프링/난이도-하/10분

이 글은 프로그래밍 관련 문제를 내고, 스스로 정답을 찾아가는 글이다. 

아마도 문제는, 회사에서의 경험 50%, 신규로 생각해낸 문제 50% 정도의 비중일 것이다. 

단, 보안상 회사 소스는 공개할 수 없기 때문에, 모든 내용은 필자가 직접 임의로 작성한 코드이다. 그래서, 필자가 직접 만든 문제 코드라서 좀 지저분하다.



1번째 퍼즐

첫번째 문제는, 아주 기초적인 스프링 RestTemplate 관련 내용이다.  필자는 해당 문제를 당일 바로 해결해야 하는 급한 상황이었는데, 20분 정도 걸려서 빠르게 개발했는데, 완전 잘못 코딩을 하였다. 바로 두 번의 코드리뷰를 통해서 코드를 수정을 했다. 어렵지 않은 내용인데 잘못해서 부끄럽게 생각한다. 아무튼 팀장님의 코드리뷰를 지원받아서 당일 배포는 잘 마무리가 되었다. 


카테고리 : 자바&스프링

난이도 : 하

문제를 푸는 시간 : 10분


실제로 필자는 해당 문제를 해결하는데 20분 정도 소요된 것 같다. 회사 프로젝트는 더 복잡하게 소스가 꼬여있기 때문에 10분으로 해결할 수는 없었다. 간단한 코드라는 점 감안해서 10분 정도면 해결할 수 있는 문제라고 판단하였다. 



관련연구

RestTemplate 이란?

생략

커넥션 풀 이란?

생략

스프링 DI 주입 방법?

생략



문제 배경

오픈API 를 호출하는 스프링부트 환경의 웹 애플리케이션이 있다고 가정하자. 애플리케이션의 클래스 다이어그램은 아래와 같다. 아주 심플하다. 


요약

서비스 레이어에는 BlogService 와 VideoService 클래스가 있다. 해당 클래스는 오픈API 를 호출/응답하는 비즈니스 로직을 포함하고 있다. 오픈API 로의 호출은 스프링의 RestTemplate 를 사용하는데, 서비스레이어에서 직접 호출하지 않고 OpenApiRequestComponent 컴포넌트를 사용한다. Service 레이어에서는 openApiRequestComponet 라는 Bean 을 주입받고, 해당 Bean 에 정의된 공통 호출 메서드를 사용하는데, 그 호출 메서드 즉, OpenApiRequestComponent 에 정의된 메서드에서 RestTemplate를 사용해서 외부 호출을 수행한다. RestTemplate 는 RestTemplateConfig 에서 Bean 을 생성한다. 


억지로 만들어 낸 예제라서 깔끔하지는 않다. 참고만 하길 바란다. 


문제 개요

문제는 Blog를 조회하는 API 와 Video 를 조회하는 API 의 응답 속도가 매우 다른 상황이다. 하나의 RestTemplate 를 사용해서 제어하기에는 운영하기 빡씬 상황이었다. 그래서 각각의 RestTemplate 를 사용해서 커넥션 풀을 따로 관리하고자 한다. 


RestTemplate 를 분리하고, BlogService 와 VideoService 에서 각각 따로 분리 된 RestTemplate 를 사용한다.

분리된 RestTemplate 는 각각의 커넥션 풀을 사용한다. RestTemplate 빈 선언시에 PoolingHttpClientConnectionManager 를 사용해서 maxTotal 과 defaultMaxPerRoute 를 각각 설정 해준다.

풀의 상태에 대한 로그를 수집한다.


옛날 개발자인 필자는 @Bean 주입을 잘못했다. 코드리뷰를 통해서 빠르게 다시 수정해서 해결하였다.


문제 소스(AS-IS)

문제 소스가 엉망이다. 대충 짰다. 


@Component

public class OpenApiRequestComponent {

    @Autowired

    private RestTemplate restTemplate;

    public String findAll(String url){

        //restTemplate.exchange()

        return "응답 데이터";

    }

}


@Configuration

public class RestTemplateConfig {

    @Bean

    public RestTemplate restTemplate() {

        return new RestTemplate();

    }

}


@RestController

public class BlogController {

    @Autowired

    private BlogService blogService;

    //blogService 호출 로직 생략

}


@RestController

public class VideoController {

    @Autowired

    private VideoService videoService;

    //videoService 호출 로직 생략

}


@Service

public class BlogService {

    @Autowired

    private OpenApiRequestComponent openApiRequestComponent;

    public String findAll(){

        return openApiRequestComponent.findAll("BLOG-OPEN-API-URL");

    }

}


@Service

public class VideoService {

    @Autowired

    private OpenApiRequestComponent openApiRequestComponent;

    public String findAll(){

        return openApiRequestComponent.findAll("VIDEO-OPEN-API-URL");

    }

}


https://github.com/sieunkr/puzzles/tree/master/puzzle-no01/question


필자의 정답(TO-BE)

필자의 정답은 다음 이시간에 작성하겠다. 문제에 대한 답을 작성하고 새로운 문제를 공개하는 방식으로 계속 이어나갔으면 한다.

작가의 이전글 Essential Use Cases
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari