본문 바로가기

개인 학습 메모장

(103)
성능 최적화 (스케일 업, 인덱스 튜닝) 목표 TPS 저번 글에서 시나리오를 통해 성능테스트를 진행해봤다. TPS는 13이 나왔고 목표했던 17 ~ 52에 한참 모자란 결과이다. 예상보다 TPS가 너무 나오지 않아 원인을 분석해본 결과 DB인 것으로 확인이 됐다. 그래서 팀원끼리 각자 맡은 도메인에 대해 쿼리를 개선해보기로 하고 다시 성능테스트를 해봤다. DB에 데이터는 10만건 들어있는 상태다. 먼저 시나리오에 포함되지 않은 읽기 쿼리들까지 포함해서 성능테스트를 해본 결과 다음과 같은 결과가 나왔다. 에러율은 낮지만 TPS는 4.7로 처참한 것을 확인할 수 있다. db는 RDS의 t3.micro를 사용하고 있었는데, cpu 사용량이 100퍼센트 가까히 찍히는 것을 확인할 수 있다. 단순히 인덱스 튜닝만으로는 해결할 수 없을 정도의 TPS와 R..
Ngrinder로 성능테스트 하기 계기 프로젝트가 거의 마무리 되고 조만간 프론트엔드 분들도 작업이 완료될 예정이라고 한다. 이에 따라 사용자를 받기 전에 목표하는 트래픽을 감당할 수 있을지 성능테스트를 해보고 필요하다면 로컬 캐시, etag, 인덱스를 태우거나 쿼리 튜닝을 하고자 한다. 목표하는 트래픽 잡기 내가 진행중인 프로젝트를 간단하게 소개하자면 지도에 사진, 평점 등과 같은 것들을 기록하고 일기를 작성하는 지도기반 커플 다이어리이다. 유사한 어플리케이션으로 커플 앱인 비트윈, 썸원이 있고 다이어리 어플인 timetreep이라는 어플리케이션이 있다. 이제 similarweb이라는 사이트에서 위 어플리케이션들이 얼마나 많은 트래픽을 받는지 확인하고 목표 트래픽을 잡아보자. 썸원인 경우 한달에 약 23만, 비트윈인 경우 한달에 약 1..
코드의 품질 관리를 도움 받기: SonarCloud, CodeMetrics SonarCloud 코드를 작성하다 보면 통용되는 컨벤션, 중복되는 코드, 보안 취약점 등을 인지하지 못한채 개발하게 된다. 심지어 Java를 C언어 처럼 사용한다거나 Go 언어를 Javascript처럼 사용하는 경우가 있을 것이다.(본인이 익숙한 언어에 맞게 다른 언어를 사용함) 이렇게 되면 새로운 언어를 배운다 하더라도 자신에게 익숙한 언어의 언어스타일로 개발을 하게 되는데 새로운 언어를 사용하는 의미 또한 많이 떨어질 것이다. 이러한 문제를 해결하기 위해 SonarCloud라는 코드 분석 오픈소스가 탄생하게 됐다. 품질관리 요소 이제 어떻게 품질을 관리하는지 알아보자 소나큐브가 코드를 분석하는 지표는 여기에 있다. Java를 기준으로 사용해본 결과 이펙티브 자바에서 강조하는 내용과 일치하는 부분이 ..
오랜만에 일기 어느덧 부트캠프에 들어온지 4개월이 지났다. 그 동안의 시간을 돌아봤을 때 정말 열심히 공부했고 다시 돌아가더라도 더 열심히 할 수는 없을 것 같다는 생각이다. 이렇게 공부를 열심히 할 수 있었던 배경에는 동료들이 있었기 때문인 것 같다. 고맙게도 동료들은 나를 믿고 질문을 많이 해줬으며 나 또한 그것을 보답하기 위해 많이 공부했고 실제로 어려운 개념을 쉬운 말로 설명 하는 과정은 큰 학습 효과를 줬다고 생각한다. 이렇게 동료와 함께 공부하고 친해지는 것이 부트 캠프의 가장 큰 장점이 아닐까 싶다. 공부한 내용이 쌓여가며 과거를 돌아봤을 때 나의 프로젝트는 헛점 투성이었고 지금의 내가 이 사람과 함께 일할 수 있을까? 라는 질문을 해봤다. 뽑을 사람이 없다면 그렇게 하겠지만 잘하는 사람들 많은데 굳이 눈..
우리의 문제 상황에 맞는 락 구현 요약 사용자가 여러개의 좌석을 선택한 상황에서 동시에 다른 사용자가 선택한 좌석과 겹치는 상황이 발생했을 때 어떻게 하면 사용자의 경험을 좋게하면서 최소한의 비용으로 이 상황을 극복할지에 관해 작성했다. 좌석을 선점(선택)할 때는 db를 사용하지 않았기 때문에 일반적인 락과는 다르게 접근해야 했으며, 레디스라는 캐시 서버에 특정 조건에 연산이 수행되지 않도록 하는 것이 문제 해결의 열쇠였다. 문제상황 문제 상황을 말하기에 앞서 예약을 하는 흐름은 다음과 같다. 매장을 선택한다. 매장에서 예약가능한 시간과 날짜를 선택한다 해당 날짜의 좌석을 선점한다. 예약 버튼을 누르면 선점한 좌석이 예약이 된다. 이를 코드로 보여주자면 아래와 같다. 문제의 코드 예약할 좌석의 상태를 캐싱해두는 코드 @Service @R..
이벤트 기반으로 책임 분리 확장성 있는 코드 확장성 이라는 개념에는 여러가지 요소가 있다. 기능의 확장 저장소의 확장 서버의 확장 기능의 확장 예를 들어 회원가입을 하면 회원가입 쿠폰을 뿌린다거나, 회원가입 쿠폰을 뿌리는 이벤트를 종료하는 상황이 있을 것이다. 저장소의 확장 데이터가 너무나도 많이 쌓여 RDB가 아닌 NoSQL로 저장소를 변경하는 상황이 발생하거나, 읽기 성능을 최적화 하기 위해 별도의 저장소를 사용하는 상황이 발생할 수 있을 것이다. 서버의 확장 특정 도메인에 사용자가 과도하게 몰려 도메인 별로 트래픽을 분산해야 하는 상황이 발생할 수 있을 것이다. 앞선 상황 이외에도 확장이라는 개념에는 또 다른 요소가 있을 수 있겠지만 나는 코딩을 할 때 위 3가지의 상황을 과하지 않게 예측하고 코드를 작성하려고 노력한다. (..
테이블 설계 글의 목적 테이블을 설계하는 것은 무척이나 어렵다. 복잡하고 동적인 현실 세계의 관계를 정적인 구조로 만드는 일은 수 많은 상황을 예측해야 하는 일이다. 테이블을 설계하며 한 고민의 과정을 정리함으로써 다음에는 좀 더 나은 생각을 할 수 있도록 글을 작성한다. 캐치 테이블의 테이블 구조 가장 크게 한 고민은 어떠한 요소를 필드로 둘지, 테이블로 둘지 두 결정 사이의 장단점을 비교하며 설계 당시에는 가장 나은 선택을 했다. 테이블을 설계할 때 가장 중요하게 여긴 가치 확장 (기능의 확장) 코드로 구현했을 때의 모습 (도메인을 분리해 다른 어플리케이션으로 작동할 수 있을지) 특이사항으로 실제 캐치테이블에서는 지원하지 않는 매장 내 테이블을 지정하여 예약을 하는 기능을 추가했다. (진짜 어려웠음) 복잡한 구조..
주문 코드 리팩토링 최근 우아한 객체지향, KSUG 채널의 스프링캠프 2023 [Session 3] 대규모 엔터프라이즈 시스템 개선 경험기를 보고난 뒤 많은 영감이 떠올라 가장 최근에 했던 프로젝트를 리팩토링 했다. 사실 리팩토링 이라기 보다는 코드를 다시 작성했다고 보는 것이 맞는 것 같다. 사람마다 생각이 다르고 시스템마다 요구사항, 환경이 다르기 때문에 지금의 코드를 작성하면서 한 생각은 어떤 코드에서는 좋지 못할수도 있다. 그럼에도 나는 유지 보수성을 목표로 코드를 작성했다. 여기서 말한 유지 보수성이란 두려움 없이, 주저함 없이, 저항감 없이 코드를 변경할 수 있는 능력을 의미한다. 위 문구는 조영호님의 말로, 유지보수의 본질을 가장 명확하게 설명하고 있으며, 나의 마음에 가장 와닿았다. 자, 이제 코드를 개선해보..