Kubernetes 이야기

Nats - 오픈 소스 메시징 시스템 본문

Kubernetes/일반

Nats - 오픈 소스 메시징 시스템

kmaster 2022. 7. 27. 17:56
반응형

NATS 는 오픈 소스 메시징 시스템( 메시지 지향 미들웨어 라고도 함 ) 이다. NATS 서버는 Go 프로그래밍 언어로 작성되어 있고,. 서버와 인터페이스하는 클라이언트 라이브러리는 수십 가지 주요 프로그래밍 언어에 사용할 수 있다. NATS의 핵심 설계 원칙은 성능, 확장성 및 사용 용이성이다.

 

Nats를 사용하여 마이크로 서비스 구성을 손쉽게 구현할 수 있다.

 

출처: https://nats.io/blog/building-scalable-microservices-with-nats/

 

마이크로 서비스 구조에서 NATS 서버는 다음과 같은 기능을 제공할 수 있다.

 

  • 보안
  • 오류 처리(메시지 보증 및 승인을 통해)
  • 라우팅(제목 기반 메시지 통신을 통해)
  • 확장성(클러스터링을 통해)
  • 성능(동급 최고의 성능)
  • 관찰 가능성(로깅 및 Prometheus 에이전트를 통해)
  • 부하 분산(대기열 기반 메시징을 통해)

 

아키텍쳐

NATS 는 단순성, 성능, 보안 및 확장성에 중점을 둔 발행/구독 메시지 지향 미들웨어이고, 처음부터 클라우드에서 작동하도록 구축되었다.

NATS 메시징은 Core NATSNATS Streaming으로 구성된다. Core NATS는 최대 1회 전달을 지원하며 가볍고 성능이 좋으며 항상 사용 가능하도록 설계되었다. NATS Streaming은 최소 한 번 배달, 메시지 재생 및 구독 연속성(영구 구독자)을 제공하는 로그 기반 지속성을 지원한다.

 

Core NATS

 

Core NATS는 발행/구독 , 요청/회신 및 작업 대기열 메시징 패턴 을 위한 이상적인 메시징 소프트웨어이다 .

NATS 서버는 NATS 서버( nats-server ) 에 연결하기 위해 NATS 프로토콜(일반적으로 NATS 클라이언트 라이브러리를 통해)을 사용하는 애플리케이션인 NATS 클라이언트 간에 메시지를 라우팅한다 . 논리적으로 응용 프로그램은 메시지 버스 를 통해 통신하지만 네트워크 구성은 표준 TCP 클라이언트-서버 모델이다.

 

Clustering

 

고가용성과 확장성을 제공하기 위해 NATS 서버는 풀 메시 클러스터링을 지원한다.

구독 및 라우팅

 

NATS 클라이언트는 구독을 생성할 때 서버의 주제에 대한 관심을 등록한다.

 

서버가 클러스터링되면 클라이언트를 대신하여 클러스터의 다른 서버에 관심을 자동으로 등록 하여 연결되어 있는 클러스터의 서버에 관계없이 클라이언트에 메시지 전달을 제공한다.

 

 

Core NATS 클라이언트 설계 및 아키텍처

 

NATS 프로토콜은 몇 개의 동사만 있는 텍스트 기반이며 단순하다.  아키텍처는 클라이언트 언어 또는 플랫폼의 관용적 기능에 따라 다르지만 공식적으로 유지 관리되는 모든 클라이언트는 다음 기능을 지원한다.

  • 서버에 연결할 때 자격 증명이 전달되도록 허용
  • TLS 지원
  • 메시지 게시
  • 제목 구독 및 메시지 수신
  • 복원력을 위한 버퍼링 메시지
  • 끊어진 연결 감지 시 서버에 재연결
  • 검색 프로토콜을 통해 사용 가능한 서버 업데이트

NATS 클라이언트의 일반적인 흐름은 매우 간단하다.

  • 서버에 대한 연결을 설정하고 오류/알림 처리기를 설정한다.
  • 선택적으로 제목 및 설정 핸들러를 구독하여 메시지를 처리한다.
  • 선택적으로 메시지를 게시한다.
  • 완료되면 클라이언트는 NATS 서버에서 연결을 끊는다.

 

NATS Streaming

