NATS 설치 및 특징

Look! there's a flower!·2024년 10월 16일
0

There are easier ways to install NATS using golang and etc.
Anyway...

manual install NATS

NATS client

$ curl -OL https://github.com/nats-io/natscli/releases/download/v0.1.1/nats-0.1.1-amd64.deb
$ sudo dpkg -i nats-0.1.1-amd64.deb

NATS server

$ curl -L https://github.com/nats-io/nats-server/releases/download/v2.10.7/nats-server-v2.10.7-linux-amd64.zip -o nats-server.zip
$ unzip nats-server.zip
$ sudo cp nats-server/nats-server /usr/bin

register nats-server as system service if necessary.

or you can use other methods like this:
$ curl -sf https://binaries.nats.dev/nats-io/nats-server/v2@v2.10.20 | sh

docker

$ docker pull nats:latest
$ docker run -p 4222:4222 -ti nats:latest
but i prefer to use command line because nats-server is just a binary file.

NATS 특징

서버 클러스터링

server list를 통해 접속 할 수 있음
다른 서버가 죽더라도 구독 정보는 full mesh 데이터 구조로 다른 서버에 공유되므로 다른 서버가 서비스를 계속 할 수 있음

Pub/Sub, Request/Reply, Queueing 모델

Pub/Sub

메시지를 Subscribe 하면 메시지가 발행(Publish)될 때 모든 Subscribe 한 클라이언트들에게 해당 메시지를 전달

Request/Reply

Pub/Sub가 메시지를 구독하면 메시지 발행 시 구독한 클라이언트들 즉 구독자들에게 메시지를 전달하는 방식인데 이 경우 요청한 응답을 받고자 한다면 양방향으로 Pub/Sub를 구현해야만 한다.
이때 Request/Reply를 이용하면 요청한 Request에 대한 Reply 형식으로 응답 메시지를 전달 할 수 있다.

Queueing

모든 구독자들에게 메시지를 전달하는 것이 아니라 구독자들 중에서 처리 할 클라이언트를 하나 선택해서 전달하는 방식이다.
여러 구독자가 메시지 처리를 분담하여 서버 부하를 줄일 수 있다.

JetStream 방식

기본적으로는 메모리 기반으로 메시지 전달하지만 JetStream을 통해 파일 또는 데이터베이스에 메시지를 저장하여 안정성을 높일 수 있음
사용법은 다름

import asyncio
import json
import nats

async def main():
    # NATS 서버 연결
    nc = await nats.connect("nats://127.0.0.1:4222")
    js = nc.jetstream()

    # 스트림 생성
    stream_config = {
        "name": "EVENTS",
        "subjects": ["events.>"],
    }
    await js.add_stream(stream_config)

    # 소비자 생성
    consumer_config = {
        "durable_name": "events-consumer",
        "deliver_subject": "events-deliver",
    }
    consumer = await js.add_consumer("EVENTS", consumer_config)

    # 메시지 발행
    for i in range(10):
        data = {"id": i, "message": f"Event {i}"}
        await js.publish("events.new", json.dumps(data).encode())
        print(f"Published: {data}")

    # 메시지 구독
    async def message_handler(msg):
        data = json.loads(msg.data.decode())
        print(f"Received: {data}")
        await msg.ack()

    await js.subscribe("events-deliver", cb=message_handler)

    # 10초 동안 메시지 수신 대기
    await asyncio.sleep(10)

    await nc.close()

if __name__ == "__main__":
    asyncio.run(main())
profile
Why don't you take a look around for a moment?

0개의 댓글