안녕하세요.
멘토링을 하면서 주니어 개발자들이 어려워 하는 개념들에 대해 어떻게 하면 쉽게 전달할 수 있을지에 대해서 많은 고민을 하고 있는 푸(Foo)라고 합니다.
잘 부탁 드리겠습니다.
이력
2019. 08 ~ 현재 : 카카오 자바 백엔드 개발자
2021. 08 ~ 현재 : programmers 백엔드 데브코스 멘토
2021. 12 ~ 현재 : F-Lab 자바 백엔드 멘토
책
이것이 취업을 위한 백엔드 개발이다 with 자바(링크)
기타 이력 및 타 플랫폼 강의들은 아래 GitHub 링크에서 확인할 수 있습니다.
GitHub - https://github.com/lleellee0
Courses
Reviews
- Building Robust Systems That Tolerate Failures
- Resilience4j - CircuitBreaker for creating fault-free services
- Super easy portfolio distribution
- Building Robust Systems That Tolerate Failures
- Log Management Required for Developers
Posts
Q&A
데이터 버저닝 질문
HAHA님 안녕하세요~우선 강의 잘 봐주시고, 좋은 질문 남겨주셔서 감사합니다. 날카로운 질문이네요. ㅎㅎ 단순히 이벤트 버전과 데이터베이스 버전을 비교해서 다르면 무시하는 방식만으로는, 동시에 발생하는 '동일한 상품에 대한 진짜 서로 다른' 재고 감소 요청 중 뒤에 발행되는 요청이 유실되는 문제가 발생할 수 있습니다.이 문제는 동일한 이벤트의 '중복 처리'를 막는 멱등성 문제와는 다른, 여러 유효한 요청이 경합하는 동시성 제어의 문제입니다. 문제 상황: 유효한 주문의 유실말씀하신 시나리오를 흐름으로 정리하면 다음과 같습니다.초기 상태: 상품 A의 재고는 10개, 데이터베이스(DB)의 버전은 5입니다.주문 1 발생: 프로듀서가 상품 A의 정보(버전 5)를 읽고, 재고 감소 이벤트(A)를 발행합니다.주문 2 발생: 거의 동시에, 아직 주문 1의 이벤트가 컨슈머에 의해 처리되기 전에, 다른 프로듀서가 상품 A의 정보(여전히 버전 5)를 읽고, 재고 감소 이벤트(B)를 발행합니다.컨슈머 처리:이벤트 A가 먼저 도착합니다. DB 버전(5)과 이벤트 버전(5)이 일치하므로 재고를 9로 감소시키고, DB 버전을 6으로 업데이트합니다. (성공)이벤트 B가 도착합니다. 이벤트에 담긴 버전은 5이지만, 현재 DB 버전은 6입니다. 버전이 다르므로 컨슈머는 이 요청을 무시합니다. (실패 및 유실)이 경우, 분명히 유효한 주문이었던 '주문 2'가 그냥 무시되어버리는 문제가 발생합니다.(이걸 물어보신게 맞겠죠? ㅎㅎ) 이 문제를 해결하려면 컨슈머의 로직이 더 정교해져야 합니다. 이 문제를 해결하는 가장 좋은 방법은 고유 ID를 사용한 멱등성 처리와 버전을 사용한 동시성 제어를 모두 적용하는 것입니다. 1단계: 멱등성 키(Idempotency Key)로 중복부터 확인모든 이벤트는 eventId나 orderId와 같이 절대 중복되지 않는 고유 ID를 가져야 합니다.컨슈머는 로직을 시작하기 전에, "이미 처리한 ID인지"를 별도의 processed_events 같은 테이블에 확인(INSERT 시도)합니다.만약 ID가 이미 있다면? → 이것은 '진짜 중복' 이벤트입니다. 즉시 처리를 중단하고 무시합니다. 이 단계에서 실제 중복 문제는 완벽히 걸러낼 수 있습니다.2단계: 버전으로 동시성 충돌 확인ID가 처음 들어온 것이라면? → 이제 이것은 '중복'이 아닌 '정상' 이벤트(순서가 밀렸을 수는 있는)임이 보장됩니다.이 상태에서 이전 답변에서 설명한 버전 비교 로직을 수행합니다.버전 일치: 첫 처리이므로 재고를 감소시킵니다.버전 불일치: 다른 정상 주문에 의해 순서가 밀린 것이므로, 현재 DB 상태를 기준으로 재고를 재확인하고 업데이트를 재시도합니다. 이러한 'ID로 중복을 먼저 거르고, 버전으로 순서를 제어하는 방법'을 통해, 질문해주신 상황에 대해 데이터 정합성을 지킬 수 있을겁니다. 본 영상에서는 동시성 제어보다는 장애 상황으로 인해 재시도 되는 등 중복 발행된 데이터에 대해 멱등성이 있는지에 포커스를 맞춰서 강의에서 이야기 한 것처럼 설명되었습니다! 이 질문글은 강의 노트에도 링크 추가해두겠습니다~혹시 또 궁금한 내용 있으면 질문 남겨주세요~!감사합니다!
- 1
- 2
- 26
Q&A
배포에대한 질의..
이경용님 안녕하세요~몇가지 방법이 있긴한데 혹시 DB 비밀번호 등 GitHub로 노출되지 않았으면 좋겠는 값(Secret 이라고 부릅니다)이 있어서 그런걸까요? 어떤 의도냐에 따라 방법이 달라질 것 같습니다~! 만약 수동배포 그 자체를 하고 싶으신거라면 로컬 개발환경에서 package 하여 jar 파일을 생성한 후 scp 등 명령어로 직접 서버에 업로드하여 실행시키는 방법도 가능합니다. 그게 아니라 Secret을 숨기고 싶은거라면,서버에 환경 변수를 설정해주거나Jenkins 등에서 배포할 때 스크립트로 주입시켜 주거나Vault 같은 시크릿 저장소를 활용하거나쿠버네티스(K8s) 같은걸 사용한다면 클러스터 내부의 Secret을 활용하는 방법 등 다양하게 있을 것 같습니다.혹시 어떤 의도인지 이야기해주시면 추가적으로 답변 드리겠습니다!
- 1
- 1
- 20
Q&A
안녕하세요 무중단 배포에대해 질문드립니다.
이경용님 안녕하세요!우선 강의 잘 봐주셔서 감사합니다. ncp나..ec2도 같은 원리일까요?-> 넵 동일하게 VM(가상 머신)을 클라우드 서비스를 이용해 생성하면 리눅스 운영체제가 설치되어있는 서버가 생성되는거고, 거기에서 우리가 실행시키고 싶은 자바 애플리케이션을 실행시키는겁니다. Blue-Green, Rolling Update이것을 좀 깊게 학습하고싶은데 추천해주실만한 학습자료가 있을까요?-> 해당 개념 자체를 깊게 학습할만한 자료는 저도 잘 모르겠네요 ㅎ... 각각의 개념은 꽤 심플한 개념입니다. 차라리 CD(지속적 배포) 그 자체에 대해 학습하시면 어떨까 생각되는데, 그런거라면 https://product.kyobobook.co.kr/detail/S000217112008 이 책도 괜찮을 것 같습니다. 또 만약에 리액트나 별도의 프론트를 추가할경우?서버 3개가 아니라.. 4개가 되는지 궁금합니다.-> 이건 구성하기 나름인데, 같은 서버에 올리는 것도 가능합니다. (스프링 부트 애플리케이션에 리액트 프론트엔드를 포함하는 것도 가능하고, 서로 다른 포트로 프론트엔드 서버를 띄우는 것도 가능) 다만 프론트엔드 개발, 유지보수 과정에서 백엔드 서버가 영향을 받지 않는게 더 유리하기 때문에 통상적으로 분리하여 운영하는게 일반적입니다. 따라서 서버 숫자가 더 늘어난다고 보셔도 될 것 같습니다! 궁금하신 내용에 대한 답변이 됐을까요? 궁금한 내용 있으면 추가로 질문 남겨주세요.감사합니다. :)
- 1
- 2
- 37
Q&A
수강 추천
이진아 님 안녕하세요!만약 배포 경험이 없으셨다면 다음 강의 먼저 수강해보시는걸 추천드립니다!포트폴리오 초간단 배포하기 https://inf.run/My8ci 스프링 부트 애플리케이션 베이스로 만들어진 강의인데, 아마 지금 강의보다 훨씬 쉬울겁니다.혹시 이전에 개발 경험 적어주시면 좀 더 타겟해서 다른 강의 추천드리겠습니다. :)
- 1
- 2
- 24
Q&A
복제 관련 질문입니다!
오래 기다리셨습니다. 일반적으로는 Primary-Replica 간의 복제 지연이 크게 문제가 되진 않지만, 만약 신경 써야하는 상황이라면 근본적인 DB 복제 지연 시간 줄이기 '방금 글 쓴 사용자(시스템)'의 읽기 요청은 Primary DB로 보내주기위 2가지 방법이 함께 적용되면 좋을 것 같습니다.1번은 복제 지연 시간을 줄여 가급적 복제 지연으로 인한 데이터 불일치가 발생하지 않도록 하는겁니다. 방법은 여러가지겠지만, DB 서버들의 사양을 올리고 쿼리 튜닝, 병렬 복제 등 다양한 수단을 활용하면 됩니다. 다만 이 부분은 백엔드 개발자보다는 DBA 레벨에서 다뤄야할 내용들 인 것 같아요. 그럼 2번은 복제 지연이 발생하면 안되는 요청과 아닌 요청을 구분하여 복제 지연이 발생하면 안되는 요청에 대해선 읽기 연산도 Primary에서 이루어지도록 하는겁니다. 이 때에는 당연히 사용자나 시스템을 구분할 수 있는 Key를 두어 구분해야하고, 시스템마다 공유할 수 있게 Redis 같은 공유 저장소를 활용해야합니다.그리고 스프링 부트 애플리케이션 기준으로 DataSource 를 Primary와 Replica 양쪽에 대해 설정해주고, 요청에 따라 읽기 연산이지만 Primary로 연결해야할 요소를 구분해줘야합니다. AOP를 활용하면 좋겠죠?다만 이렇게 설정하는게 정말 우리 시스템에 필요한지 검토해볼 필요가 있습니다. DataSource 설정이 두개가 되는 것도 설정의 복잡함을 만들고, 일반적으로 Primary-Replica 구조에서 사용하는 DB Proxy를 활용한 자동 Failover가 동작하지 않을 수도 있습니다. 애플리케이션 레벨에서 Failover를 직접 처리해줘야할 수도 있어요. 이런 불편함을 감수할 필요가 있는지 검토가 필요합니다. 제가 대략 알고있는, 경험해본 내용은 이정도인데 답변이 됐을까요? 추가적으로 궁금한 내용 있으면 질문 남겨주세요~ :)
- 1
- 2
- 67
Q&A
복제 관련 질문입니다!
공부맛있다님 안녕하세요! 좀 더 구체적으로 복제 지연 때문에 어떤게 문제가 되는지 이야기 해주시면 저도 같이 고민해볼 수 있을 것 같습니다~DB 레벨에서의 복제 지연에 대한 내용일까요~?어쩌면 CAP 이론에 대한 내용 읽어보시면 궁금하셨던 내용을 해소하거나 좀 더 구체화시켜서 질문주실 수 있을 것 같습니다!한번 확인해보시고 마저 질문 남겨주세요~
- 1
- 2
- 67
Q&A
현업에서 서킷브레이커 상태 전파를 할 때 Actuator를 사용 하시는지 궁금합니다!
드루와라잇님 안녕하세요~다른 인스턴스들로 서킷 브레이커의 상태를 전파하기 위해서는 Kafka 같은 메시지큐나 Spring Cloud Config 같은 분산 설정 관리 도구를 사용합니다. Actuator는 특정 인스턴스의 서킷 브레이커 상태를 확인하거나 강제로 변경하기위해서는 활용할 수 있지만, 상태 전파가 목적이라면 메시지큐나 분산 설정 관리 도구를 활용하는게 좋습니다~ 서킷 브레이커 상태를 전파하는 상황에 대해 경험을 이야기 드리자면, '추천' 로직을 수행하기 위해 여러 머신러닝, 딥러닝 모델을 호출하곤 하는데요, 일부 모델이 높은 부하를 받아서 응답이 느려지거나 분석에 실패하는 경우 해당 모델로 가는 서킷을 OPEN 시키는 상황이 있었습니다. 궁금하셨던 내용에 대한 답변이 됐을까요?또 궁금한 내용 있으면 질문 남겨주세요.감사합니다.
- 1
- 1
- 34
Q&A
@Transactional선언 메서드 정상동작하는건가요?
후아휴님 안녕하세요!해당 내용은 제가 예제 코드를 제미나이로 생성하면서 의도와 다르게 작성된 부분입니다!(Self Invocation이 아니라 public 되어 있어 외부 호출을 가정하여 이렇게 작성된듯합니다)이 부분은 강의 흐름에서 주요하게 소개되는 내용은 아니지만, 혼란을 드릴 수도 있는 내용이라고 생각되어 강의 예제 코드에 주석으로 보충 설명과 이 질문글 링크를 남겨놨습니다.제보해주셔서 감사하고, 수강에 불편을 드려서 죄송합니다. (_ _)
- 1
- 2
- 54
Q&A
영상 편집이 잘못된 것 같아요. (순서가 중간에 계속 바뀜)
말씀하신대로 영상 편집본 중 일부가 중복으로 포함되어있었습니다.이 부분 수정하여 다시 업로드 했습니다. 🙂오류 제보해주셔서 대단히 감사합니다!!
- 0
- 3
- 45
Q&A
영상 편집이 잘못된 것 같아요. (순서가 중간에 계속 바뀜)
dongbin-yoon님 안녕하세요!제가 지금 바로 확인해보고 조치 및 답변 드리겠습니다.수강에 불편 드려 죄송합니다. (_ _)
- 0
- 3
- 45