- 자바/스프링/난이도-하/10분
이 글은 프로그래밍 관련 문제를 내고, 스스로 정답을 찾아가는 글이다.
아마도 문제는, 회사에서의 경험 50%, 신규로 생각해낸 문제 50% 정도의 비중일 것이다.
단, 보안상 회사 소스는 공개할 수 없기 때문에, 모든 내용은 필자가 직접 임의로 작성한 코드이다. 그래서, 필자가 직접 만든 문제 코드라서 좀 지저분하다.
첫번째 문제는, 아주 기초적인 스프링 RestTemplate 관련 내용이다. 필자는 해당 문제를 당일 바로 해결해야 하는 급한 상황이었는데, 20분 정도 걸려서 빠르게 개발했는데, 완전 잘못 코딩을 하였다. 바로 두 번의 코드리뷰를 통해서 코드를 수정을 했다. 어렵지 않은 내용인데 잘못해서 부끄럽게 생각한다. 아무튼 팀장님의 코드리뷰를 지원받아서 당일 배포는 잘 마무리가 되었다.
카테고리 : 자바&스프링
난이도 : 하
문제를 푸는 시간 : 10분
실제로 필자는 해당 문제를 해결하는데 20분 정도 소요된 것 같다. 회사 프로젝트는 더 복잡하게 소스가 꼬여있기 때문에 10분으로 해결할 수는 없었다. 간단한 코드라는 점 감안해서 10분 정도면 해결할 수 있는 문제라고 판단하였다.
생략
생략
생략
오픈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 주입을 잘못했다. 코드리뷰를 통해서 빠르게 다시 수정해서 해결하였다.
문제 소스가 엉망이다. 대충 짰다.
@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
Contribute to sieunkr/puzzles development by creating an account on GitHub.
github.com
필자의 정답은 다음 이시간에 작성하겠다. 문제에 대한 답을 작성하고 새로운 문제를 공개하는 방식으로 계속 이어나갔으면 한다.