Education*
Devops
Architecture
F/B End
B.Chain
Basic
Others
CLOSE
Search For:
Search
BY TAGS
linux
HTTP
golang
flutter
java
fintech
개발환경
kubernetes
network
Docker
devops
database
tutorial
cli
분산시스템
www
블록체인
AWS
system admin
bigdata
보안
금융
msa
mysql
redis
Linux command
dns
javascript
CICD
VPC
FILESYSTEM
S3
NGINX
TCP/IP
ZOOKEEPER
NOSQL
IAC
CLOUD
TERRAFORM
logging
IT용어
Kafka
docker-compose
Dart
CNCF NATS
Recommanded
Free
YOUTUBE Lecture:
<% selectedImage[1] %>
yundream
2023-05-23
2022-09-10
4459
## Overviews  [CNCF](https://www.cncf.io/) NATS(NAT Streaming)는 클라우드 네이티브 애플리케이션용으로 설계된 메시징 시스템이다. NATS는 "NATS is Not a Tyical Server"의 약자로 Derek Collison 이 2010년 개발했으며 현재는 Linux Foundation의 CNCF(Cloud Native Computing Foundation)에서 관리하는 오픈소스 프로젝트다. NATS는 분산 시스템을 지원하는 연결기술(connective technology)로 메시지의 주소 설정, 검색, 통신을 담당한다. 마이크로서비스아키텍처(MSA)에서의 메시지 교환, 스트림 처리를 위해서 사용한다. 주요 사용처는 아래와 같다. * 클라우드 메시징 * 서비스 (마이크로서비스, 서비스메시) * 이벤트 / 데이터 스트림(데이터 모니터링, 분석, ML/AI) * Command and Control * IoT & Edge * Telemetry / 센서 데이터 / Command and Control * 레거시 메시징 시스템의 확장 또는 교체 ## 디자인 NATS를 이용하면 애플리케이션의 위치에 상관없이 쉽게 메시지를 주고 받을 수 있다. 메시지는 토픽(Topic)을 기반으로 식별되며, 애플리케이션의 종류와 디바이스의 종류에 상관 없이 통신이 가능하다. 메시지는 PUB/SUB(게시/구독) 패턴을 따르며, 한명 이상의 구독자가 메시지를 수신 할 수 있다.  이런 단순한 디자인을 통해서 애플리케이션은 메시지 처리 코드를 공유하고 상호관심사항을 분리하며, 메시지 요청량의 증가를 쉽게 처리할 수 있도록 확장할 수 있다. **Cloud Native 친화적인 디자인** * Auto-Discovery를 기반으로 하는 고가용성 및 확장성: 다운타임및 구성변경 없이 클러스터 크기를 동적으로 확장할 수 있다. 클러스터 정보가 업데이트되면 NATS 서버 노드와 클라이언트 전체에 업데이트 내용이 실시간으로 전파되어 사용 가능한 NATS 서버 목록을 자동으로 업데이트한다. 이때 어떠한 다운타임이나 서버 및 클러스터의 재구성이 필요하지 않다. * 탄력성: NATS는 개별 클라이언트와 서버에 서비스를 제공하는 것 보다 시스템 전체의 가용성을 우선시하도록 디자인 됐다. 예를 들어서 기존의 메시징 시스템에서는 소비자(consumer)의 메시지처리 속도가 느리면 전체 시스템을 희생하여서 메시지를 수용하려고 리소스를 사용하는데, 이는 잠재적으로 시스템 전체의 불안정성을 증가시킬 수 있다. NATS는 느린 소비자가 있을 경우에 해당 소비자의 연결을 끊는 방식으로 전체 시스템의 안정성을 높인다. * 종속성이 없으며 낮은 오버헤드: NATS 서버는 매우 가볍고 구성도 간단해서 클라우드 환경에 사용하기에 이상적이다. 서버는 실행 전제조건이나 런타임 종속성 없이 단일 바이너리로 작동한다. NATS 서버 도커이미지는 10M 미만이고 메모리를 거의 사용하지 않아서 컨테이너 오케스트레이션 시스템에서 매우 빠르게 적용할 수 있다. ## QoS **NATS JetStream**기능을 활성화하여 애플리케이션 특성에 맞는 QoS(Quality of Service) 정책을 선택 할 수 있다. * **At most once QoS** : NATS는 **최대 한번**의 QoS를 제공한다. 구독자가 Topic에 연결하지 않은 상태에서 메시지가 전송되면, (나중에 접속하더라도) 수신되지 않는다. 이것은 TCP/IP가 제공하는 것과 동일한 수준의 QoS다. **Fire and Forget** 메시징 시스템인 것이다. 메시지는 메모리에만 저장되지 디스크에 쓰지는 않는다. * **At-least / exactly once QoS** : 메시지는 디스크에 저장되며, 이를 통하여 **최소한 한번 및 정확히 한번**과 같은 더 높은 QoS를 사용 할 수 있다. 이 QoS를 이용하면 안정적으로 메시지를 처리하는 애플리케이션을 개발 할 수 있다. ## Subject-Based messaging 기본적으로 NATS는 PUB/SUB 기반으로 작동하며, 이는 **Subject**(Topic 이라고 하기도한다)에 의존한다. ### Subject 란 Subject-Base messaging는 PUB/SUB 시스템에서 일반적으로 사용하는 메시징 패턴으로, 메시지는 특정 Subject에 게시되고 가입자는 특정 Subject를 구독함으로서 메시지를 주고 받는다. Subject는 문자열로 구성된다.  ### 작동방식 Subject-Based messaging의 구성요소와 작동방식은 아래와 같다. * Publishing(게시): 게시자(Publisher)는 Subject를 만들고 여기에 메시지를 전송한다. Subject는 특정 범주나 주제를 나타내는 계층적인 문자열이다. 예를 들어 "Sports.news", "weather.forecast", "stockmarket.updates"를 subject로 사용할 수 있다. * Subscribing(구독): 구독자(subscribers)는 특정 subject로 부터 메시지를 수신하는 개체로, 구독자가 구독을 신청하는 행위를 subscring 라고 한다. 하나 이상의 여러 subject를 구독할 수 있다. 예를들어서 스포츠에 관심있는 구독자는 sports.* 를 구독하여 스포츠의 하위 subject에 게시된 메시지를 받을 수 있다. * Message Delivery(메시지 전달): 게시자가 특정 subject에 메시지를 보내면 메시징 시스템은 해당 subject를 구독하는 모든 구독자에게 메시지를 전달한다.  ### 느슨한 연결(결합) Subject-Based messaging은 게시자와 구독자 사이에 subject를 둠으로서 **게시자와 구독자를 분리** 시킨다. 이 패턴은 일반적인 분산 시스템, 이벤트 기반 및 메시징 미들웨어 프레임워크에 사용하며, 확장 가능하고 느슨하게 결합된 모듈식 시스템의 구축을 용이하게 한다. **느슨한 결합(loose coupling)** 으로 얻을 수 있는 장점은 아래와 같다. 1. 모듈성 및 캡슐화: Subject를 중심으로 잘 정의된 인터페이스 기반으로 설계할 수 있다. 각 모듈은 독립적으로 개발, 테스트, 배포, 유지관리 할 수 있으므로 특정 애플리케이션의 변경사항이 다른 애플리케이션에 미치는 영향을 줄임으로써 모듈화를 촉진한다. 다른 모듈의 코드를 이해할 필요가 없으므로 코드가 간단해지고 더 쉽게 이해할 수 있다. 2. 유연성 및 확장성: 구성요소가 느슨하게 결합되어 있으므로 다른 모듈에 영향을 주지 않고 제거하거나 업데이트 할 수 있다. 이러한 유연성은 비즈니스 요구의 변화에 따라서 유연하게 새로운 기능을 추가하고 외부 기능과 통합하여 시스템이 쉽게 진화할 수 있게 한다. 3. 테스트 가능성: Subject를 중심으로 분리가 되어 있기 때문에 다른 모듈에 영향을 주지 않고 혹은 다른 모듈의 참여를 강제하지 않고 쉽게 테스트 할 수 있다. "시나리오에 따라서 메시지를 생성할 수 있는 테스트 프로그램"만 있으면 되기 때문이다. 즉 격리된 테스트를 만들 수 있어서 테스트 사례의 복잡성을 줄여서 전반적인 소프트웨어 품질을 향상시킬 수 있다. 4. 복원력: 느슨한 결합은 특정 모듈에서 발생하는 오류가 전체 시스템으로 확산되지 않도록 한다. 모듈에서 발생한 영향은 모듈로만 제한되어서 계단식으로 오류가 퍼져나가는 것을 막는다. 또한 문제가 생긴 모듈만 대체하거나 롤백할 수 있으므로 내결함성과 복원력을 높인다. ## Subject 계층 Subject는 "." 을 이용해서 계층적으로 구성할 수 있다. 예를 들어 news subject는 아래와 같이 정의 할 수 있다. ``` news.sports news.financial news.political news.science news.science.it news.science.medical ``` 계층 구조를 이용해서 정보를 범주화 할 수 있으며, 게시자와 구독자는 특정 범주에 있는 메시지들을 게시하고 수신할 수 있다. 예를 들어서 카테고리별로 주요 뉴스를 뽑아내는 애플리케이션을 개발해야 한다면 news.* 을 구독해야 할 것이다. IT 소식을 전하는 블로그라면 news.science.it 를 구독하면 된다. ### Single Token 매칭 와일드카드(\*)는 단일 토큰과 일치한다. 예를 들어서 모든 지역의 동부(east)시간대를 구독하고 싶다면 **time.\*.east**를 설정하면 된다. 이 경우 time.us.east, time.eu.east 를 구독하게 된다.  ### Multiple Tokens 매칭 **>** 는 하나 이상의 토큰과 일치하며, subject의 마지막에만 사용 할 수 있다. 예를 들어 time.us.> 는 time.us.east, time.us.east.atlanta 와 일치한다. time.us.\* 은 single token만 매칭되기 때문에 time.us.east 만 구독 할 수 있다.  ## Publish - Subscribe NATS는 일대다 통신을 위한 publish-subscribe 메시지 배포 모델의 구현체다. 게시자는 subject에 메시지를 보내고, subject를 구독 중인 한명 이상의 구독자가 메시지를 받는다.  메시지는 아래와 같이 구성된다. 1. subject 2. 바이트 배열 형태의 페이로드(payload). 전송가능한 메시지의 크기는 1MB가 기본설정으로 64MB까지 늘릴 수 있다. 3. 헤더 필드 4. replay 주소 필드 : 옵션 ## JetStream NATS는 Publish-Subscribe의 구현체로 이는 NATS의 핵심(Core) 기능이다. 하지만 이 Core 기능은 **Fire and Forget**방식으로 작동하기 때문에 persistence 시스템, QoS와 같은 좀 더 나은 기능이 필요하다. **JetStream**은 내장형 분산 지속성(persistence) 시스템이다. 기본 내장되어 있기 때문에 필요할 때 활성화 해서 기능을 확장 할 수 있다. JetStream은 내용이 방대하기 때문에 별도의 문서에서 자세히 다루도록 하겠다. ## NATS 테스트 애플리케이션 예제 NATS 테스트를 위해서 간단한 채팅 프로그램을 만들었다. ### NATS Server 설치 docker 기반으로 설치했다. ``` # docker run --name nats-test -p 4444:4444 nats [1] 2022/09/10 06:02:56.134643 [INF] Starting nats-server [1] 2022/09/10 06:02:56.134661 [INF] Version: 2.8.4 [1] 2022/09/10 06:02:56.134663 [INF] Git: [66524ed] [1] 2022/09/10 06:02:56.134664 [INF] Cluster: my_cluster [1] 2022/09/10 06:02:56.134665 [INF] Name: NDKULCPLHUDJA7DFWEDKUDW5ALMSBL4PVHRDR54ZGUF7P5JKV3G35SXC [1] 2022/09/10 06:02:56.134666 [INF] ID: NDKULCPLHUDJA7DFWEDKUDW5ALMSBL4PVHRDR54ZGUF7P5JKV3G35SXC [1] 2022/09/10 06:02:56.134669 [INF] Using configuration file: nats-server.conf [1] 2022/09/10 06:02:56.135039 [INF] Starting http monitor on 0.0.0.0:8222 [1] 2022/09/10 06:02:56.135468 [INF] Listening for client connections on 0.0.0.0:4222 [1] 2022/09/10 06:02:56.135567 [INF] Server is ready [1] 2022/09/10 06:02:56.135584 [INF] Cluster name is my_cluster [1] 2022/09/10 06:02:56.135597 [INF] Listening for route connections on 0.0.0.0:6222 ``` ### NATS Chatting Application ```go package main import ( "bufio" "fmt" "log" "os" "strings" "sync" "time" "github.com/nats-io/nats.go" ) func main() { fmt.Print("Subject > ") reader := bufio.NewReader(os.Stdin) subject, err := reader.ReadString('\n') if err != nil { log.Fatal(err) } subject = strings.TrimSuffix(subject, "\n") fmt.Print("Name > ") name, err := reader.ReadString('\n') if err != nil { log.Fatal(err) } name = strings.TrimSuffix(name, "\n") nc, err := nats.Connect("nats://172.17.0.3:4222", nats.Name("Test")) if err != nil { log.Fatal(err) } wg := sync.WaitGroup{} wg.Add(1) go func() { defer wg.Done() sub, err := nc.SubscribeSync(subject) if err != nil { log.Fatal(err) } for { msg, err := sub.NextMsg(10 * time.Second) if err != nil { } else { _, err = fmt.Printf("%s > %s", subject, string(msg.Data)) } } }() go func() { reader := bufio.NewReader(os.Stdin) for { msg, _ := reader.ReadString('\n') nc.Publish(subject, []byte(name+":"+msg)) } }() wg.Wait() } ```  ## NATS 기반 분산 Architecture 예제  E-Commerce 애플리케이션으로 Kubernetes 와 Docker로 배포를 하고 각 서비스간 통신에 **NATS Stream(JetStream)** 을 사용했다. 1. Auth : Session을 관리한다. 사용자 정보는 MySQL로 Session은 REDIS로 관리한다. 2. Orders : 사용자 주문을 관리하는 서비스다. 주문은 만료시간이 지나면 삭제된다. 3. Payment : 결재를 관리한다. Stripe API 혹은 Payment Gateway 서비스를 이용한다. 4. Expiration : 주문은 특정 시간동안만 유효하다. ## NATS 주요 사용 사례 * [Rapidloop](https://nats.io/blog/rapidloop-monitoring-with-opsdash-built-on-nats/): 마이크로 서비스 백플레인(backplane), Service Discovery 및 Service Orchestration * [Clarifai](https://nats.io/blog/how-clarifai-uses-nats-and-kubernetes-for-machine-learning/): Kubernetes에서 마이크로서비스를 위한 컨트롤 플레인(control plane) * [StorageOS](https://nats.io/blog/nats-good-gotchas-awesome-features/): 시스템 이벤트 노티 시스템 * [Fission.io](https://nats.io/blog/serverless-functions-and-workflows-with-kubernetes-and-nats/): NATS streaming를 이용한 서버리스 기능을 위한 이벤트 소싱 * [Choria/MCollective](http://nats.io/blog/nats-for-the-marionette-collective/): NATS를 이용한 서버 오케스트레이션 구현 * [Joyent](https://nats.io/blog/nats-on-autopilot/): NATS streaming를 이용한 센서 데이터 집계 * [Weaveworks](https://nats.io/blog/nats-on-autopilot/): Weave Cloud SaaS를 위한 PUB/SUB 및 대기열 기반 라우팅 ## NATS vs Kafka Kafka와 유사점이 있어서 서로 비교가 되고는 하는데, 비슷한 듯 하지만 설계철학이 달라서 사용 사례도 서로 다르다. | 분류 | NATS | Kafka | | --------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 메시징 모델 | PUB/SUB 모델을 따르며, 실시간 메시징 시나리오, 단순성 및 짧은 시간, 높은 처리량 중심 | 분산 커밋 로그 메시징 모델. 높은 처리량, 내결함성 및 내구성 중심 | | 확장성과 지속성 | 고성능 메시징 및 짧은 대기시간을 강조. 메시지 지속성을 제공하지 않는다. 다만 NATS Streaming는 메시지지속성을 제공한다. | 뛰어난 내구성, 분산/복제된 커밋 로그 스토리지 시스템을 제공하며, 디스크에 메시지를 저장한다 | | Consumer 그룹 | 여러 구독자가 그룹을 구성하며 그룹의 한 구성원한 메시지를 수신하는 메시지 대기열 그룹의 지원 | 여러 컨슈머가 메시지를 병렬로 처리할 수 있는 consumer 그룹의 지원. | | 생태계 | 미니멀리즘, 사용 편의성에 중점. Kafka에 비해서 상대적으로 작은 생태계 | 광범위한 도구 및 통합 옵션을 갖춘 강력한 생태계의 지원. Kafka Streams, SQL Query, Apache Flink, Apache Spark와 다양한 시스템 및 프레임워크를 위한 컨넥터 제공 | | 사용 사례 | 대기시간이 짧은 메시징, 실시간 이벤트 처리, 경량 PUB/SUB 통신 시나리오, MSA, IoT 시스템, Cloud Native 애플리케이션 | 내결함성을 요구하는 이벤트 스트리밍, 데이터 통합, 데이터 파이프라인, 실시간 분석, 로그 집계 | ## NATS vs ETCD NATS와 ETCD 모두 분산 시스템에서의 정보교환을 목적으로 하고 있다. NATS는 분산 시스템에서 애플리케이션에 "**데이터를 제공**" 하기 위해서 사용한다. NATS는 애플리케이션에 필요한 데이터를 메시지에 패키징하고 엔드포인트로 전송하여 이를 전달한다. 다양한 메시징 패턴(분산 대기열, PUB/SUB, 응답 요청)을 지원하며, 하나의 개별 소비자와 통신하거나 하나의 메시지를 팬아웃하여 여러 소비자에게 보낼 수 있다. ETCD는 분산 시스템의 오케스트레이션 및 **메타 데이터 저장과 공유** 문제를 해결하도록 설계됐다. Key/Value 저장소에 데이터를 유지하고 분산 잠금 및 리더 선출을 포함한 동시성 제어 요소를 지원한다. NATS를 사용할지 아니면 ETCD를 사용할지는 아래 두가지 요소에 기반하여 결정할 수 있다. 1. 데이터구조: 분산 애플리케이션이 스트림이 아닌 Key/Value 저장소로 구조화된 데이터에 이점을 얻을 수 있는지 검토한다. 애플리케이션이 Key/Value 데이터 스토리지의 이점이 필요한 경우 etcd가 더 나은 선택이다. 2. 업데이트 빈도: etcd는 값의 업데이트가 일어날 때 분산잠금을 이용해서 데이터의 일관성을 보장한다. 분산잠금은 메시지 전송보다 더 비싼 작업이다. 값을 자주 업데이트해야 하는 경우 NATS가 더 나은 선택이다. ## 참고 * [Microservice e-commerce app](https://github.com/SarthakJha/TicketX) * [채널톡 실시간 채팅 서버 개선 여정 - 2편 : Nats.io로 Redis 대체하기](https://channel.io/ko/blog/real-time-chat-server-2-redis-pub-sub)
Recent Posts
MLOps with Joinc - Kubeflow 설치
Vertex Gemini 기반 AI 에이전트 개발 05. 첫 번째 LLM 애플리케이션 개발
LLama-3.2-Vision 테스트
Vertex Gemini 기반 AI 에이전트 개발 04. 프롬프트 엔지니어링
Vertex Gemini 기반 AI 에이전트 개발 03. Vertex AI Gemini 둘러보기
Vertex Gemini 기반 AI 에이전트 개발 02. 생성 AI에 대해서
Vertex Gemini 기반 AI 에이전트 개발 01. 소개
Vertex Gemini 기반 AI 에이전트 개발-소개
생성 AI 모델 Flux.1 설치 및 사용
GPT를 이용한 Reranker 테스트
Archive Posts
Tags
cloud
messaging
msa
분산시스템
Copyrights © -
Joinc
, All Rights Reserved.
Inherited From -
Yundream
Rebranded By -
Joonphil
Recent Posts
Archive Posts
Tags