
1. Signal의 본질
Django signal은 “특정 이벤트가 발생했을 때 연결된 리시버(receiver) 함수들을 호출하는 Pub/Sub 구조”
- 발신자(sender): 이벤트를 발생시키는 쪽 (예: post_save, post_delete, 혹은 custom signal)
- 수신자(receiver): 그 이벤트에 반응해서 실행되는 함수
즉, 결합도를 낮추고(Decoupling) 이벤트 기반 처리를 할 수 있게 해줍니다.
- 시그널을 쓰지 않는다면 → 뷰나 모델 안에서 직접 함수를 호출해야 하므로, 코드가 점점 강하게 얽히고 변경에 취약해짐.
- 시그널을 쓰면 → 한 앱에서 이벤트가 발생했을 때 다른 앱이 알 수 있음. (예: user_deleted → CRM, 결제앱, 알림앱 등에서 반응 가능)
2. 언제 시그널을 쓰는 게 적합한가?
- 적합할 때
- 여러 앱이 동일한 이벤트를 다르게 처리해야 할 때 (회원가입 시 → 알림 발송, CRM 적재, 추천시스템 등록 등)
- 특정 이벤트가 “확장”될 가능성이 클 때 (추후 새로운 앱에서 같은 이벤트를 구독할 수 있음)
- 도메인 계층을 깔끔하게 유지하고 싶을 때 (User 앱은 탈퇴 이벤트만 발생시키고, CRM은 자기 관심사만 처리)
- 적합하지 않을 때
- 오직 한 앱 안에서만 쓰이고, 이벤트가 다른 곳과 연계되지 않을 때
- 뷰(view) 안에서 단순히 함수를 시그널로 호출할 때 → 이건 그냥 함수 직접 호출이 더 명확하고 직관적
“시그널은 이벤트가 여러 앱/모듈 간에 공유될 때 빛을 발한다”
MSA (Microservices Architecture)
- MSA에서는 Django 내부 시그널이 아니라, 메시징 시스템(Kafka, RabbitMQ, AWS SQS 등)이 “Signal” 역할을 하게 됨.
- 즉, 서비스 간에는 Django Signal을 직접 못 쓰고, 이벤트를 메시지 큐에 퍼블리시해서 다른 서비스들이 구독하는 구조를 씀.
- 예시:
- User 서비스: "user.deleted" 이벤트를 Kafka에 발행
- CRM 서비스: "user.deleted" 이벤트를 구독 → CRM 데이터 삭제
- Billing 서비스: "user.deleted" 이벤트를 구독 → 구독권 해지
이 경우 Django Signal은 여전히 Monolith 내부에서 쓰일 수 있고, 외부 서비스로 이벤트를 퍼블리시하는 트리거 역할을 할 수도 있음.
4. 정리
- Signal의 장점:
- 앱 간 결합도를 줄이고 이벤트 기반 확장을 가능하게 한다.
- 하나의 이벤트 → 여러 처리 가능.
- Signal의 한계:
- 단일 앱 안에서만 쓰면 사실상 함수 호출과 다를 게 없음.
- 추적이 어렵고 디버깅 힘들어질 수 있음.
- Monolithic일 때: Django Signal은 매우 유용, 단 앱 내부에서만 남발하지 말 것.
- MSA일 때: 서비스 간 Signal 대신 메시지 브로커 사용. Django Signal은 서비스 내부 decoupling 용도로만 사용.