NATS 스트리밍 서버 및 스트리밍 클라이언트 는 코어 NATS와 다른 프로토콜이다. 개념적으로는 NATS 스트리밍을 NATS 스트리밍 서버 위의 계층으로 간주하는 것이 유용하다. 스트리밍 서버는 실제로 핵심 NATS 클라이언트이다. 이것은 NATS 스트리밍 서버가 작업을 분배하는 전용 호스트를 가질 수 있도록 하는 유연성을 제공한다.

 

 

스트리밍 클라이언트 디자인 및 아키텍쳐

 

NATS 스트리밍 프로토콜은 내부 프로토콜 메시지에 더 많은 필드가 필요하기 때문에 더 복잡하다. 직렬화를 위해 protobuf를 사용하는 NATS 프로토콜을 통한 바이너리 프로토콜이다. 
NATS 스트리밍 클라이언트는 다른 클라이언트 API 를 사용하지만 핵심 NATS에 있는 많은 기능을 NATS 스트리밍 클라이언트에서 사용할 수 있다. 그러나 스트리밍 메시지와 핵심 NATS 메시지는 상호 교환할 수 없다. 
NATS 스트리밍은 또한 코어 NATS와 별도의 제목 네임스페이스를 사용하므로 스트리밍을 통해 메시지를 게시하고 코어 NATS를 통해 구독할 수 없다.

공식적으로 지원되는 모든 클라이언트는 다음을 제공한다.

 

  • 코어 NATS를 통한 NATS 스트리밍 서버와의 논리적 스트리밍 연결.
  • 메시지 게시
  • 메시지를 수신하기 위해 제목을 구독하고 여기 에 있는 다양한 구독 옵션을 지원 하며 지속적인 구독 지원을 제공
  • 대기열 그룹 구독
  • 게시 승인 처리 및 수신된 메시지 승인 지원

NATS 스트리밍 클라이언트의 일반적인 흐름은 핵심 NATS 클라이언트와 매우 유사합니다.

  • 스트리밍 서버에 연결 설정
  • 선택적으로 제목 및 설정 핸들러를 구독하여 메시지를 처리한다
  • 선택적으로 메시지를 게시하고 서버에서 게시 승인을 처리한다.
  • 완료되면 클라이언트는 NATS 스트리밍 서버와의 연결을 닫는다.

 

Nats VS Apache Kafka

 

Kafka는 Event Streaming Platform 이고 NATS는 기존 Message Queue 에 가깝다 . Kafka는 강력한 순서 지정 및 지속성 의미 체계로 기존 pub-sub 모델을 강화하는 새로운 Event-Driven Architectures 의 고유한 요구 사항을 중심으로 최적화되었다 . 반대로 NATS는 pub-sub 토폴로지를 중심으로 고도로 최적화되어 있으며 메시지 순서와 안정적인 전달이 문제가 되지 않는 디커플링 시스템을 위한 훌륭한 플랫폼이다. ( 물론, Nats에는 Kafka와 비슷한 NATS Streaming이 있다. )

 

Kafka는 더 넓은 범위의 메시징 및 이벤트 시나리오를 처리하여 전반적인 유연성을 더 많이 제공한다고 객관적으로 말할 수 있지만 구성 및 유지 관리가 비례적으로 더 복잡하고 일부 시나리오에서는 과도할 수 있다. NATS는 더 간단한 솔루션으로 시작하고 운영하기가 훨씬 쉽다.

 

Nats 외에 메시지 기술을 위해 사용되는 제품으로는 Apache Kafka, RabbitMQ, Apache Pulsar 등의 제품의 있다.

이 제품들의 비교자료는 아래를 참고한다.

 

https://docs.nats.io/nats-concepts/overview/compare-nats

 

Compare NATS - NATS Docs

Kafka has a large number of integrations in its ecosystem, including stream processing (Storm, Samza, Flink), Hadoop, database (JDBC, Oracle Golden Gate), Search and Query (ElasticSearch, Hive), and a variety of logging and other integrations.

docs.nats.io

 

설치

Nats를 Kubernetes에서 설치하기 위해서 여러가지 방법이 있지만, Helm 을 이용하여 설치해 보자.

 

# helm repo add nats https://nats-io.github.io/k8s/helm/charts/
# helm install my-nats nats/nats

설치가 완료되면 아래와 같이 설치내역을 조회할 수 있다.

NAME                               READY   STATUS    RESTARTS   AGE
pod/my-nats-0                      3/3     Running   0          42m
pod/my-nats-box-75bb48bdbf-5ppbz   1/1     Running   0          42m

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                                                 AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP                                                 35d
service/my-nats      ClusterIP   None         <none>        4222/TCP,6222/TCP,8222/TCP,7777/TCP,7422/TCP,7522/TCP   42m

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/my-nats-box   1/1     1            1           42m

