Spring boot 쿼리 최적화 문제와 Spring Cloud Openfeign

2024. 6. 19. 00:01·Springboot

오늘은 내가 프로젝트의 전반적인 기능이 완성되고 성능을 개선시킨 부분에 대해 말해보고자 한다.


일단 어느정도 개발이 완료 되고난후, 직접 Grafana로 각 API 요청시 발생하는 CPU 사용량이나 Memory 사용량에 대해 추적해보았다. 

그러던중... 다음과 같은 이슈를 마주했다.

 

이슈

👉 현재 작업하던 Post Service의 CPU 및 Memory 사용량이 다른 MSA 환경의 Service들보다 매우 높다는 것을 **[Grafana monitoring]**을 통해 확인이 되었다.

Memory: 1.26 GIB, CPU: 0.699

문제

👉 실제로 Jmeter로 서버 성능을 측정을 해보고 프론트에서도 요청을 보냈을때 시간이 매우 오래걸리는 것으로 보아 백엔드 비즈니스 로직자체가 무겁고 어딘가 불필요하게 시간이 소요된다는 것을 알 수 있었다.

 

해결

👉 최대한 MSA 서비스들 사이의 요청과 응답을 최대한 줄여주고, 불필요한 메모리 소모 혹은 데이터베이스 테이블 같은 것은 속성으로 변경

 

1. 명령형 API(RestTemplate)을 Openfeign 연결로 변경

Before

String updateURL = recUrl + "/recommends/editings";
        String jsonBody;
        ObjectMapper objectMapper = new ObjectMapper();

        String token = jwtProvider.parseToken(request);
        try {
            Map<String, Object> docFields = new HashMap<>();
            docFields.put("changedHashtag", hashtags);
            docFields.put("blogId", blogId);
            System.out.println("docFields = " + docFields);
            jsonBody = objectMapper.writeValueAsString(docFields);
            HttpRequest updateRequest = HttpRequest.newBuilder()
                    .uri(URI.create(updateURL))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + token)
                    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                    .build();

            HttpClient client = HttpClient.newHttpClient();
            HttpResponse<String> updateResponse = client.send(updateRequest,
                    HttpResponse.BodyHandlers.ofString());

            if (updateResponse.statusCode() == 200) {
                System.out.println("업데이트 완료");
            } else {
                System.out.println("업데이트 도중 오류가 발생하였습니다: " + updateResponse);
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        Map<String, Object> docFields = new HashMap<>();
        docFields.put("changedHashtag", hashtags);
        docFields.put("blogId", blogId);
        System.out.println("docFields = " + docFields);

        recommendClient.sendAllHashtags(docFields, "Bearer " + token);
    }

원래는 이렇게 HTTP Client 요청을 해주었으나 

 

@FeignClient(name ="recommend-service", url = "${application.config.recommend-url}")
public interface RecommendClient {

    @PostMapping("/hashtags")
    void sendNewHashtags(@RequestBody Map<String, Object> docFields, @RequestHeader("Authorization") String token);

    @PostMapping("/editings")
    void sendAllHashtags(@RequestBody Map<String, Object> docFields, @RequestHeader("Authorization") String token);


}

이렇게 openfeign Client 연결로 변경해주었다!

 

2.  불필요한 테이블 속성값으로 대체

프로젝트 전체를 살펴보던중, 과도한 쿼리가 발생하는 영역을 분석한 후 테이블 정규화를 해제 시켜줬어. 요청이 잦은 서버 간의 두 테이블을 적절히 조인하여, 주로 발생하는 쿼리 수를 크게 줄일 수 있었다!

 

Category table 제거

해결 결과

결과적으로, CPU 사용량을 0.699에서 0.129로 대폭 감소시키는 데 성공했으며, 코드의 품질과 유지보수성 또한 크게 개선할 수 있었다. 특히 명령형 API를 사용하지 않고 비동기 호출 방식을 활용해 서버 간 요청 대기 시간을 줄이고, 인터페이스 기반의 호출 규격을 명확히 정의할 수 있어 개발 생산성과 유지보수성을 동시에 향상시킬 수 있었다!

CPU 사용량 대폭 감소: 0.699 → 0.129

'Springboot' 카테고리의 다른 글

SpringBoot: TDD(Test-Driven-Development)란?  (5) 2025.01.03
Spring Batch 활용  (1) 2024.12.09
Spring boot: DDD(Domain Driven Design)란?  (0) 2024.09.23
Spring Boot 순환 참조 오류(Error creating bean with name)  (1) 2024.06.18
SpringBoot Builder 패턴의 이해  (3) 2024.04.03
'Springboot' 카테고리의 다른 글
  • Spring Batch 활용
  • Spring boot: DDD(Domain Driven Design)란?
  • Spring Boot 순환 참조 오류(Error creating bean with name)
  • SpringBoot Builder 패턴의 이해
무엇을해야하는지
무엇을해야하는지
어차피 잘될거지만, 그래도 꾸준히 열심히 최선을 다해서
  • 무엇을해야하는지
    What2Do
    무엇을해야하는지
  • 전체
    오늘
    어제
    • 분류 전체보기 (92)
      • MLOps (5)
        • DeepLearning(연구-논문) (0)
        • MS Azure AI (1)
        • MLOps projects (4)
      • DevOps&Cloud (23)
      • AWS (21)
      • Algorithm(Python) (25)
      • Springboot (8)
      • IT 시사 (2)
      • 운영체제 (4)
      • 네트워크 (2)
      • JAVA (1)
      • 면접&코테 후기 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    SpringBoot
    스프링부트
    rockstat
    3차원
    BFS
    cors #클라이언트 #서버 #서버사이드 렌더링
    aws #iam #group #role
    ec2 #instace
    testcode #spring #단위테스트 #통합테스트
    tdd #테스트코드 #spring #springboot
    dp #dfs
    clpud
    leetcode #codesignal #코테 #그리디 #알고리즘
    카엔프
    프로세스
    EC2
    dp #동적계획법 #백준 #파이썬
    AWS
    knapsack #가방 #백준 #dp #topdown
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
무엇을해야하는지
Spring boot 쿼리 최적화 문제와 Spring Cloud Openfeign
상단으로

티스토리툴바