전체 글 (67) 썸네일형 리스트형 왜 Redis는 Jemalloc을 쓸까? “레디스가 메모리를 어떻게 빌리고(allocate), 반납하고(purge), 조각을 줄이는지(defrag)”를 Jemalloc 관점에서 보기1) 왜 Redis는 Jemalloc을 쓰나요?단편화에 강하고 동시성 확장에 유리. 다수의 리눅스 빌드에서 기본 할당기로 사용. 다만 일부 ARM/임베디드 환경은 libc가 기본일 수 있음 → 실제 값은 INFO memory의 mem_allocator로 확인2) Jemalloc 내부 구조 핵심 🧩Arenas : 스레드들이 경쟁을 줄이도록 여러 ‘할당 풀’을 둡니다.Bins / Size classes : 크기 구간별 버킷(작은 할당은 bin에서 빠르게 처리)Tcache(스레드 캐시) : 스레드 로컬 캐시로 잠금 없는 초고속 할당, 대신 메모리 사용량이 약간 늘 수 있.. Redis 캐싱으로 DB 부하 감소시키기 1) 언제 캐시를 쓰면 좋은가? 🤔읽기 비율이 높고(Read-heavy), 데이터가 자주 안 바뀔 때동일 파라미터로 반복 조회가 많은 API (예 : 상품 상세, 코드, 마스터 데이터)응답 지연이 DB I/O 때문에 커질 때 (예 : 총 2k RPS, 캐시 히트 80%면 DB는 400 RPS만 처리)→ 이런 상황이면 Redis 캐시가 DB QPS를 (1 - HitRate)배로 줄여줌.2) 캐시 전략 한 장 요약 🧭가장 안전하고 흔한 전략은 Cache-Aside (Lazy Loading)조회 : 캐시에 없으면 DB에서 가져와 캐시에 넣고 반환쓰기/수정 : DB에 쓰고 관련 캐시를 무효화패턴 자세히 : Azure Architecture Center의 Cache-Aside 설명이 가장 깔끔 Microsof.. 데드락(Deadlock) 4대 조건 상호배제 (Mutual Exclusion)한 자원은 동시에 한 명만 쓸 수 있음예 : 한 포크는 철수나 영희 중 한 명만 잡을 수 있어요.점유하며 대기 (Hold and Wait)이미 자원 하나는 쥔 채, 다른 자원을 기다림예 : 왼손 포크 쥔 채 오른손 포크가 비길 기다려요. 비선점 (No Preemption)남이 쥔 자원을 빼앗을 수 없음예 : “잠깐만, 그 포크 강제로 뺏는 건 안 돼요.”환형 대기 (Circular Wait)A→B→C→…→A 식으로 서로 둥글게 기다림예 : 모두 왼쪽 포크만 들고 서로의 오른쪽 포크를 기다려요. 이 네 가지가 동시에 성립해야 데드락이 생겨요. 하나만 깨도 데드락은 안 생김어떻게 “하나를 깨서” 피하나요? (현업 포인트)상호배제 완화 : 읽기 전용/락프리 자료구조로 .. Logback/SLF4j 사용 이유 한 줄 요약코드는 SLF4J(리모컨)만 보고 말하고, 실제로 로그를 찍는 일은 Logback(TV)이 함. 그래서 TV를 바꿔도(Logback→다른 것) 코드는 거의 안 바꿔도 됨SLF4J는 로깅 Facade라서 코드가 구현체에 묶이지 않음. 서드파티가 JUL/Log4j/JCL을 써도 브리지로 한 채널로 모음. 또한 {} 파라미터 로깅과 MDC 덕에 성능과 추적성이 좋음. 구현체는 Spring Boot 기본인 Logback을 쓰면 Appender/MDC/Async/JSON 로깅까지 운영 기능이 기본 제공되어, 배포·관리가 쉬움왜 이 조합이 좋을까? (현업 포인트 5개)갈아끼우기 쉬움 : 내일 Logback 대신 Log4j2로 바꿔도, 코드는 SLF4J 그대로 (SLF4J는 ‘로깅 API’ 앞단 추상화 계.. 다국어 Papago API 연결 공식 사이트 설명도 좋음. 쉽게 따라하기1) 콘솔에서 키 발급네이버 클라우드에서 Papago Translation 사용 설정 → 애플리케이션 등록 → Client ID/Secret 발급2) 설정 (환경변수/설정파일)application.ymlpapago: base-url: ${PAPAGO_URL} client-id: ${PAPAGO_CLIENT_ID} client-secret: ${PAPAGO_CLIENT_SECRET}운영에선 실제 값은 환경변수로 주입3) WebClient Bean@Configuration@RequiredArgsConstructor@FieldDefaults(level = AccessLevel.PRIVATE)public class Config { @Bean WebClient pa.. Sentry + OpenSearch 로그 수집 왜 이렇게 하나요?Sentry : 예외·에러 알림과 이슈 그룹핑 자동화. (Spring Boot 스타터 + Logback 연동) OpenSearch : JSON 로그를 모아 검색/대시보드. (에이전트로 수집 or Logback에서 바로 전송)1) 의존성 추가 (Gradle 예시)dependencies { // Sentry (Spring Boot + Logback) implementation "io.sentry:sentry-spring-boot-starter-jakarta:8.19.1" implementation "io.sentry:sentry-logback:8.19.1" // JSON 로그 인코더 (Logback) implementation "net.logstash.logback:logstash.. Retry 시스템 만들기 왜 필요한가?네트워크 순간 끊김, 외부 API 일시 장애, DB 잠깐 과부하… 이런 일시적(Transient) 오류는 “조금 있다 다시” 하면 종종 해결...이걸 자동으로 해주는 게 Retry. 단, 영구적(Permanent) 오류는 다시 해도 안됨 (예: 잘못된 파라미터)재시도 대상만 고르는 게 핵심1) 기본 원칙대상 선별 : 재시도할 예외만 고르기 (네트워크 타임아웃, 429/503 등). 재시도해도 소용없는 예외는 제외Backoff + Jitter : 점점 기다리는 시간 늘리기(Exponential Backoff) + 최대 대기 시간(cap)서버 힌트 존중 : HTTP 429에 Retry-After 있으면 그만큼 쉬었다 재시도Idempotency : 같은 요청을 여러 번 보내도 한 번만 처리되게 키.. 실무형 Global Exception Handler 만들기 (ErrorCode Enum + 국제화 + 로그 시스템까지) * 에러 응답 표준(Contract)부터 결정클라이언트와 약속이 제일 중요 { "timestamp": "2025-08-19T12:34:56.789Z", "path": "/api/v1/orders", "status": 400, "code": "ORD_001", /** 비즈니스 오류 식별자(사내 표준) **/ "message": "잘못된 주문 요청입니다.", /** 사용자 노출용(i18n 적용) **/ "errors": [ /** 바인딩/검증 상세 **/ {"field": "quantity", "reason": "must be greater than or equal to 1"} ], "traceId": "a1b2c3d4e5f6" /** 로그 추적(MDC)과 연결 **/}1) ErrorCo.. 이전 1 2 3 4 5 ··· 9 다음