Бесплатная миграция IT-инфраструктуры в облако

Установка, настройка и использование NATS

Миша Курушин
Миша Курушин
Технический писатель
15 ноября 2024 г.
31
14 минут чтения
Средний рейтинг статьи: 5

NATS — это простой, быстрый и легковесный брокер сообщений, написанный на языке программирования Go.

У NATS есть несколько особенностей организации данных:

  • Ключ — Значение (Key — Value): Данные внутри NATS хранятся в форме «ключ — значение» так, что каждому ключу соответствует определенное значение.
  • Темы (Subjects): Данные внутри NATS объединяются в так называемые «Темы», которые представляют собой именованные каналы для передачи сообщений. Темы можно разделять на сегменты из иерархических структур. 
  • Публикация/Подписка (Pub/Sub): Данные внутри NATS передаются через модель, в которой «Отправители» отправляют сообщения в «Темы», а «Получатели» могут подписываться на эти «Темы» для получения сообщений. 

В отличие от многих других брокеров сообщений (например, Apache Kafka или RabbitMQ), NATS имеет несколько весомых преимуществ:

  • Простота и производительность. Сообщения передаются через простой и быстрый протокол Pub/Sub. То есть при отправке сообщения в тему его мгновенно получают все те, кто на нее подписан. Таким образом, задержки и прочие накладные расходы минимальны.
  • Отсутствие состояния. Информация о состоянии переданных через брокер сообщениях не сохраняется внутри него, равно как и данные по подписчиках тем. Отсутствие необходимости в запутанной синхронизации состояний позволяет NATS легко масштабироваться.
  • Отсутствие очередей по умолчанию. В стандартной конфигурации NATS не формирует очереди сообщений. Это важно в тех случаях, когда своевременность данных важнее их сохранности. А еще это освобождает от управления очередями. 
  • Надежный протокол. Сообщения внутри брокера передаются по протоколу методом «at-most-once delivery» — «максимум одна доставка». Таким образом, подписчик либо получает сообщение один раз, либо не получает вообще. Благодаря этому повышается надежность коммуникации и предотвращаются дубли в реагировании на пересылаемые сообщения.

Таким образом, с помощью NATS можно выстраивать быструю и надежную коммуникацию между множеством различных сервисов.

В этом руководстве мы подробно рассмотрим как установить, настроить и корректно использовать NATS в собственных проектах, запущенных на операционной системе Ubuntu 22.04.

cloud

Загрузка NATS

Обновление пакетов

Перед установкой рекомендуется обновить список доступных репозиториев в системе:

sudo apt update

Загрузка архива

Далее необходимо вручную загрузить ZIP-архив с NATS с его официального репозитория на GitHub:

wget https://github.com/nats-io/nats-server/releases/download/v2.10.22/nats-server-v2.10.22-linux-amd64.zip

По завершении загрузки можно проверить список файлов:

ls

Среди них будет архив с NATS:

nats-server-v2.10.22-linux-amd64.zip  resize.log  snap

Распаковка архива

Далее установим пакет, который выполняет распаковку ZIP-архивов:

sudo apt install unzip -y

Флаг -y добавляем, чтобы установщик автоматически ответил положительно на все возникающие вопросы.

Теперь разархивируем архив с NATS с помощью установленного распаковщика:

unzip nats-server-v2.10.22-linux-amd64.zip

Проверим список файлов:

ls

Как видно, появилась новая папка с содержимым архива:

nats-server-v2.10.22-linux-amd64  nats-server-v2.10.22-linux-amd64.zip  resize.log  snap

Архив нам больше не нужен, поэтому удаляем его:

rm nats-server-v2.10.22-linux-amd64.zip

Установка NATS

Установка сервера

Давайте взглянем на содержимое появившейся папки:

ls nats-server-v2.10.22-linux-amd64

Внутри нее есть основная директория с сервером NATS:

LICENSE  nats-server  README.md

Именно ее мы должны скопировать в системный каталог с бинарными файлами:

sudo mv nats-server-v2.10.22-linux-amd64/nats-server /usr/local/bin/

А уже после копирования необходимо установить соответствующие права доступа:

sudo chmod +x /usr/local/bin/nats-server

Папку с содержимым NATS, по аналогии с архивом, теперь можно тоже удалить:

rm nats-server-v2.10.22-linux-amd64 -R

Проверка сервера

Сервер NATS можно считать установленным! Давайте убедимся в этом, запросив его версию:

nats-server -v

В консольном терминале появится соответствующий вывод:

nats-server: v2.10.22

Однако эта команда не запускает сервер, а лишь возвращает его версию.

Выполнить запуск сервера можно следующим образом:

nats-server

В консоли должен появиться примерно такой вывод:

