기술블로그
-
배포(3) 무중단 배포: 롤링 vs 블루-그린(https 배포완료)
무중단 배포란 말 그대로 새 버전과 새 기능을 추가할 때 서비스 중단 없이 매끄럽게 업데이트되게끔 하는 걸 의미한다.Rolling, Blue-Green, Canary, Shadow 이렇게 총 4개의 전략을 찾아볼 수 있었고,그림자는 고려사항이 너무 많고, 카나리와 블루-그린은 유사해서 오늘은 롤링과 블루/그린에 대해 알아보고, 내 서비스에 알맞은 무중단 배포 방식을 고르고 적용해보자 Rolling전체 인스턴스를 한꺼번에 바꾸는 게 아니라, 조금씩 순차적으로 새로운 버전으로 교체하는 방식이다.일부 인스턴스만 업데이트되므로 전체 서비스가 중단되지 않는다. 업데이트 도중에 문제가 발생하면, 문제 있는 인스턴스만 롤백 가능하고 별도의 환경을 준비할 필요 없이 현재 인프라에서 순차적으로 배포 가능하다는 장점이 ..
2025.02.16
-
배포(2) 프로젝트에 적용된 CI/CD
원래 어제는 CI만 하려고 했는데 생각보다 간단해서 CD까지 했다.mysql, redis 연결까지 확인 완료 ! 일단은 Continuous Delivery까지만 끝냈다. (다음 글은 무중단 배포라는 뜻) github action으로 배포, 리소스 사용량은?우선 지난 게시글에서 살펴봤던 리소스 사용량부터 알아보자github action없이 배포했을 때는 cpu를 13% 사용했었는데, 4-5%만 사용하였다.역시나, 의존성 다운로드 과정을 하나도 거치지 않으니 네트워크 패킷 입력 개수도 눈에 띄게 줄었다.직접 배포했을 땐 66480이었는데.. 배포 시 입력량이 너무 적길래 좀 더 앞의 시간대도 살펴봤다.앞서 살펴봤던 지표는 이미 이미지를 다운로드 한 시점일거란 생각에서 찾아봤는데,2시 25분 도커이미지 다운..
2025.02.16
-
배포(1) CI/CD와 github action 알아보기
공부 시작https://www.redhat.com/ko/topics/devops/what-is-ci-cd CI/CD(CI CD, 지속적 통합/지속적 배포): 개념, 툴, 구축, 차이CI/CD는 애플리케이션의 통합 및 테스트 단계부터 제공 및 배포까지 애플리케이션 라이프사이클 전체에서 지속적인 자동화와 지속적인 모니터링을 제공하는 것을 뜻합니다.www.redhat.com우선 나는 이부분에 문외한이고 CI/CD가 정확히 어떤 문제를 해결했는지부터 찾아봐야한다. CI란 개발자가 코드를 변경할 때 마다, 자동으로 빌드와 테스트를 수행해 문제를 조기에 발견하는 과정이다.동시에 개발 중인 어플리케이션의 분기(브랜치)가 너무 많아서 상호 충돌할 가능성이 있는 문제를 해결해줄 수 있다. CD는 Continuous De..
2025.02.15
-
JWT: Redis에서 RefreshToken & BlackList 관리하기
왜 Spring security를 사용하지 않았는가?1. spring security의 구조에 대한 이해가 필요하다. 학습곡선도 분명히 존재한다. spring security를 사용하더라도, 그저 ‘사용’만 한다면 보안측에서 허술한 건 당연하기에 상당한 시간이 필요할 것이다.2. 구조에 대한 이해가 제대로 되지 않은 상태로 jwt 블랙리스트나, refresh token 저장 등을 하려면 개발에 소요되는 시간이 꽤나 지체될 것이다.3. 구현하고 싶은 기능 중에 spring security에서 커스텀하려면 어려운 기능이 존재하는데,JWT Payload 암호화(AES로 암호화된 Payload 처리하기)JWT Key RotationRedis 기반 블랙리스트모두 spring security에서 기본적으로 제공하진..
2025.02.13
-
ConfigurationProperties로 민감정보 관리하기
문제가 되는 상황TOKEN_TIME처럼 민감한 정보들이 하드코딩되어있다.설정 파일에서 관리해 줄 필요가 있었고, 모든 설정을 일일이 @Value 어노테이션으로 불러오면 코드가 복잡해질 것이다.이런 불편함을 해소해 주는 어노테이션이 @ConfigurationProperties이다. ConfigurationProperties스프링의 @ConfigurationProperties는 외부 설정 파일(application.properties나 application.yml)에 정의된 설정 값을타입 안정성이 있는 자바 빈인 POJO에 바인딩 해주는 어노테이션이다.단순히 문자열로 읽어오는 게 아니라, 정수, 불리언, 리스트 등 다양한 타입으로 변환해서 자바 객체에 담아준다.복잡한 설정 값을 계층적으로 매핑할 수 있어서..
2025.02.11
-
4. 운영체제 4장 스레드 동기, 비동기, 스레드풀
동기 스레딩 vs 비동기 스레딩동기 스레딩:부모가 자식 스레드를 생성하고 실행하는데, 자식이 끝날 때까지 기다려야 한다.데이터를 공유하면서 실행되고, 스레드 간 자원 공유가 가능하다.하나의 흐름이 끝나야 다음 작업이 가능해서 효율이 낮아질 수 있고 속도가 비동기에 비해 느리다. 비동기 스레딩:부모가 자식 스레드를 생성하지만, 기다리지 않고 바로 다음 작업을 수행한다.자식 스레드도 독립적으로 실행되며 서로 영향을 주지 않는다. 각각 따로 실행되므로 레이스컨디션을 방지 가능하다.멀티스레드 환경에서 동시 처리가 가능해 성능이 향상된다. 의문1: 동기 스레딩은 병행성과, 비동기 스레딩은 병렬성과 매칭되나?이벤트 기반 비동기 방식은 병행성도 제공한다! 1. 동기 방식public class SyncThreadExa..
2025.02.10
-
조회 성능 개선 작업 정리본
문제: 조회 성능이 매우 매우 느리다.초기 거래소 조회 속도: 36.8초1차 개선 후: 24.17초개선내용:1. tradeCount 집계테이블 생성2. tradeCount테이블의 count에 인덱스 생성(asc)3. 마켓status와 createdAt 복합인덱스 생성4. trade에 createdAt 인덱스 생성(desc) 문제점: 인덱스가 너무 많고, trade에 인덱스가 걸려있어 삽입 시 오버헤드 우려됨. trade는 삽입이 활발히 일어나는 항목이므로 해당 부분에 대한 개선 필요했음커서기반 페이지네이션 적용 후: 3.6초개선내용:1. 커서 기반 페이지네이션 적용2. 정렬 전략 별로 다른 cursor 사용, tie-breaker로 itemId 사용3. 조건에 따른 조회와 검색이 많이 일어나는 항목이므로..
2025.02.06
-
성능 개선 4편 & 트러블슈팅: 커서 기반 페이지네이션 + 전략 패턴
커서 기반 페이지네이션이란?데이터베이스에서 대량의 데이터를 효율적으로 탐색하기 위한 기법이다.커서 기반 페이지네이션은 특정 커서(정렬된 컬럼의 마지막 id값)를 기준으로 다음 데이터를 가져와서 인덱스를 탈 수 있어 성능 저하 없이 빠르게 데이터를 불러올 수 있다.기존 오프셋 기반 페이지네이션에서 오프셋이 커질수록 발생하는 성능 저하 문제나 데이터 중복/누락 문제를 효과적으로 방지할 수 있다. 물론 단점도 존재한다. 임의의 페이지로 바로 이동하기 어렵다는 점이다. 페이지 번호 대신 마지막 데이터의 커서를 사용하기 때문에, 사용자가 특정 페이지를 지정해서 바로 접근하는 기능을 구현하기 힘들다. 또 다른 단점은 구현 복잡도가 증가한다는 점이다. 정렬 기준이나 필터 조건이 다양해지면 커서를 통한 데이터 조회가 ..
2025.02.05
-
성능 개선 3편: Index 적용하고 비교분석하기
2025.02.03 - [팀 프로젝트/플러스 프로젝트] - 성능 개선 2편: Index 설계하기 (with Explain analyze, Explain) 성능 개선 2편: Index 설계하기 (with Explain analyze, Explain)인덱스 없이 조회, 얼마나 걸릴까?개선이 시급한 쿼리는 거래소/경매장 | 전체조회/인기아이템 이렇게 4개다.총 4개 쿼리의 실행속도를 우선 알아보자.hibernate 2차캐시는 사용하지 않고 있다.(defauroqkfchqh.tistory.com해당 글에서 이어집니다.요약하면 인덱스는 총 5개를 걸고,(bidderCount, trade createdAt, market/auction status-createdAt 복합인덱스, tradeCount)집계용 테이블(tr..
2025.02.04
-
트러블슈팅: queryDSL 중복집계, 비정상적으로 큰 count 문제(with only_full_group_by)
MySQL의 ONLY_FULL_GROUP_BY모드와(디폴트 설정),JPA/QueryDSL에서 아이템별 집계를 구현할 때 발생한 문제(groupby 중복 행, count 합계 뻥튀기)해결 과정을 정리한 문서입니다. 1. 문제 상황JPQLQuery query = queryFactory .select(new QMarketListResponseDto( market.item.id, market.item.name, JPAExpressions .select(market.amount.sum().coalesce(0)) .from(market) .where(market.item.id.eq(item.id)), ..
2025.02.02
-
3. 운영체제 3장 프로세스 간 통신
부모 프로세스와 자식 프로세스pid가 1인 프로세스(systemd)가 루트 부모 프로세스 역할을 하고, 새로 생성되는 프로세스들을 자식 프로세스라 한다.이 자식 프로세스들은 또다시 부모가 될 수 있으며 그 결과 트리를 형성한다. 부모 프로세스가 자식 프로세스를 생성할 때,1. 부모의 메모리 공간을 복사해 줄 수 있다. 전역변수, 힙, 스택 영역이 자식에게 그대로 전달된다. 하지만 복사된 후에는 부모와 자식이 독립적인 메모리 공간을 가진다.(변경해도 서로 영향 x)2. 자식 프로세스는 부모가 갖고 있던 환경변수를 그대로 상속받는다.3. file descriptor를 공유할 수 있다. 부모가 열린 파일을 자식도 동일하게 사용할 수 있다.4. IPC(파이프, 메세지 큐, 공유 메모리, 소켓)를 사용하면 부모가..
2025.01.30
-
2. 운영체제 3장 프로세스 기초, 컨텍스트 스위칭
프로세스 메모리 배치운영체제에서 프로세스가 실행될 때 메모리는 여러 영역으로 나뉘어 있다.코드와 전역 변수는 고정된 크기의 영역에 저장되고, 실행 중 생성되는 데이터는 동적으로 할당되는 힙과 스택에 저장된다.스택은 함수 호출과 관련된 정보가 저장되는 곳으로, 호출될 때 데이터를 push하고 끝나면 pop하면서 제거된다.이 때의 데이터를 "activation record"라고 하며, 함수 매개변수, 지역변수, 복귀 주소가 포함된다.마찬가지로 메모리가 동적 할당됨에 따라 힙이 커지고, 메모리가 시스템에 반환되면 축소된다. 정말 유명한 사이트 stack overflow이름의 유래가 이곳이다. 스택 메모리가 과도하게 커지는 것을 스택 오버플로우라고 하는데, 스택 오버플로우의 대표 예시로 순환 참조를 들 수 있다..
2025.01.29
-
Spring WebFlux를 활용한 HTTP메서드 처리 확장과 성능 테스트
로드밸런서 공부를 할 때 사용했던 코드를 가져와서 사이드 프로젝트를 만들고 있는데,현재 로드밸런서는 요청값을 처리하는 데에 한계가 있다.컨트롤러는 @GetMapping을 통해 오직 GET요청만 처리하도록 설계되어 있고,RequestProcessor는 내부적으로 HTTP요청을 처리하며 POST방식만을 사용하여, POST요청만 전송 가능하다. 다양한 HTTP메서드를 처리하려면 요청에 따라 다른 로직을 처리하는 추가 설계가 필요하다. 설계 방향성 잡기: 사용자 편의성을 고려하자!직관적으로 생각해봤을때, 클라이언트는 로드밸런서의 존재를 알지 못한다.사용자가 api를 호출할 때 마다 request에다 method도 입력해서 보내는 것 보다, api자체를 여러 개로 나누어 관리하는 것이 유저 입장에서 편리할 것이..
2025.01.26
-
apache jmeter로 부하테스트 해보기
2025.01.23 - [개인 공부용 프로젝트/loadbalancer.project] - 로드밸런서의 동시성 문제 해결을 위한 각종 플랜ㄴ이 글에서 이어집니다 이전 부하테스트가 왜 실패했는가를 생각해보았는데 그건 부하테스트가 아니었다초당 100건으로 부하테스트라니 내가 생각해도 웃기긴 하다그래서 오늘 상당한 과부하를 일으킬거기 때문에 내 노트북에서 테스트할 순 없고 이놈이 희생해야겠다도커에다 로드밸런서를 올리고,도커내부의 같은 네트워크 안에서 실행되기에 서버 주소도 로컬호스트에서 도커내부의 주소로 바꿔주었다인식이 잘 된다 바로 부하테스트를 진행해보자 오늘은 모두 같은 플랜으로 하기보다는, 부하를 점점 늘려서 한계치를 테스트 해볼 계획이다.우선 우리 도커가 튼튼하리라 믿고 초당 10만의 사용자를 보내보자1..
2025.01.25
-
로드밸런서의 동시성 문제 해결을 위한 각종 플랜
2025.01.17 - [개인 공부용 프로젝트/loadbalancer.project] - 직접 만든 로드밸런서로 다중인스턴스 관리하기지난 로드밸런서 글에서, synchronized와 atomic변수의 차이를 개념적으로 알아보았다면이번에는 concurrentHashMap과 threadLocal을 이용한 전략도 추가하고, 부하테스트를 진행해서 4가지 방법의 차이를 몸소 느껴보자 synchronizedpublic class RoundRobinSynchronized implements LoadBalancerStrategy { private int currentIndex = 0; @Override public synchronized String getNextServer(List healthySe..
2025.01.23
-
내 애기 로드밸런서가 드디어 숨을 쉬어요
https://github.com/roqkfchqh/loadbalancer GitHub - roqkfchqh/loadbalancerContribute to roqkfchqh/loadbalancer development by creating an account on GitHub.github.com10시간 걸렸다대충 깡통 스프링부트 프로젝트를 생성하고 헬스체킹용 컨트롤러 클래스 메서드를 추가한다근데 깡통으로 하는데 왜 10시간 걸렸냐면 아웃소싱 프로젝트로 실험하겠다고 욕심부렸다가 8시간날렸다리눅스놋북으로 환경이 바뀌어서 db쪽에서 계속 에러나서(알고보니까 이것도 ㅋ sql ddl auto설정 안 했었음 멍청이)깔끔히 포기하고 로드밸런서만 확인하는쪽으로 틀었다services: app1: containe..
2025.01.21
-
직접 만든 로드밸런서로 다중인스턴스 관리하기
로드밸런싱은 서버에 가해지는 부하(로드)를 분산(밸런싱) 해주는 기술이다. 클라이언트와 서버 풀 사이에 위치하며, 한 대의 서버로 부하가 집중되지 않도록 트래픽을 관리해서 각각의 서버가 최적의 퍼포먼스를 보일 수 있도록 해준다. ELB로 그냥 사용하면 되지만 어떻게 모르고 사용할 수 있겠는가 싶어서(사실 튜터님한테 과제받음 ㅋ) 직접 구현해보고, 어떤 식으로 흘러가는지 알아보도록 하자. 내가 구현할 로드밸런서는 모듈화된 단 하나의 로드밸런서고, 어떤 프로젝트에든 적용해볼수있는걸로 만들어보자.@Slf4j@Componentpublic class LoadBalancer { private final HealthCheckService healthCheckService; private int curren..
2025.01.20