NAME                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/my-nats-box-75bb48bdbf   1         1         1       42m

NAME                       READY   AGE
statefulset.apps/my-nats   1/1     42m

 

my-nats-0 은 nats server이고 my-nats-box는 서버와 상호 작용하는 간단한 방법으로 사용할 수 있는 NATS 상자 유틸리티 컨테이너이다.

( my-nats-box는 helm 설치 시 옵션으로 제거 할 수 있고, 인증은 기본값이 false이다. )

 

my-nats-box에 접속하면 nats cli를 통해 간단히 테스트를 하고, 모니터링을 할 수 있다.

# kubectl exec -it my-nats-box-75bb48bdbf-5ppbz   -- /bin/sh -l
             _             _
 _ __   __ _| |_ ___      | |__   _____  __
| '_ \ / _` | __/ __|_____| '_ \ / _ \ \/ /
| | | | (_| | |_\__ \_____| |_) | (_) >  <
|_| |_|\__,_|\__|___/     |_.__/ \___/_/\_\

nats-box v0.11.0
my-nats-box-75bb48bdbf-5ppbz:~# nats sub test &
my-nats-box-75bb48bdbf-5ppbz:~# 11:28:52 Subscribing on test

my-nats-box-75bb48bdbf-5ppbz:~#

 

이제 다른 터미널에서 pub 을 실행해 보자.

# kubectl exec -it my-nats-box-75bb48bdbf-5ppbz   -- /bin/sh -l
             _             _
 _ __   __ _| |_ ___      | |__   _____  __
| '_ \ / _` | __/ __|_____| '_ \ / _ \ \/ /
| | | | (_| | |_\__ \_____| |_) | (_) >  <
|_| |_|\__,_|\__|___/     |_.__/ \___/_/\_\

nats-box v0.11.0
my-nats-box-75bb48bdbf-5ppbz:~# nats pub test "hi test"
11:30:02 Published 7 bytes to "test"
my-nats-box-75bb48bdbf-5ppbz:~#

 

sub을 조회하면

my-nats-box-75bb48bdbf-5ppbz:~# nats pub test "hi test"
11:30:02 Published 7 bytes to "test"
my-nats-box-75bb48bdbf-5ppbz:~#

 

또한, nats-top을 통해 간단히 nats 서버 모니터링이 가능하다.

NATS server version 2.8.4 (uptime: 50m32s)
Server:
  Load: CPU:  0.0%  Memory: 22.2M  Slow Consumers: 0
  In:   Msgs: 4  Bytes: 15  Msgs/Sec: 0.0  Bytes/Sec: 0
  Out:  Msgs: 5  Bytes: 22  Msgs/Sec: 0.0  Bytes/Sec: 0

Connections Polled: 2
  HOST                     CID    NAME                      SUBS    PENDING     MSGS_TO     MSGS_FROM   BYTES_TO    BYTES_FROM  LANG     VERSION  UPTIME   LAST ACTIVITY
  192.168.166.134:35296    4      NATS CLI Version 0.0.32   1       0           4           0           15          0           go       1.14.0   45m39s   2022-07-26 11
  192.168.166.134:39934    8      NATS CLI Version 0.0.32   1       0           1           0           7           0           go       1.14.0   3m0s     2022-07-26 11

 

Python Client 연동

 

Nats와 Python연동을 위해서는 Python 3.7 이상을 사용해야 한다.

 

설치

# pip install nats-py

예제

import asyncio
import nats

async def main():
    # Connect to NATS!
    nc = await nats.connect("my-nats.default.svc.cluster.local:4222")

    # Receive messages on 'foo'
    sub = await nc.subscribe("foo")

    # Publish a message to 'foo'
    await nc.publish("foo", b'Hello from Python!')

    # Process a message
    msg = await sub.next_msg()
    print("Received:", msg)

    # Close NATS connection
    await nc.close()

if __name__ == '__main__':
    asyncio.run(main())

실행결과

# python3 ex1.py
Received: Msg(_client=<nats client v2.1.4>, subject='foo', reply='', data=b'Hello from Python!', headers=None, _metadata=None, _ackd=False)

 

출처 

https://docs.nats.io/

https://github.com/nats-io/nats-general/blob/master/architecture/ARCHITECTURE.md

https://docs.nats.io/running-a-nats-service/nats-kubernetes

 

 

 

반응형
Comments