[3704] 2024/11/07 02:59:53.908362 [INF] Starting nats-server
[3704] 2024/11/07 02:59:53.908623 [INF]   Version:  2.10.22
[3704] 2024/11/07 02:59:53.908669 [INF]   Git:      [240e9a4]
[3704] 2024/11/07 02:59:53.908701 [INF]   Name:     NC253DIPURNIY4HUXYQYC5LLAFA6UZEBKUIWTBLLPSMICFH3E2FMSXB7
[3704] 2024/11/07 02:59:53.908725 [INF]   ID:       NC253DIPURNIY4HUXYQYC5LLAFA6UZEBKUIWTBLLPSMICFH3E2FMSXB7
[3704] 2024/11/07 02:59:53.909430 [INF] Listening for client connections on 0.0.0.0:4222
[3704] 2024/11/07 02:59:53.909679 [INF] Server is ready

В данном случае сервер запускается с привязкой к консольному терминалу, а не как фоновая служба. Поэтому, чтобы обратно выйти в режим ввода команд, нужно нажать сочетание клавиш Ctrl + C.

Конфигурация NATS

Создание конфигурационного файла

После того, как сервер брокера запущен, можно создать отдельный каталог для конфигурационного файла NATS:

mkdir /etc/nats

А после непосредственно сам конфигурационный файл:

sudo nano /etc/nats/nats-server.conf

Его содержимое будет следующим:

cluster {
	name: "test-nats"
}

store_dir: "/var/lib/nats"
listen: "0.0.0.0:4222"

Конкретно в этой конфигурации устанавливаются самые базовые параметры:

  • name: Наименование сервера внутри кластера NATS.
  • store_dir: Путь к директории, в которой будут храниться рабочие данные.
  • listen: IP-адрес и порт, который будет занимать сервер NATS.

Создание отдельного пользователя

Для всех каталогов, связанных с NATS, необходимо создать отдельного пользователя:

useradd -r -c 'NATS service' nats

Теперь создадим каталоги, указанные в конфигурационном файле:

mkdir /var/log/nats /var/lib/nats

Для каждой директории назначим соответствующие права доступа для ранее созданного пользователя:

chown nats:nats /var/log/nats /var/lib/nats

Создание фоновой службы

Ранее мы запускали сервер NATS с привязкой к консольному терминалу. В этом случае при выходе из консоли сервер будет прекращать свою работу.

Чтобы этого не происходило, необходимо создать файл для службы systemd:

sudo nano /etc/systemd/system/nats-server.service

Его содержимое будет таким:

[Unit]
Description=Сервер брокера сообщений NATS
After=syslog.target network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/nats-server -c /etc/nats/nats-server.conf
User=nats
Group=nats
LimitNOFILE=65536
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target

В этом файле есть несколько ключевых параметров:

  • Description: Короткое описание службы.
  • ExecStart: Команда запуска сервера NATS с явным указанием конфигурационного файла
  • User: Имя пользователя, созданного специально под NATS

Созданную службу необходимо в явном виде добавить в список автозапуска:

systemctl enable nats-server --now

Флаг --now сразу же запускает указанную службу.

В консоли появится соответствующее сообщение:

Created symlink /etc/systemd/system/multi-user.target.wants/nats-server.service → /etc/systemd/system/nats-server.service.

Теперь проверим статус запущенной службы:

systemctl status nats-server

Если служба сервера NATS запущена успешно, то среди консольного вывода будет соответствующее сообщение:

...
 Active: active (running)
...

Подключение к NATS

К серверу NATS можно подключаться через консольный терминал и таким образом выполнять тестирование брокера сообщений. Например, публиковать сообщения или подписывать на темы.

Установка клиента

Для того чтобы управлять сервером NATS, необходимо установить соответствующий клиент natscli, который можно скачать с официального репозитория на GitHub:

wget https://github.com/nats-io/natscli/releases/download/v0.1.5/nats-0.1.5-amd64.deb

После этого загруженный архив можно распаковать и установить:

dpkg -i nats-0.1.5-amd64.deb

А сам архив можно удалить за ненадобностью:

rm nats-0.1.5-amd64.deb

Отправка сообщений

Теперь можно отправить сообщение брокеру сообщений:

nats pub -s 127.0.0.1 "someSubject" "Some message"

В этой команде мы отправляем сообщение «Some message» в тему «someSubject» брокеру сообщений, который запущен по IP-адресу 127.0.0.1 и расположен на стандартном порту NATS — 4222.

После этого в консольном терминале появится информация об отправленных данных:

19:59:51 Published 12 bytes to "someSubject"

Чтение сообщений

В данный момент никто не увидит это сообщение, так как отсутствует какой-либо агент, подписанный на указанную тему.

