이번에는 라즈베리파이에 NATS를 설치했다.
웹사이트, 사진첩, 나중에 붙을 작은 앱들이 점점 늘어나면 서로 직접 호출하기보다, 중간에 가볍게 메시지를 주고받을 통로가 있으면 편해진다.
NATS는 그 역할에 잘 맞는 작은 메시징 시스템이다.
NATS는 무엇인가
NATS는 가볍고 빠른 메시징 시스템이다.
어떤 프로그램이 특정 주제로 메시지를 보내면, 그 주제를 구독하고 있던 다른 프로그램들이 메시지를 받는다.
이런 구조를 보통 publish / subscribe라고 부른다.
예를 들면 이런 식이다.
photo.uploaded -> 사진 업로드 완료
site.published -> 사이트 배포 완료
diary.created -> 새 잡상 작성
나중에 작은 앱들이 많아졌을 때, 서로를 직접 알지 않아도 같은 메시지 버스를 통해 느슨하게 연결할 수 있다.
NATS는 기본 메시징 외에도 request / reply, queue group, 그리고 디스크에 메시지를 보존하는 JetStream 기능을 제공한다.
왜 라즈베리파이에 설치했는가
지금 muabow.com은 라즈베리파이 위에서 돌아간다.
현재 이 장비에는 이미 아래 서비스들이 있다.
nginxcloudflared- 사진첩 관리자 앱
- 정적 블로그 빌드 결과물
여기에 NATS를 붙이면, 앞으로 이런 흐름을 만들 수 있다.
- 사진 업로드 후 사이트 갱신 이벤트 발행
- 배포 완료 이벤트 기록
- 백그라운드 작업 큐
- 작은 봇이나 자동화 작업 연결
- 여러 앱 사이의 느슨한 통신
즉 지금 당장 대단한 분산 시스템을 만들려는 것이 아니라, 작은 개인 서버 안에 조용한 이벤트 통로를 하나 만들어두는 느낌이다.
설치 방식
Debian 패키지에도 nats-server가 있었지만, 라즈베리파이의 패키지 저장소에는 2.10.27 버전이 올라와 있었다.
공식 릴리스 기준 최신은 nats-server v2.14.0이었고, NATS 공식 문서도 릴리스 아카이브를 받아 바이너리를 설치하는 방식을 안내한다.
그래서 이번에는 GitHub 공식 릴리스에서 linux-arm64 바이너리를 받아 설치했다.
설치한 바이너리는 아래 두 가지다.
nats-server v2.14.0
nats CLI v0.4.0
라즈베리파이 환경은 aarch64, Debian GNU/Linux 13 (trixie)다.
설치 위치
바이너리는 아래 위치에 설치했다.
시스템 실행 경로 아래의 nats-server, nats
설치 확인은 이렇게 했다.
nats-server --version
nats --version
설정 파일
NATS 설정 파일은 시스템 설정 디렉터리 아래에 두었다.
현재 설정은 이렇게 잡았다.
server_name: local-nats
host: 127.0.0.1
port: <client-port>
http: 127.0.0.1:<monitoring-port>
jetstream {
store_dir: <jetstream-store-dir>
max_mem_store: 128Mb
max_file_store: 2Gb
}
중요한 점은 host: 127.0.0.1이다.
NATS를 외부에 바로 열지 않고, 라즈베리파이 내부 앱들만 붙을 수 있게 했다.
나중에 외부에서 접근해야 할 일이 생기면 인증, TLS, 터널링 방식을 따로 정리한 뒤 열어야 한다.
JetStream도 켜두었다
기본 NATS는 빠른 실시간 메시징에 가깝다.
하지만 JetStream을 켜면 메시지를 디스크에 저장하고, 나중에 다시 읽거나 작업 큐처럼 사용할 수 있다.
현재 저장소는 전용 데이터 디렉터리에 둔다.
제한은 작게 잡았다.
메모리: 128MB
파일 저장소: 2GB
개인 서버에서 처음 쓰기에는 이 정도면 충분하다.
systemd 서비스
NATS는 systemd 서비스로 등록했다.
서비스 이름은 다음과 같다.
nats.service
서비스 파일은 아래 위치에 있다.
systemd 서비스 디렉터리 아래
핵심 실행 명령은 이렇다.
nats-server -c <config-path>
이제 재부팅 후에도 자동으로 올라온다.
확인 명령은 다음과 같다.
systemctl status nats
systemctl is-enabled nats
systemctl is-active nats
현재 상태는 enabled, active다.
열린 포트
현재 NATS는 외부에 열려 있지 않다.
로컬에서만 아래 포트가 열린다.
127.0.0.1:<client-port> NATS client
127.0.0.1:<monitoring-port> monitoring
모니터링 확인은 이렇게 할 수 있다.
curl http://127.0.0.1:<monitoring-port>/varz
여기서 서버 이름, 버전, JetStream 상태, 메모리 사용량 같은 정보를 볼 수 있다.
실제 pub/sub 테스트
설치 후 실제 메시지가 오가는지도 확인했다.
한쪽에서 구독을 걸고:
nats --server nats://127.0.0.1:<client-port> sub test.subject
다른 쪽에서 메시지를 발행했다.
nats --server nats://127.0.0.1:<client-port> pub test.subject "hello"
구독 쪽에서는 다음처럼 메시지를 받았다.
[#1] Received on "test.subject"
hello
즉 NATS 서버, CLI, 로컬 연결, publish/subscribe 흐름이 모두 정상이다.
어디에 쓸 수 있을까
지금 사이트 구조에서 NATS는 이런 식으로 쓰기 좋다.
- 사진 업로드
- 배너 선택 변경
- 갤러리 선택 변경
- 사진첩 이벤트
- 글 작성
- 잡상 작성
- 정적 사이트 빌드 완료
- 사이트 배포 이벤트
- 이미지 리사이즈
- 썸네일 생성
- 로그 기록
- 백그라운드 작업
- 특정 이벤트가 오면 알림 남기기
- 나중에 관리자 화면에 최근 이벤트 표시하기
- 작은 자동화
아직은 준비 단계지만, 앞으로 앱들이 하나씩 늘어날수록 의미가 커질 수 있다.
운영 명령
자주 볼 명령은 이 정도다.
sudo systemctl status nats
sudo systemctl restart nats
sudo journalctl -u nats --no-pager -n 100
curl http://127.0.0.1:<monitoring-port>/varz
nats --server nats://127.0.0.1:<client-port> sub test.subject
nats --server nats://127.0.0.1:<client-port> pub test.subject "hello"
정리
이번 작업으로 라즈베리파이에 작은 메시지 버스가 생겼다.
외부 공개는 하지 않았고, 내부 앱들이 안전하게 붙을 수 있도록 localhost에만 열어두었다.
JetStream도 켜두어서 나중에 단순 이벤트뿐 아니라 작은 작업 큐나 저장형 이벤트에도 사용할 수 있다.
지금은 조용히 켜져 있는 기반 시설에 가깝다.
하지만 사이트가 조금씩 자라면서, 이 작은 NATS 서버가 앱들 사이의 말길이 되어줄 수 있다.
참고한 공식 문서: