codevillain
@codevillain
Students
1,780
Reviews
111
Course Rating
4.9
19년차 백엔드 개발자
Kakao (2018 ~ 2024, 前 리더)
LF (LG Fashion, 2017, IT 플랫폼팀 차장)
쿠팡 (2013~2017, Sr. Software Engineer)
오픈소스 개발자 대회 은상 (2012. 지식경제부, NIPA)
주요 분야
Java, Spring, MSA 환경에서 오랜 시간 일을 하였습니다. 대용량 데이터 처리 및 마이크로 서비스 아키텍쳐 설계, 복잡한 도메인의 엔티티 설계 경험과 팀을 이끌어본 경험을 통해 기술적 지식과 10년 이상의 면접관 경험을 통해 인터뷰를 준비하는 방법과 커리어의 로드맵 방향을 잡는데 도움을 드리고 싶습니다.
강의 경력
2024.11 대구대학교 경산이노베이션 아카데미 취업 특강
2024.10 한빛미디어 주니어 개발자를 위한 취업 세미나 2차 특강
2024.09 부산대학교 SW융합교육원 취업 특강
2024.04 한빛미디어 주니어 개발자를 위한 취업 세미나 특강
저서 (개발자 기술 면접 노트, 한빛미디어, 2024.03)
교보문고 실시간 검색 1위 (2024.04.07)
Courses
Reviews
- Solving asynchronous architecture using RabbitMQ in one go
polynomeer
·
Solving Developer Job Seeking and Changing Jobs in One Go: Tips from a Senior Interviewer [Practical Guide]Solving Developer Job Seeking and Changing Jobs in One Go: Tips from a Senior Interviewer [Practical Guide]- Solving asynchronous architecture using RabbitMQ in one go
gguu
·
Solving Developer Job Seeking and Changing Jobs in One Go: Tips from a Senior Interviewer [Practical Guide]Solving Developer Job Seeking and Changing Jobs in One Go: Tips from a Senior Interviewer [Practical Guide]- Solving asynchronous architecture using RabbitMQ in one go
Posts
Q&A
step 4 - fanout 관련 질문
안녕하세요. 수강자님 1번부터 답변드리면, 예제 구조만 놓고 보면 Topic이 더 좋은 선택지입니다. 다만 step4에서 Fanout을 사용한 이유는 동작 방식에 대한 설명 (하나의 메시지를 모든 구독자에게 브로드 캐스트 하는 pub/sub의 가장 기본적인 형태)을 구현하고자 하는 측면과 실무에서 같은 뉴스 메시지를 처리하더라도 각 Consumer가 다른 로직으로 처리 해야 할 경우 (예를들면 1번은 DB에 저장, 2번은 푸시 알림, 3번은 로직 처리 등) Fanout을 통해 동일한 메시지를 받아 후작업을 처리할 수 있다는 점 이렇게 두가지 측면을 고려에서 비슷한 형태의 메시지에 대해 서로 다르게 처리하는 다수의 consumer 로서 fanout 브로드캐스팅을 지정한거라고 보시면 됩니다. Step 4 예제는 뉴스레터라는 시나리오를 빌렸지만, 실제로 보여주고자 하는 것은 Fanout Exchange의 브로드캐스트 동작 방식입니다. 2번의 경우 pub/sub의 특징중 하나는 구독자 중립성입니다. Consumer 중 하나가 장애가 나도 나머지 컨슈머는 영향을 받지 않으나 이걸 하나로 합치면 장애시 모든 뉴스처리가 중단되거나 트래픽 폭증으로 인해 지연이 발생할 때 전체 어플리케이션에 영향을 줍니다. 이런 독립성과 확장성 (하나의 타입이 추가되면 consumer만 추가 바인딩)을 고려해 서로 영향을 덜주고 처리가 보장되는 간단한 형태의 예제인 뉴스레터로 설명하였고, 말씀하신 방식도 동작은 합니다. 다만 메시지 처리 실패시 영향 범위, consumer 내부 분기 로직, 독립적 스케일링 등을 고려하면 큐를 분리하는 것이 운영 측면에서 이점이 있습니다.단계별로 예제를 연결하다보니 예제 성격이 부족한거 같습니다만, 메시지 처리 실패시 영향 범위나 consumer 내부 분기 로직 (메시지 타입에 따라 파싱 및 판단 분기)을 고려, 독립적인 스케일링 (특정 뉴스만 트래픽이 폭증할때) 등을 고려하면 Fanout 으로 연결하고 consumer의 워커를 늘리는 등의 일관성이나 유연성을 장점으로 볼 수 있습니다.또한 단일 큐 자체는 모니터링할 때도 상태구분이 fanout 보다 어렵습니다. 큐의 격리 레벨에서 장애나 독립 스케일링, 모니터링 이런 점을 고려할 때 fanout이 적합하다라고 보시면 되겠습니다.감사합니다.
- 0
- 2
- 35
Q&A
동적 큐 이름 설정 방법 및 SimpleRabbitListenerContainerFactory의 재정의에 따른 Retry 설정 미적용 관련 질문입니다.
안녕하세요. 수강자님 동적 큐 네임 바인딩과 관련해서는 SpEL도 동작은 하겠으나 (저도 테스트는 안해봤습니다) 제가 이해한 질문은 동적 큐 바인딩을 통해 브로드 캐스트 하는 방식이 맞는지 물어보신거 같습니다. @Configuration public class RabbitMQConfig { // Bean으로 큐 이름 저장 (한 번만 생성) @Bean public String dynamicPublishNotificationQueueName() { return PUBLISH_NOTIFICATION_QUEUE + ":" + UUID.randomUUID().toString(); } @Bean public Queue publishNotificationQueue( @Qualifier("dynamicPublishNotificationQueueName") String queueName) { // 주입받아서 사용 return new Queue(queueName, false, true, true); // durable=false, exclusive=true, autoDelete=true } @Bean public FanoutExchange publishNotificationExchange() { return new FanoutExchange(PUBLISH_NOTIFICATION_EXCHANGE); } @Bean public Binding publishNotificationBinding( Queue publishNotificationQueue, FanoutExchange publishNotificationExchange) { return BindingBuilder .bind(publishNotificationQueue) .to(publishNotificationExchange); } } @Component public class NotificationSubscriber { @RabbitListener(queues = "#{@dynamicPublishNotificationQueueName}") public void consumePublishNotificationMessage(Notification notification) { notificationService.publishNotification(notification); } }이런식으로 작성해서 3개의 인스턴스를 바탕으로 테스트 해보시고, 로깅을 추가해서 테스트 해보시면 좋을거 같습니다. 두번째 질문의 retry 관련해서는, SimpleRabbitListenerContainerFactory 를 수동으로 정의하고 RabbitListenerContainerFactoryConfigurer.configure 를 별도로 핸들링하지 않으면 Spring boot의 property가 작동하지 않는다고 않는다고 알고 있습니다. 아래의 코드를 보시고 테스트를 한번 해보시기 바랍니다. @Bean public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory( ConnectionFactory connectionFactory) { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); // configurer.configure()를 호출하지 않음! // YAML 설정이 전혀 적용되지 않음 return factory; }이 코드는 아래와 같이 정의할 수 있습니다.@Bean public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory( ConnectionFactory connectionFactory, RabbitListenerContainerFactoryConfigurer configurer) { // ⭐ 주입 SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); // Boot 설정 먼저 적용 configurer.configure(factory, connectionFactory); // 추가 커스터마이징 (Boot 설정 덮어쓰기) factory.setDefaultRequeueRejected(false); factory.setMessageConverter(myCustomConverter()); return factory; }configurer의 configure 에 래빗팩토리와 커넥션 팩토리를 통해 application.yml의 설정을 반영해야 합니다. 요건이나 환경이 정확하지 않아서 다소 상세하게 답변 드리기 어려운 점 참고하시기 바랍니다.
- 0
- 1
- 74
Q&A
RabbitMQ 익스체인지 질문
안녕하세요 수강자님. 질문하신 내용이 정확합니다. Direct exchange에 해당하는 내용인데 제가 착각하고 잘못 설명했네요. 강의 자료 수정하겠습니다. 좋은 내용 알려주셔서 정말 감사드립니다.
- 1
- 3
- 69
Q&A
강의 자료 관련
안녕하세요. 수강자님. 2강에 강의자료 공지가 있었는데 못보셨나봅니다. https://2dell.notion.site/RabbitMQ-1792d6475f85808eaf95c4b66b4bf7dc?pvs=4 참고하시기 바랍니다. 강의 수강해주셔서 감사드립니다.
- 0
- 2
- 67
Q&A
지원서 작성 가이드와 샘플이력서 살펴보기 강의질문
안녕하세요. 수강자님포트폴리오는 한장에 하나의 프로젝트가 다 들어가도록 핵심을 정리해서 보여줘야 합니다.물론 신입일 경우 많은 내용을 보여주고 싶은 마음이 있겠으나, 서류를 검토하는 입장에서는 내용이 많다고 더 보지도 않고 오히려 서류가 많아져서 정작 중요하게 부각되어야 할 내용이 보이지 않는 경우가 많습니다.따라서 이력서와 마찬가지로 단순하고 명확하게 작성하는게 중요합니다. 경력직인 경우 포트폴리오는 필요없습니다. 경력기술서에 자세히 적으면 되고, 본인이 직접 한 업무라면 그에 따른 설명도 지원하고자 하는 회사의 업무 방향에 맞게 작성해서 어필해야 합니다. 연관관계가 있다면 더욱 좋겠죠? 무료편에는 회사 공고 분석이 다소 적은 분량으로 올라가있습니다만, 채용 공고를 분석해서 그에 맞는 방향으로 이력서를 수정해서 제출해야 합니다. 참고하시기 바랍니다.
- 0
- 2
- 88
Q&A
인증 에러
안녕하세요. 메시지 에러 자체는 RabbitMQ의 인증 에러 인데요, 도커 ps와 log를 확인해보시고, management 에 접근해보시기 바랍니다. (admin/admin으로 http://localhost:15672에 접근되는지) 원래 기본 계정은 guest/guest 입니다. 강의에 나온대로 RabbitMQ를 먼저 설치한 뒤 테스트 해보시고 제대로 된다면 도커 설정의 문제이므로 (로그나 권한 실행 타이밍으로 인한 에러)일 이 부분을 체크 먼저 하시고 범위를 줄여오류 사항을 예측해봐야 합니다.구글에서 docker rabbitmq access reused error 로 검색했을때 위에 언급한 문제들의 해결방법이 나오므로 참고해보시되, 먼저 어드민 콘솔 부터 접근 되는지, 계정이 맞는지 부터 점검 해보시기 바랍니다. 감사합니다.
- 0
- 2
- 72
Q&A
RabbitMQ에서의 트랙잭션 메시징 질문
안녕하세요. 수강자님 DB와 RabbitMQ같은 메시지 브로커의 트랜잭션은 서로 독립적입니다.그래서 RabbitMQ에서 트랜잭션을 구현하려면 DB와는 별도로 자체에서 처리하는 방식으로 "처리는 가능" 합니다. 19강 자료에 나와있는데, amqp-client에 의존성 (starter-amqp에 포함)channel.txSelect():트랜잭션 시작. 이후 모든 메시지 전송 작업은 이 트랜잭션 내에서 실행.channel.txCommit():트랜잭션 커밋. 모든 작업이 성공적으로 수행되었음을 RabbitMQ에 알림.channel.txRollback():트랜잭션 롤백. 트랜잭션 내 작업을 무효화하고 변경사항을 되돌림.이 방식으로 처리는 가능합니다만, 아시다시피 메시지큐는 비동기 환경에서 분산 메시징을 처리하는데 탁월한 미들웨어이기 때문에 이 방식으로 굳이 트랜잭션을 구현하는게 의미있나? 라는 관점에서 보면 구현 비용대비 실효성이 떨어지는 편입니다따라서 19강에서 설명하는 바와 같이 Outbox 패턴(db에 별도로 저장 한 뒤 다른 프로세스를 통해 메시지 처리)이나 TCC와 같은 형태의 재시도와 보정을 통한 멱등성을 보장하는게 훨씬 업무적으로는 좋은 선택이라고 판단합니다. 완강이 얼마 남지 않으셨네요. 마무리 잘 하시기 바랍니다. 감사합니다.
- 0
- 2
- 97
Q&A
기술분석 - 배포시스템을 구축해야한다면? 부분은 강의가 제공되지 않는건가요?
안녕하세요. 수강자님빌드 배포 관련 사항은 제가 임의의 시나리오를 통해 CI/CD를 개발한다면 어떻게 아케텍처를 분석해서 적용할 수 있는가를 가상으로 설정해서 설명해보려고 넣었습니다만, 중요도에 비해 강의 분량이 다소 과하고 면접에서 필요한 부분의 개념은 강의 자료에 나온 키워드만 이해하셔도 무리없겠다 생각해서 생략 했습니다.해당 설명이 19강에서 다시 언급은 되었는데, 목차에서 관련 내용을 업데이트 하질 못했네요. 혼란을 드려 죄송합니다.블루그린/카나리 배포 정도의 차이와 특징 등을 이해하시면 되는데 여기에 더해서 배포 시스템을 개발 할 때 분석하고 적용해야 할 기능들을 정리하는건 기술면접에 큰 도움은 안될거 같아 강의를 듣는 입장에서 효율상 시간 부담을 덜어 드리고자 과감히 생략했으니 양해 부탁드립니다. 감사합니다.
- 0
- 2
- 66
Q&A
Nginx와 로드밸런서의 관계
안녕하세요. 질문 알람을 제때 못받아서 답변이 다소 늦어진 점 죄송합니다. 강의에서 언급한 Nginx를 통해 부하분산을 한다와 이후에 로드 밸런싱 기법에 대해서 바로 설명을 이어서 하였습니다. 웹 서버 자체의 로드 밸런싱을 통해 부하분산을 할 수 있다고 이해하시면 되겠습니다.장표의 그림상으로는 별도의 로드밸런서 장비가 있었으나, 없을 경우 웹 서버들로도 충분히 로드밸런싱을 구성할 수 있다는 내용입니다. 감사합니다.
- 0
- 1
- 91
Q&A
안녕하세요 "섹션2 8. Consumer간 작업 분배" 에서 질문 있습니다.
안녕하세요. 수강자님 컨슈머가 붙은 상태에서 정상적으로 메시지 큐에서 컨슈머에 전달 되면 정확하게는 처리중인 상태입니다.내부에서 따로 설정한 로직 (여기서는 슬립 후 처리) 이후 소진이 완료되고 ack 가 호출되고 이때가 소진이 완료된 시점이 됩니다. 로그가 빨리 올라와서 구분이 어려울 수 있으니 초 단위로 대기를 준 부분이 아직 처리가 안된 상태이고, 이 후에 메시지가 출력된 이후에 ack 가 전달되면 소비가 완료된 상태입니다.해당 강의는 메시지의 전달과 처리, 처리 완료 후 프로세스를 설명한 것이므로 초 단위 처리하는 부분이 실제 비즈니스 영역의 로직을 대체해서 소진 완료 이전에 로직을 실행하고 실행 후 act 가 날라가고 처리완료(소진완료) 된다고 이해하시면 됩니다. 감사합니다.
- 0
- 2
- 78






![Thumbnail image of the Solving Developer Job Seeking and Changing Jobs in One Go: Tips from a Senior Interviewer [Practical Guide]](https://cdn.inflearn.com/public/courses/334899/cover/aa860a68-f4f2-4554-91bb-2dd48b47f14d/334899.png?w=148)