Мы можем сымитировать некий сервис, подписанный на тему и читающий сообщения, с помощью другой SSH-сессии.

Для этого нужно открыть еще один консольный терминал, подключиться к удаленной машине и подписаться на ранее указанную тему:

nats sub -s 127.0.0.1 "someSubject"

В терминале появится сообщение об успешной подписке:

20:11:10 Subscribing on someSubject

Теперь повторим отправку сообщения с первого терминала:

nats pub -s 127.0.0.1 "someSubject" "Some message"

Во втором терминале появится информация о новом сообщении:

[#1] Received on "someSubject"
Some message

Отправим еще одно сообщение с первого терминала:

nats pub -s 127.0.0.1 "someSubject" "Some message again"

Во втором терминале появится соответствующее извещение:

[#2] Received on "someSubject"
Some message again

Обратите внимание, что консольный вывод полученных сообщений имеет нумерацию в квадратных скобках.

Программа на Go + NATS

Давайте создадим небольшую программу на языке программирования Golang с использованием брокера сообщений NATS.

Установка Go

Сперва необходимо убедиться, что в системе установлен компилятор Go:

go version

Если в консольном терминале появилось следующее сообщение, то Go еще не установлен:

Command 'go' not found, but can be installed with:
snap install go         # version 1.23.2, or
apt  install golang-go  # version 2:1.18~0ubuntu2
apt  install gccgo-go   # version 2:1.18~0ubuntu2
See 'snap info go' for additional versions.

В этом случае его необходимо загрузить в виде архива с официального сайта:

wget https://go.dev/dl/go1.23.3.linux-amd64.tar.gz -O go.tar.gz

А потом извлечь:

sudo tar -xzvf go.tar.gz -C /usr/local

Загруженный архив больше не нужен, поэтому его можно удалить:

rm go.tar.gz

Далее необходимо прописать компилятор Go в переменную PATH, чтобы его можно было вызывать из терминала консоли:

echo export PATH=$HOME/go/bin:/usr/local/go/bin:$PATH >> ~/.profile

А далее применяем изменения:

source ~/.profile

Теперь можно проверить корректность установки Go, запросив его версию:

go version

В терминале появится следующий вывод:

go version go1.23.3 linux/amd64

Создание проекта

Создадим отдельную папку для программы на Golang:

mkdir nats_go

После чего перейдем в нее:

cd nats_go

А далее инициализируем проект Go:

go mod init nats_go

Установка модуля

После инициализации проекта необходимо установить клиент NATS с официального репозитория на GitHub. Вручную ничего загружать не надо, достаточно воспользоваться встроенной в Golang функцией:

go get github.com/nats-io/nats.go/

Написание кода

Теперь можно создать файл с кодом программы:

nano nats_go.go

Его содержимое будет таким:

package main

import (
	"fmt" // модуль для работы с консолью
	"os" // модуль для работы с системными функциями
	"time" // модуль для работы с временем

	"github.com/nats-io/nats.go" // модуль для работы с сервером NATS
)

func main() {
	// получаем адрес сервера NATS из переменной среды
	url := os.Getenv("NATS_URL")

	// если в переменной среды нет адреса, используем адрес по умолчанию
	if url == "" {
		url = nats.DefaultURL
	}

	// выполняем подключение к серверу NATS
	nc, _ := nats.Connect(url)

	// откладываем очистку брокера сообщений до момента завершения функции main()
	defer nc.Drain()

	// отправляем сообщение в тему без подписчиков, чтобы убедиться, что оно пропадет
	nc.Publish("people.philosophers", []byte("Привет, Сократ!"))

	// подписываемся на все подтемы в теме «people»
	sub, _ := nc.SubscribeSync("people.*")

	// извлекаем сообщение
	msg, _ := sub.NextMsg(10 * time.Millisecond)

	// выводим статус сообщения (его нет, т.к. оно было отправлено до подписки на темы)
	fmt.Printf("Сообщения нет? Ответ: %v\n", msg == nil)

	// отправляем сообщение в подтему «philosophers» темы «people»
	nc.Publish("people.philosophers", []byte("Привет, Сократ!"))

	// отправляем сообщение в подтему «physicists» темы «people»
	nc.Publish("people.physicists", []byte("Привет, Фейнман!"))

	// извлекаем сообщение и выводим в консоль
	msg, _ = sub.NextMsg(10 * time.Millisecond)
	fmt.Printf("Сообщение: %q в теме %q\n", string(msg.Data), msg.Subject)

	// извлекаем сообщение и выводим в консоль
	msg, _ = sub.NextMsg(10 * time.Millisecond)
	fmt.Printf("Сообщение: %q в теме %q\n", string(msg.Data), msg.Subject)

	// отправляем сообщение в подтему «biologists» темы «people»
	nc.Publish("people.biologists", []byte("Привет, Дарвин!"))

	// извлекаем сообщение и выводим в консоль
	msg, _ = sub.NextMsg(10 * time.Millisecond)
	fmt.Printf("Сообщение: %q в теме %q\n", string(msg.Data), msg.Subject)
}

Теперь можно запустить созданную программу:

go run .

Результат работы программы появится в выводе консольного терминала:

Сообщения нет? Ответ: true
Сообщение: "Привет, Сократ!" в теме "people.philosophers"
Сообщение: "Привет, Фейнман!" в теме "people.physicists"
Сообщение: "Привет, Дарвин!" в теме "people.biologists"

Программа на Python + NATS

В качестве еще одного примера рассмотрим использование брокера сообщений NATS в языке программирования Python.

Сперва нужно убедиться, что интерпретатор Python установлен в системе, запросив его версию:

python --version

В консоли появится соответствующее сообщение:

Python 3.10.12

Обратите внимание, что в этом руководстве используется Python версии 3.10.12.

Установка PIP

Для загрузки клиента NATS для Python сперва необходимо установить пакетный менеджер PIP:

apt install python3-pip -y

Флаг -y поможет автоматически положительно ответить на все вопросы во время установки.

Установка клиента

Теперь можно установить клиент NATS для Python:

pip install nats-py

Создание проекта

Для программы на Python создадим отдельный каталог:

mkdir nats_python

И перейдем в него:

cd nats_python

Написание кода

Создадим файл с кодом программы:

nano nats_python.py

Содержимое которого будет следующим:

import os
import asyncio

# импортируем клиент NATS
import nats
from nats.errors import TimeoutError

# получение переменной окружения, в которой хранится адрес сервера NATS
servers = os.environ.get("NATS_URL", "nats://localhost:4222").split(",")

async def main():
	# подключение к серверу NATS
	nc = await nats.connect(servers=servers)

	# отправляем сообщение в тему без подписчиков, чтобы убедиться, что оно пропадет
	await nc.publish("people.philosophers", "Привет, Сократ!".encode())

	# подписываемся на все подтемы в теме «people»
	sub = await nc.subscribe("people.*")

	try:
		# извлекаем сообщение
		msg = await sub.next_msg(timeout=0.1)
	except TimeoutError:
		pass

	# отправляем сообщение в подтему «philosophers» темы «people»
	await nc.publish("people.philosophers", "Привет, Сократ!".encode())

	# отправляем сообщение в подтему «physicists» темы «people»
	await nc.publish("people.physicists", "Привет, Фейнман!".encode())

	# извлекаем сообщение и выводим в консоль
	msg = await sub.next_msg(timeout=0.1)
	print(f"{msg.data.decode('utf-8')} в теме {msg.subject}")

	# извлекаем сообщение и выводим в консоль
	msg = await sub.next_msg(timeout=0.1)
	print(f"{msg.data.decode('utf-8')} в теме {msg.subject}")

	# отправляем сообщение в подтему «biologists» темы «people»
	await nc.publish("people.biologists", "Привет, Дарвин!".encode())

	# извлекаем сообщение и выводим в консоль
	msg = await sub.next_msg(timeout=0.1)
	print(f"{msg.data.decode('utf-8')} в теме {msg.subject}")

	# отписываемся от тем
	await sub.unsubscribe()

	# очищаем брокер сообщений
	await nc.drain()

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

Теперь можно запустить созданный скрипт:

python nats_python.py

Результатом его работы станет следующий вывод в консольном терминале:

Привет, Сократ! в теме people.philosophers
Привет, Фейнман! в теме people.physicists
Привет, Дарвин! в теме people.biologists

Как можно заметить, логика работы этой программы на Python ничем не отличается от логики работы программы на Go. Разница лишь в синтаксических конструкциях конкретного языка программирования.

Подготовили для вас выгодные тарифы на VDS

Заключение

В этом руководстве было рассмотрено использование брокера сообщений NATS в виде последовательных этапов:

  • Загрузка и установка NATS из официального репозитория на GitHub
  • Минимальная конфигурация сервера NATS
  • Управление сервером NATS через клиент консольного терминала
  • Использование NATS в программе на Golang
  • Использование NATS в программе на Python

Все используемые в этом руководстве клиенты NATS (для терминала, Go и Python) были загружены с официального репозитория NATS на GitHub, в котором размещаются модули и библиотеки для всех поддерживаемых NATS языков программирования.

Больше подробной информации о настройке и использовании NATS можно найти в официальной документации. Также есть множество официальных примеров использования NATS в разных языках программирования.

Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server
15 ноября 2024 г.
31
14 минут чтения
Средний рейтинг статьи: 5
Пока нет комментариев