우아한테크코스/학습 정리

    [Grafana Loki] 다중 서버 환경에서 그라파나 로키를 이용해 로깅하기

    들어가면서 현재 진행중인 프로젝트에서 구성했던 서버를 Scale Out 하게 되었습니다. 여기에는 여러가지 배경이 있었는데요, 가장 큰 이유는 앞으로 있을 크고 작은 업데이트를 적용할 때 무중단 배포를 수행하기 위해 블루/그린 배포 전략을 적용하기 위한 서버 이중화가 필요했었다는 것입니다. 그에 따라 배포 시에는 블루/그린 서버로 사용되지만 평소에는 nginx 로드 밸런싱 기능을 활용하여 트래픽을 분산처리할 수 있도록 하여 리소스를 최대한 효율적으로 사용하고자 했습니다. 그런데 문제가 하나 있었습니다. 기존에는 단일 서버 환경에서 수행하던 로깅 데이터 모니터링이 정상적으로 동작하지 않는 문제였는데요. 그 원인은 서버가 이중화 되면서 한 곳에 저장되던 로깅 데이터가 각 서버에 나뉘어져 저장되기 시작했다는 ..

    [최적화] Tomcat 스레드 풀 튜닝에 대한 고찰

    들어가면서 서비스 API 서버를 구축하고 운영하면서 Tomcat 스레드 풀과 관련된 설정값들을 어떻게 튜닝할 수 있을지 생각해볼 기회가 생겼습니다. 막연하게 최적의 설정값을 찾으면 성능이 좋아지겠다고 생각은 했지만 왜 튜닝을 해야하는지, 어떻게 진행해야 하는지 감이 잘 잡히지 않았었습니다. 그래서 나름대로 백엔드 서버에서 Tomcat 스레드 풀 관련 설정값들을 왜 튜닝해야 하는지, 어떻게 튜닝할 수 있는지를 고민해보고 정리해봤습니다. 스레드 풀의 크기를 적절하게 조절해야 하는 이유 스레드를 생성하는 것은 비용이 많이 드는 작업입니다. 새로운 스레드를 위한 메모리 공간을 할당하는데 이 메모리 공간은 JVM이 할당받은 메모리 공간을 점유하게 됩니다. 이 때 기본적으로 1MB의 메모리 영역만큼을 하나의 스레드..

    [DB] 인덱스 기본 개념과 클러스터링, 논클러스터링 인덱스

    들어가면서 프로젝트의 기본적인 성능 최적화를 위해 사용중인 데이터베이스에 인덱스를 적용해야 할 일이 생겼습니다. 그 전에 인덱스의 간단한 기본 개념과 클러스터링, 논클러스터링 인덱스에 대해 정리해보려합니다. 인덱스 기본 개념 및 용어 정리 인덱스란 데이터베이스에서 원하는 값을 빠르게 찾기 위해 사용하는 자료구조입니다. 인덱스를 이용하면 데이터베이스 테이블에 대한 검색 성능을 향상시킬 수 있으며, where 절 등을 통해 활용됩니다. 인덱스의 특징 인덱스는 항상 최신의 정렬상태를 유지합니다. 인덱스도 하나의 데이터베이스 객체입니다. 데이터베이스 크기의 약 10% 정도의 저장 공간을 필요로 합니다. 자주 사용되는 용어 정리 페이지 : 데이터가 저장되는 단위 (MySQL 에서는 16KB) Full Table ..

    [Logging] Slack 알림 메세지 Logger 구현하기

    [Logging] Slack 알림 메세지 Logger 구현하기

    들어가면서 기존에 하루스터디 팀 프로젝트를 진행하면서 스프링 콘솔에서 출력되던 스프링 자체 로깅 메세지와 HTTP 웹 요청 / 응답 메세지 값들을 로깅하고자 했습니다. 이를 수행하기 위해 LogBack에서 기본으로 제공하는 Appender 중 RollingFileAppender를 채택해서 사용했습니다. 기본적으로 서버에 파일로 로깅 데이터를 남긴 후 그라파나로 시각화하여 로그를 조회할 수 있는 시스템을 구축하는 것이 최종적인 목표였기 때문입니다. 그러던 중 서버에서 에러 로그가 발생하면 자동으로 백엔드 팀 슬랙에 알림이 오도록 기능을 추가하고 싶어졌습니다. 현재는 서버에서 에러가 발생했는지 여부를 확인하기 위해 팀원들이 직접 그라파나에 접속해서 확인해야 했는데 이를 매번 주기적으로 확인하기란 쉽지 않습니..

    [Logging] Logback을 이용한 기본적인 로깅하기

    들어가면서 현재 진행중인 팀 프로젝트 하루스터디 서비스는 배포가 완료된 상태입니다. 배포 완료의 기쁨을 느꼈던 것도 잠시, 저희는 실제 배포 환경에서 서비스를 운영하면서 마주치는 버그와 이슈 상황들을 바로 마주하게 되었습니다. 로컬 환경에서라면 인텔리제이의 debug 기능을 활용하거나 정말 단순하게는 System.out을 통해 원하는 값을 직접 출력 해볼 수도 있을 것입니다. 하지만 현재 하루스터디 서비스는 배포 서버에 이미 배포가 되어 있는 상태라서 기존 방식으로는 버그와 이슈 상황들에 대한 원인 파악이 쉽지 않았습니다. 따라서 이를 해결하기 위해 로깅 기능을 구현해서 도입하기로 결정했습니다. 본 포스팅은 팀 로깅 작업을 진행하기 전 개인적으로 진행한 학습 내용을 정리하기 위한 것임을 밝힙니다. SLF..

    [Spring Data JPA] Save() 메서드 persist VS merge

    Spring Data Jpa에서 엔티티를 영속화 하기 위해서 repository 인터페이스를 만들고 save 메서드를 정의해 사용하는 것이 일반적이다. 그런데 학습과정에서 JpaRepository 인터페이스의 save 메서드 구현 코드를 접하게 되었다. 아래에 나온 코드는 org.springframework.data.repository.CrudRepository 의 기본 구현체로 제공되는 SimpleJpaRepository 클래스에 구현되어 있는 save() 메서드다. @Transactional @Override public S save(S entity) { Assert.notNull(entity, "Entity must not be null"); if (entityInformation.isNew(ent..

    엔티티 간 상속관계를 DB 모델로 구현하기 위해 Join 전략을 선택하는 이유에 대한 고찰

    들어가면서 위 이미지는 현재 하루스터디의 DDL을 도식화한 ERD입니다. 간략하게 각 테이블을 엔티티 단위로 묶어서 설명해보면 다음과 같습니다. study : 하루스터디 서비스에서 개설되는 스터디에 대한 정보를 관리 member_progress : 개설된 스터디에서 참여자들의 진행 정보를 관리 member_record : 참여자들이 스터디의 각 사이클마다 진행한 사전 계획과 회고를 관리 member : 참여자들의 개인 정보를 관리 participant_code : 스터디 방 개설 후 입장 시 필요한 참여코드를 관리 여기에서 주목할 것은 study, member_progress, member_record 테이블입니다. 현재 ERD에서는 한 눈에 알아보기 힘들긴 하지만 이 테이블들은 전부 Join전략을 통해..

    브랜치 전략에서 squash and merge 방식 사용에 대한 고찰

    들어가면서 우아한테크코스 레벨3에서 현재 팀 프로젝트(이하 하루스터디)를 진행하고 있다. 하루스터디 서비스 개발을 시작하기 전에 서비스 기획과 더불어서 팀 컨벤션을 정하는 회의를 많이 진행했다. 그 중 Git 브랜치 전략도 팀 컨벤션으로 정하였는데 이 기간에 예비군 훈련과 겹쳐서 직접적으로 팀원들과 브랜치 전략을 연습하고 정하는 시간에 함께하지 못했다. 이후 팀원들이 정리해둔 문서를 보며 혼자 브랜치 전략을 연습하던 와중 마주한 문제가 있었는데 이를 정리하고자 한다. squash and merge 사용 시 직면한 문제상황 위 이미지에 나온 것 처럼, main 브랜치에서 프로덕션 코드를 관리하고 develop 브랜치에서 기능 구현 작업들이 완료되면 main 브랜치에 PR을 날리는 방식으로 운영한다고 가정했..