목록전체 글 (108)
Kuma's Curious Paradise
이번에 한 서버에서 메모리와 디스크 사용량 관련 문제가 발생해 설정 변경을 진행했다. 그런데 막상 설정을 바꾸려다 보니, Dockerfile 안의 JVM 옵션들이 정확히 어떤 의미인지 제대로 이해하지 못하고 있다는 생각이 들었다. 그래서 이번 기회에 Dockerfile의 각 설정이 어떤 의미인지, 그리고 왜 JVM 메모리 설정을 조정해야 하는지 정리해보려 한다. 우선 이번 작업이 메모리 문제의 근본 원인을 완전히 해결한 것은 아니다. 다만 JVM이 컨테이너 안에서 사용할 수 있는 메모리 범위를 더 안전하게 제한해, 컨테이너가 갑자기 OOMKilled 되는 위험을 줄이는 방향으로 설정을 조정했다. 수정 대상 Dockerfile은 다음과 같다.FROM amazoncorretto:17-alpineENV TZ=..
2025년 3월, 나는 직업을 바꾸었다. 전 직장을 퇴사한 지 1년 반만에 일어난 일이었다. 이것이 워낙 큰 사건이었던 탓인지, 이전의 시간들은 조금 흐릿하게 남아 있다. 그럼에도 회고를 하자면, 내가 처음 개발을 시작하던 때를 떠올리지 않을 수 없다. 그때 세웠던 목표를 얼마나 달성했는지, 그 시절의 마음가짐은 지금과 어떻게 달라졌는지 살펴봐야 하기 때문이다. 다행히도 당시 참여했던 부트캠프에서, 수강생 상담용 질문에 답변을 적어 둔 기록이 블로그에 있다. 2023년 12월 12일의 글이다.입사할 때 내가 가장 바랐던 것은, 아주 추상적인 단어지만 ‘열기’였다. 사람들이 일에 얼마나 관심을 갖고 있는지, 서로에게 어떤 방식으로 영향을 주고받는지, 더 나아지기 위해 어떤 노력을 기울이고 있는지 같은 것..
📚 2025년 독서 시도 : 30권완독 : 18권중단 : 9권읽는 중 : 3권🥲 독서 저조 구간10월, 11월 : 더 이상 블로그를 쓰지 못하게 된 시기와 겹친다. 10월부터 거의 매일 무언가를 했다. 스터디 준비, 사이드 프로젝트, 집까지 들고오는 업무, 두 개의 독서 모임, 그리고 외주까지. 하루라도 비는 날이 생기면, 이상하게 너무 불안했다. 내가 쉬어도 되는 이유를 찾고, 그걸로 나를 설득하는 데만 오전 시간을 다 보냈다. 그러고나서 텅 비어버린 오후에는 생각없이 있고 싶어서 영상들을 봤다. 체인소맨, 불량연애, 흑백요리사... 다 재미있는 작품들이었다. 지금 생각해보면 필요했던 것은 그저 정리였던 것 같은데... 영상과 영상 사이를 건너다니며 도망만 쳤다. 이제 드디어 정리를 해 볼 시간. ..
김현우의 을 읽는 동안 여러 번 고개를 끄덕였다. 문장 하나하나가 마치 오래된 교훈처럼 들렸다. 함부로 공감한다고 하지 말라. 이해한다고 쉽게 말하지 말라. 맞다. 인간은 타인을 너무 쉽게 재단한다. 나 역시 얼마나 자주 "네 마음 알아"라고 말했던가. 그럴 때마다 나는 잠시나마 온화한 얼굴을 하고 상대의 세계를 이해했다고 착각했을지 모르겠다. 그러나 책을 덮고 나서 남은 것은 묘한 답답함이었다. 그렇다면 우리는 무엇을 할 수 있는가. 윤리의 문턱이 높아질수록 타인에게 다가가는 길은 멀어진다. 마치 담장 높은 집 앞에 선 것처럼. 초인종을 누르기가 망설여지고 나는 받아들여지지 못할 것 같다. 담장은 분명 필요하다. 누군가 내 집을 함부로 드나들지 못하게 막아준다. 하지만 동시에 그 벽은 내게 오는 길을..
지난번 글에서 circuit breaker의 구조에 대해서 살펴보았다. 이번 글에서는 WebClient에서 CircuitBreaker를 적용하는 방법과 Reactive(Flux/Mono) 환경에서 서킷 브레이커가 내부적으로 어떻게 동작하는지를 다뤄보려고 한다. 좀 두서없는 글이 될 수도 있을 것 같다. 1. webclient 사용 시 circuit breaker 적용하는 법WebClient로 외부 API를 호출할 때 서킷 브레이커를 적용하는 방법은 의외로 간단하다.아래와 같이 .transformDeferred() 안에 CircuitBreakerOperator를 추가해주면 끝이다.private final CustomCircuitBreaker customCircuitBreaker;public Mono get..
메인 페이지를 개발하다 보면, 여러 서버를 찔러서 한꺼번에 데이터를 가져와 합쳐야 하는 경우가 있다. 이들은 속도가 중요하기 때문에 Reactor 형식으로 구성되어 있다. 예를 들어, 메인 페이지에 필요한 메뉴가 4가지라면 다음과 같은 비동기 호출이 있을 수 있다. Mono fetchFirstMenu();Mono fetchSecondMenu();Mono fetchThirdMenu();Mono fetchFourthMenu();이때 결과를 합쳐서 TotalMenuResponseDto에 담아야 한다면 어떻게 해야 할까? 고민이 된다면 tupel과 zip(), flatMap() 등의 개념을 이해해야 할 때다. 1. Tuple이란 무엇인가?Tuple(튜플)은 수학에서 “순서가 있는 값들의 모음”이라는 뜻이다. T..
데이터베이스 테이블을 보다 보면 utf8mb4_unicode_ci, utf8mb4_general_ci 같은 낯선 문구를 종종 마주하게 된다. 이는 바로 collation을 의미하는데, 오늘은 collation이 무엇인지, 어떻게 사용되는지 등을 살펴보자. 1. Collation이란?Collation은 데이터베이스에서 문자열을 비교하고 정렬하는 규칙을 말한다.예를 들어, Apple과 apple을 같은 것으로 볼지, 다른 것으로 볼지는 collation에 따라 달라진다. 한글이나 특수문자 정렬은 어떻게 할지 같은 규칙 등도 모두 collation과 관계가 있다. Character Set(문자 집합): 어떤 문자를 저장할 수 있는가?예: UTF-8, ASCII, EUC-KRCollation(콜레이션): 저장..
좋아서 두 번 읽은 책이다. 아마 세 번을 읽어도 지루하지 않을 것 같다.작법에 대한 수많은 책들 중 단연코 눈에 띄는 책이다. 그러나 이 책을 덮을 때, 글쓰기보다는 삶을 더 오래 생각하게 된다. 좋은 에세이가 무엇인가를 묻는 동시에, 좋은 삶이 무엇인지를 묻기 때문이다. "논픽션의 페르소나는 대리인이 아니다. 논픽션 작가는 소설가나 시인이라면 거리를 둘 수 있는 변명과 낭패감을 공개적으로 드러내야 한다. 공공장소에서 소파에 드러눕는 거나 매한가지다." 소설가는 허구의 인물을 내세워 그의 그림자속에 숨을 수 있다. 시인은 목소리의 굴절 속에서 스스로를 가릴 수 있다. 그러나 논픽션 작가는 달아날 수 없다. 그는 자기 얼굴을 드러내야 한다. 낭패와 변명, 불편한 욕망과 자기 소외까지도. 그것은 마치 공..
1. 들어가며외부 API를 호출하며 장애 전파를 막기 위해 CircuitBreaker를 사용할 일이 생겼다. 적용 자체는 매우 쉽다.스프링 부트에서 제공하는 어노테이션 덕분이다. 예를 들면 서킷 브레이커를 적용하는 코드는 이렇게 생겼다. @CircuitBreaker(name = "externalApi", fallbackMethod = "fallback")public String getResult() { return restTemplate.getForObject("https://externalapi.com/data", String.class);}이렇게 어노테이션을 붙이면... 외부 API 실패율이 일정 수준 이상이면 호출 자체를 차단하고일정 시간이 지나면 일부 요청만 다시 시도해보고여전히 실패하면 ..
[문제 상황]- 사용자가 '현황_2025_07_27' 파일을 요청할 경우, S3에 이미 올라가 있는 파일을 지우고 새 파일을 다시 업로드한 뒤 파일 주소를 내려주는 로직을 작성함. - 그러나 새 파일이 아닌 이전 파일이 다운로드되는 문제가 생김. [결론]- cloudfront에 이전 파일이 캐시되어 있었음. - '현황_2025_07_27'이라는 파일명이 같으므로, cloudfront는 파일이 삭제된 것을 모르고 똑같이 이전 파일을 내려줌. - 해당 버킷 디렉토리의 cloudfront의 캐시를 0으로 만들어 캐시를 무효화 하도록 함. [대안]- 코드 레벨에서는 Cache-Control: no-store나 max-age=0 등의 헤더를 S3 업로드 시 설정할 수도 있음. - 또 다른 대안으로는 cloud..