2021. 12. 10. 15:43ㆍ학습일지
개요
Redis의 주요 구성요소를 정리하고 학습하던 중, 낯설은 단어를 발견하였다. Lettuce
를 소개하는 문구에서 나온 Netty
라는 네트워크 애플리케이션이었다. 해당 깃헙을 살펴 보았는데, event-driven
이라는 단어가 있었다. 대체 이 단어는 무엇을 의미하는 걸까? 이번 게시글에서는 이 단어에 대해 학습한 내용을 정리해보겠다.
Event-Driven?
위키피디아의 내용을 인용해보자.
The term event-driven refers to a methodology that focuses on events and event dependencies.
요컨대, event에 집중하는 개발 방법론인 듯 하다. 해당 링크를 살펴보면 알겠지만, Event-Driven
에서 파생된 단어가 많다. 즉, 상대적으로 상황에 따라 의미가 달라질 수 있다는 뜻이다. 이러한 상황에서는 파생된 단어의 의미를 하나하나 다 알아가기 전에 Event-Driven
이라는 단어를 분리하고, 하나씩 분석하여, 핵심 개념을 파악하는 것이 더 효율적일 수 있다.
Driven?
우선 Driven
이라는 단어부터 보자, 이 단어는 무언가를 주도하는 의미를 가지고 있다. 이 단어를 가지고 있는 개발 용어로는 대표적으로 TDD(Test Driven development), DDD(Domain Driven development)라는 용어가 있다. 이 두 용어도 중요하고, 알고 싶은 부분이 많지만, 우선은 현재 상황에 집중하도록 하자. 앞의 두 단어의 맥락과 연관지어보면, Event-Driven
이란, 앞의 Event
를 주도하는 개념이라고 볼 수 있다.
Event?
네이버 사전에 의하면, 공통적으로 사건, 행사를 뜻하지만, 좀 더 자세히 보면, 분야에 따라 의미가 달라진다. https://en.wikipedia.org/wiki/Event_(computing) 여기를 참고해보자.
In programming and software design, an event is an action or occurrence recognized by software, often originating asynchronously from the external environment, that may be handled by the software.
위 내용을 인용하자면, 이벤트란, 소프트웨어에 의해 비동기적으로 발생하는 하나의 동작이다. 여기서 비동기적이라는 말은 하나의 게시글로 정리해야할 정도로 내용이 많지만, 우선 간단히 설명하자면, '커널에서 발생하는 입출력 작업을 굳이 애플리케이션 스레드에 notify
를 하지 않는다'로 이해해도 될 것 같다. 즉, 애플리케이션 스레드는 커널 스레드의 입출력 작업 상태를 동기화할 필요가 없기 때문에, 커널에서 입출력 작업을 하는 동안, 애플리케이션 자체의 작업을 계속 진행할 수 있다.
Event + Driven?
이제 두 단어를 합쳐보자. 합쳐보면 의미는 대략 이벤트 주도
로 볼 수 있겠다. 즉, 소프트웨어에 발생하는 동작을 주로 비동기적인 방식으로 관리하겠다는 뜻이다. https://en.wikipedia.org/wiki/Event_(computing)의 내용을 좀 더 살펴보면, Event Driven
기반의 시스템은 외부의 동작을 프로그램으로 관리하는데, 일반적으로 Event loop
를 통해 관리한다고 한다. 여기서 Event loop
는 일종의 디자인 패턴으로 클라이언트의 요청들을 순차적으로 담아서(주로 queue의 형태로 담는다.) 동작을 수행하는 데 필요한 곳으로 분배하는 작업을 할 수 있게 해준다.
텍스트 만으로는 전달이 어려울듯 하니 이미지로 한 번 표현을 해보겠다.
위 그림을 바탕으로 Event Driven
을 더 자세히 설명해보자면, 클라이언트의 특정 행위(Event)에 따라 애플리케이션이 반응하여, 특정 동작을 변경하는 방식인데, 이러한 방식을 Event-Driven 방식
이라고 한다. 여기서 개발자는 발생한 이벤트를 처리하는 함수를 작성하여, 클라이언트에게 출력을 진행하면 된다.
Event-Driven Programming
그렇다면, 이 Event-Driven 방식
이 적용된 사례로 무엇이 있을까? 이 방식이 적용된 사례를 찾아보자면 배민찬이 있겠다. 배민찬에서 설명하는 내용을 참고해보면, 이벤트는 3가지 역할이 존재하는데, 바로 생산자(producer), 소비자(consumer), 연결자(channel)가 있다. 생산자는 이벤트를 발행(publish)하고, 소비자는 말 그대로 소비하는데, 누가 그 이벤트를 발행했는지 알 필요는 없다. 그리고 중간의 연결자는 두 가지의 이벤트(생산자와 소비자)를 연결시켜준다. 이러한 형태를 '느슨한 결합'이라고 하며, 보통 프레임워크나 프로그래밍 언어에서는 이러한 형태를 구현을 돕는 api를 제공한다. Java Spring을 예로들면 다음과 같은 api를 제공한다.
이벤트 생산자
interface ApplicationEventPublisher {
void publishEvent(ApplicationEvent event);
void publishEvent(Object event);
}
이벤트 소비자
interface ApplicationListener<E entends ApplicationEvent> extends EventListener {
void onApplicationEvent(E event);
}
애노테이션 기반 이벤트
@Component
public class AnnotationDrivenEventListener {
@EventListener(condition = "#event.success")
public void handleSuccessful(ApplicationListener<E entends ApplicationEvent> event) {
System.out.println("Handling generic event (conditional).");
}
}
마무리
이제 그동안 학습한 내용을 정리해서 하나의 구조로 표현해보자.
Event-driven 구조에서는 크게 3가지로 분류할 수 있다.
- 이벤트를 발생시키는 객체(Publisher)
- 이벤트를 관리하는 객체(Channel)
- 이벤트를 실행하는 객체(Consumer)
위의 구조 중에서 Event queue를 관리하는 법은 보편적으로 오픈소스를 사용하는 것이 좋은데, 대표적으로 RabitMQ와 Aphache Kafka가 있다. 이 부분에 대한 학습은 나중에 사용하게되는 상황이 생길 때 그때 진행하도록 하겠다.
'학습일지' 카테고리의 다른 글
멀티 프로세스/스레드 환경에서 동기화를 위한 여러 전략과 차이 (0) | 2022.01.19 |
---|---|
벡터 in Java (0) | 2021.12.19 |
확장에 유리한 아키텍처? 그러면, 인증정보는 어떻게 관리할까? (0) | 2021.11.29 |
Web 서비스를 운영할 때, 알맞은 아키텍처는 무엇일까? (0) | 2021.11.28 |
프로젝트 인증로직 Description (0) | 2021.11.28 |