Line/Armeria - 오픈 소스 기여기 01

JeongYong·2024년 7월 9일
1

오픈 소스

목록 보기
1/3

Armeria란?

Armeria는 java기반의 고성능 비동기 마이크로서비스를 손쉽게 구축할 수 있는 프레임워크다.
예를 들어 gRPC, Thrift, Kotlin, Retrofit, Reactive Streams, Spring Boot 및 Dropwizard 등 선호하는 기술을 활용하여 모든 유형의 마이크로서비스를 구축할 수 있다.

Armeria는 Netty의 창시자인 trustin(이희승) 님과 Line의 ikhoon님, minwoox님, jrhee님이 메인테이너로 있다.

공식문서
Armeria를 소개합니다
Spring WebFlux와 Armeria를 이용하여 Microservice에 필요한 Reactive + RPC 동시에 잡기

기여 준비하기

기여하기 위해서는 프로젝트를 어느 정도 이해하고 있어야 한다.
그래서 Armeria의 이해도를 높이고자 Armeria의 공식문서, Line 기술 블로그등을 찾아봤다.

이 과정에서 튜토리얼 문서에 잘못된 내용을 발견해서 얼떨결에 컨트리뷰터가 되었다.
REST Tutorial Step 7 Modifying a Document #5654

그리고 기술 블로그의 Armeria로 Reactive Streams와 놀자! - 1 이 글을 보며, Reactive Streams가 Armeria에서 중요한 역할을 당담하고 있음을 알게되었다.

이는 해당 글에서 자세하게 다루고 있지만, 여기서도 간단하게 다뤄보겠다.

Reacitve Streams은 공식 문서에서 다음과 같이 정의하고 있다.

Reacitve Streams은 논블로킹, 백프레셔를 이용한 스트리밍 방식의 비동기 데이터 처리를 위한 표준입니다.

이해하기 힘든 이 용어들 (스트리밍 방식, 비동기 방식, 백 프레셔, 표준)이 의미하는 것이 무엇인지 정리해 보겠다.

스트리밍 방식이란?

앞 그림은 전통적인 데이터 처리 방식스트리밍 데이터 처리 방식을 비교한 그림이다.

전통적인 데이터 처리 방식은 요청이 오면, 페이로드를 애플리케이션 메모리에 저장해서 처리해야 된다. 여기서 저장소의 데이터를 필요로 한다면, 더욱더 많은 메모리 공간을 요구하게 된다.

이 과정에서 애플리케이션 메모리의 종속되다 보니 처리할 데이터가 많아지면 'out of memory'가 발생한다.

만약 순간적으로 많은 요청이 몰린다면 다량의 Garbage Collection이 발생해서 응답을 정상적으로 처리할 수 없게 된다.

이러한 문제는 스트리밍 데이터 처리 방식을 적용한다면, 해결할 수 있다.

그림에서 볼 수 있듯이, 스트리밍 방식은 입력 데이터에 대한 파이프를 만들어서 데이터를 물 흐르듯이 subscribe하고, 처리한 뒤, publish까지 한 번에 연결해서 처리할 수 있다.

즉, 작은 메모리를 가진 서버도 많은 양의 데이터를 처리할 수 있다는 걸 의미한다.
그래서 서버는 메모리의 종속되지 않고, 많은 양의 데이터를 탄력 있게 처리할 수 있게 된다.

비동기 방식

비동기 방식은 동기 방식과 비교해 보면 이해하기 쉽다.

동기 방식은 클라이언트가 요청을 보내고, 서버가 처리될 때까지 블로킹이 된다. 그로 인해서 요청한 스레드는 요청이 처리될 때까지 묶여있게 된다.
또한 이 요청이 완료되어야 두 번째 요청을 보낼 수 있다.

비동기 방식은 클라이언트가 요청을 보내면, 블로킹 되지 않기 때문에 바로 다음 요청을 보낸다.
그러니까 동기 방식처럼 스레드가 요청을 하고, 묶여있지 않고, 다른 일을 수행할 수 있게 되는 것이다.

그래서 비동기 방식의 장점을 정리하자면,

  • 블로킹 되지 않아 여러 요청을 동시에 보내기 때문에, 응답 속도가 빠르다.
  • 스레드가 블로킹 되지 않고, 여러 작업을 수행할 수 있기 때문에 리소스를 절약할 수 있다.

백 프레셔

백 프레셔는 간단히 말해서 구독자가 받고자 하는 데이터의 양을 정할 수 있다. (앞 그림에서 requst(10)은 10개의 데이터를 요청한다는 의미임)

만약 백 프레셔가 없다면, 발행자가 주는 데이터를 구독자는 조절할 수 없고, 그냥 받을 수밖에 없다.

그러면 구독자는 처리할 수 있는 범위를 벗어나도, 계속 발행자는 데이터를 전송하기 때문에 데이터 손실이 일어나고, 메모리 큐를 사용한다면 'out of memory'가 발생하게 된다.

이러한 문제를 백 프레셔로 해결한다.

표준

스트리밍 방식의 표준이 없었을 때는 각 회사가 공통된 스펙으로 만들지 않아 유기적으로 연결되지 않았다. 스트리밍은 유기적으로 엮여서 흘러야 의미가 있었기 때문에 표준 스펙이 필요했고, 그래서 나온 게 Reacitve Streams이다. 이러한 표준을 두고, 각자 필요한 기능을 넣어서 구현했기 때문에 서로 유기적으로 엮여서 흐를 수 있게 됐다.

여기까지 간단하게 Reactive Streams를 알아봤고, 더 자세한 내용은 다음 링크를 보기 바란다.

래퍼런스
Armeria로 Reactive Streams와 놀자! - 1
Armeria로 Reactive Streams와 놀자! - 2

Armeria의 StreamMessage

나는 Armeria에서 Reactive Streams를 비동기 데이터 스트림을 처리하기 위한 핵심 추상화 계층인 StreamMessage를 타겟으로 했고, 어떤 기능이 추가되면 좋을지 공식 문서를 읽어나갔다.

StreamMessage에 내용을 요약하면 다음과 같다.

  • Reactive Streams의 Publisher 인터페이스를 확장한 비동기 스트림 데이터 전송의 핵심 추상화.
  • 단일 구독자만 허용: 스트림은 한 번만 구독할 수 있어, 데이터가 오직 하나의 구독자에게 전달된다.
  • 일회성 스트림: 스트림 데이터를 한 번 소비하면 재사용이 불가능하다.
  • 추가 기능: 기본 Reactive Streams API 외에도 백프레셔, 타임아웃, whenComplete() (스트림 완료 시 알림), abort() (스트림 중단) 등의 부가 메서드를 제공한다.

이를 통해 Armeria는 HTTP, gRPC, WebSocket 등 다양한 네트워크 통신 환경에서 고성능, 논블로킹 방식으로 비동기 스트림 데이터를 처리할 수 있다.

이러한 StreamMessage에는 데이터 청크 별 타임아웃 기능이 없었고, 이를 구현하면 유용할 것 같다고 생각했다. 그래서 타임아웃 기능을 이슈로 선정했다.

마치며

이번 포스트에서는 어떤 프로젝트를 선정하고, 기여를 하기 위한 준비 과정을 알아봤다. 다음 포스트에서 구현하려는 기능이 구체적으로 어떤 것인지, 그 과정에서 이슈와 결과적으로 어떻게 구현되었는지를 알아보겠다.

0개의 댓글