如何在Ubuntu16.04上安装和配置NATS

来自菜鸟教程
跳转至:导航、​搜索

介绍

NATS 是一个开源的高性能消息传递系统,通常被描述为“云的中枢神经系统”。 它每秒能够路由数百万条消息,非常适合连接微服务和 IoT(物联网)设备。

NATS 是一个 PubSub 消息传递系统 。 在这种系统中,一个或多个发布者消息代理发送具有特定主题的消息,消息代理将这些消息传递给任何客户端,或订阅者[X203X ]给定主题。 发布者不知道甚至不关心订阅者,反之亦然。 这种架构使扩展系统和添加新功能变得容易,因为我们可以添加发布者和订阅者而不影响系统的其余部分。 这种类型的系统非常适合监控服务器和设备; 设备可以发送消息,我们可以订阅这些消息以通过电子邮件或其他方式发送通知。

在本教程中,我们将安装官方 NATS 服务器 gnatsd 作为服务,并以安全的方式对其进行访问。 我们还将创建一个基本的服务器过载警告系统,当服务器负载过高时发送电子邮件,使用 gnatsd 作为其消息代理。

先决条件

要完成本教程,您需要:

第 1 步 — 下载 NATS 服务器

让我们首先下载 gnatsd 服务器并确保它在我们的系统上运行没有任何问题。

在编写本教程时,最新的稳定 gnatsd 版本是 0.9.4 版。 您可以查看 NATS 下载页面 以获得更高版本,如果您想使用更新版本,请根据需要调整以下命令。

首先,使用您的非 root 帐户登录您的服务器:

ssh sammy@your_server_ip

然后,确保您位于用户的主目录中:

cd

接下来,使用 wgetgnatsd 下载到您的服务器:

wget https://github.com/nats-io/gnatsd/releases/download/v0.9.4/gnatsd-v0.9.4-linux-amd64.zip

您刚刚下载的存档是压缩存档,因此您需要安装 unzip 来提取文件。 您可以使用 apt 安装它:

sudo apt-get install -y unzip

然后使用 unzip 提取 gnatsd

unzip -p gnatsd-v0.9.4-linux-amd64.zip gnatsd-v0.9.4-linux-amd64/gnatsd > gnatsd

然后使 gnatsd 可执行,以便您可以运行它:

chmod +x gnatsd

让我们通过从当前目录运行来测试我们是否可以运行 gnatsd。 使用以下命令启动 gnatsd

./gnatsd --addr 127.0.0.1 --port 4222

您看到的输出将类似于此示例:

Output[1851] 2016/09/23 05:20:02.247420 [INF] Starting nats-server version 0.9.4
[1851] 2016/09/23 05:20:02.248182 [INF] Listening for client connections on 127.0.0.1:4222
[1851] 2016/09/23 05:20:02.248626 [INF] Server is ready

默认情况下,gnatsd 监听所有接口对应的地址 0.0.0.0 上的端口 4222。 使用 --port 参数,您可以更改端口,使用 --addr 您可以更改它侦听的地址。 我们使用 --addr 127.0.0.1 运行 gnatsd,因此它仅在我们的服务器内可用,外部客户端无法访问。 在本教程的后面,我们将保护 gnatsd 并向世界开放。

CTRL+C关闭gnatsd

现在您知道一切正常,让我们以更正式的方式进行设置。

第 2 步 — 创建目录结构和配置文件

在 Linux 上,第三方服务相关的软件经常保存在 /srv 目录下。 我们将遵循该约定并将与 NATS 相关的文件保存在 /srv/nats 下。 我们将 gnatsd 可执行文件放在 /srv/nats/bin 中。

首先,创建/srv/nats/bin文件夹:

sudo mkdir -p /srv/nats/bin

然后将 gnatsd 移动到 /srv/nats/bin 文件夹:

sudo mv ~/gnatsd /srv/nats/bin

服务器可以从文件中加载其配置,当我们需要在教程后面修改服务器设置时,这将派上用场。 创建文件 /srv/nats/gnatsd.config

sudo nano /srv/nats/gnatsd.config

并将以下内容添加到文件中:

/srv/nats/gnatsd.config

port: 4222
net: '127.0.0.1'

该配置文件告诉 gnatsd 服务器在地址 127.0.0.1 上的端口 4222 上侦听,就像以前一样,但这次我们不必在命令中指定这些选项线。

让我们再次运行服务器以确保我们已正确配置。 执行以下命令以使用新的配置文件启动 gnatsd

/srv/nats/bin/gnatsd -c /srv/nats/gnatsd.config

输出与您之前看到的类似:

Output[1869] 2016/06/18 05:30:55.988856 [INF] Starting nats-server version 0.9.4
[1869] 2016/06/18 05:30:55.989190 [INF] Listening for client connections on 127.0.0.1:4222
[1869] 2016/06/18 05:30:55.989562 [INF] Server is ready

再次按 CTRL+C 关闭 gnatsd 并返回提示。 现在让我们创建一个将运行此服务的用户。

第三步——创建服务用户

使用自己的用户帐户运行每项服务以限制服务受到损害时的损害是一种很好的安全做法。 让我们创建一个拥有 NATS 服务和 NATS 相关文件的用户和组。

首先,让我们创建一个名为 nats 的系统用户和组:

sudo adduser --system --group --no-create-home --shell /bin/false nats
OutputAdding system user `nats' (UID 106) ...
Adding new group `nats' (GID 114) ...
Adding new user `nats' (UID 106) with group `nats' ...
Not creating home directory `/home/nats'.

我们将 /bin/false shell 分配给 nats 系统用户以禁用该用户的登录并抑制主目录创建。 我们还创建了一个 nats 组。

让我们将 /srv 目录的所有者更改为 nats 用户和组:

sudo chown -R nats:nats /srv

现在我们已经创建了 nats 用户和组,让我们继续创建 NATS 服务。

第 4 步 — 将 gnatsd 作为服务运行

我们希望 gnatsd 在系统启动时启动,如果它崩溃则重新启动。 我们将使用 systemd 来处理这个问题。

systemd 是 Linux 系统的服务管理器。 它负责在启动时启动服务,在必要时重新启动它们,并在系统关闭时以受控方式停止它们。

我们需要创建一个 服务配置 来定义应该如何以及何时启动 NATS 服务。 用户创建的服务文件位于 /etc/systemd/system 中,因此创建文件 /etc/systemd/system/nats.service

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

在文件中,放置这个脚本来定义 gnatsd 应该如何启动:

/etc/systemd/system/nats.service

[Unit]
Description=NATS messaging server

[Service]
ExecStart=/srv/nats/bin/gnatsd -c /srv/nats/gnatsd.config
User=nats
Restart=on-failure

[Install]
WantedBy=multi-user.target
  • [Unit] 部分包含有关服务的一般信息,例如描述服务的 Description
  • [Service] 部分包含与服务相关的配置。 ExecStart 是运行服务器的命令。 我们在这里使用 gnatsd 可执行文件的绝对路径。 Restart=on-failure 表示如果服务崩溃或因失败而终止,必须重新启动服务。 如果它被 systemd 停止,它将不会重新启动。
  • [Install] 部分包含有关服务的安装信息。 WantedBy=multi-user.target 告诉 systemd 在启动 multi-user.target 时启动服务。 这是在系统启动时启动服务的通用方式。

一旦服务描述到位,我们可以使用以下命令启动它:

sudo systemctl start nats

让我们通过发送 PING 消息来确认 gnatsd 正在运行:

printf "PING\r\n" | nc 127.0.0.1 4222

我们刚刚使用 ncgnatsd 进行通信。 nc 是一个命令行实用程序,用于与 TCP 或 UDP 服务器进行通信。 我们使用的命令会打印类似于以下内容的输出:

OutputINFO {"server_id":"Os7xI5uGlYFJfLlfo1vHox","version":"0.9.4","go":"go1.6.3","host":"127.0.0.1","port":4222,"auth_required":false,"ssl_required":false,"tls_required":false,"tls_verify":false,"max_payload":1048576}
PONG

响应 PONG 让我们知道服务器正在侦听并按预期工作。 我们需要运行最后一个命令以使我们的 NATS 服务器在启动时启动:

sudo systemctl enable nats

您将看到以下输出,确认该服务已安装:

OutputCreated symlink from /etc/systemd/system/multi-user.target.wants/nats.service to /etc/systemd/system/nats.service.

我们成功地将 gnatsd 配置为作为服务运行。 现在让我们保护它并使其可供外部客户端访问。

第 5 步 — 保护与 NATS 服务的连接

如果我们想与 gnatsd 一起使用的所有发布者和订阅者都运行在同一台服务器上,我们可以称之为完成并继续前进,但如今这种情况很少见。 我们需要让外部客户端以安全的方式连接并发布消息到 gnatsd

gnatsd 支持 TLS 传输,因此我们将使用它来保护 gnatsd 和 NATS 客户端之间的通信。

首先,我们需要一个证书。 您可以购买商业证书,从 Let's Encrypt 检索一个或生成自签名证书。 我们将使用后一种方法,因为获取证书超出了本文的范围。

创建一个目录来临时保存证书:

mkdir ~/priv

然后使用以下命令创建自签名证书:

openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
    -keyout priv/gnatsd.key -out priv/gnatsd.crt \
    -subj "/C=US/ST=Texas/L=Austin/O=AwesomeThings/CN=www.example.com"

此命令创建一个 2048 位和 10 年有效期的 RSA 证书。 请注意,我们使用了任意域名,因为我们不会在本文中为 gnatsd 服务器启用 TLS 验证。

您现在应该在 ~/priv 目录中拥有文件 gnatsd.keygnatsd.crt。 让我们将这些文件移动到我们的 /srv/nats/ 目录结构下,以便将所有内容放在一个位置。 执行以下命令:

sudo mv ~/priv /srv/nats

现在,使 /srv/nats/priv 只能由 nats 用户和组访问:

sudo chmod 440 /srv/nats/priv/*
sudo chmod 550 /srv/nats/priv
sudo chown -R nats:nats /srv/nats/priv

现在我们更新 /srv/nats/gnatsd.config 以包含我们刚刚创建的证书和密钥。 再次打开配置文件:

sudo nano /srv/nats/gnatsd.config

并添加以下部分来告诉 gnatsd 使用您的证书和密钥:

/srv/nats/gnatsd.config

. . .

tls {
  cert_file: "/srv/nats/priv/gnatsd.crt"
  key_file: "/srv/nats/priv/gnatsd.key"
  timeout: 1
}

保存文件并退出编辑器。 然后重新启动服务,以便它可以获取更改。

sudo systemctl restart nats

让我们测试一下我们的证书是否有效。 运行此命令:

printf "PING\r\n" | nc localhost 4222

这次,命令输出以下消息:

OutputINFO {"server_id":"npkIPrCE5Kp8O3v1EfV8dz","version":"0.9.4","go":"go1.6.3","host":"127.0.0.1","port":4222,"auth_required":false,"ssl_required":true,"tls_required":true,"tls_verify":false,"max_payload":1048576}

-ERR 'Secure Connection - TLS Required'

服务器返回消息 -ERR 'Secure Connection - TLS Required' 确认新配置已被拾取并且需要安全连接,而 nc 不知道该怎么做。

为了能够在不安装完整的 NATS 客户端的情况下与我们的 NATS 服务进行通信,我们将使用一个名为 catnats 的工具。 我们先下载它:

wget https://github.com/yuce/catnats/raw/0.1.2/catnats.py

并使其可执行:

chmod +x catnats.py

最后,将catnats.py移动到/srv/nats/bin文件夹并重命名为catnats

sudo mv catnats.py /srv/nats/bin/catnats

让我们通过发送与我们之前发送的相同的 PING 消息来检查我们是否可以使用 catnats 与我们的 NATS 服务通信:

printf "PING\r\n" | /srv/nats/bin/catnats --addr 127.0.0.1:4222

你会看到这个输出表明我们的连接是安全的:

OutputINFO {"server_id":"npkIPrCE5Kp8O3v1EfV8dz","version":"0.9.4","go":"go1.6.3","host":"127.0.0.1","port":4222,"auth_required":false,"ssl_required":true,"tls_required":true,"tls_verify":false,"max_payload":1048576}
PONG

现在我们已经保护了通信,让我们启用身份验证,以便需要用户名和密码才能连接到 NATS。

第 6 步 — 要求身份验证

我们的 NATS 服务默认不需要身份验证。 当服务只能在专用网络上访问时,这很好,但我们希望我们的 NATS 服务可以在 Internet 上访问,因此我们应该启用身份验证。 gnatsd支持用户名密码认证,开启方便。

打开/srv/nats/gnatsd.config文件:

sudo nano /srv/nats/gnatsd.config

添加指定凭据的新 authorization 部分。 我们将使用 user1 作为本教程的用户名和 pass1 作为密码。 您应该在生产环境中使用更长、更复杂的密码:

/srv/nats/gnatsd.config

. . .

authorization {
  user: user1
  password: pass1
}

保存文件,然后将 /srv/nats/gnatsd.config 的所有者更改为 nats 并使其可由该用户读取,以保护系统上其他用户的用户名和密码:

sudo chown nats /srv/nats/gnatsd.config
sudo chmod 400 /srv/nats/gnatsd.config

然后重新启动服务以使更改生效:

sudo systemctl restart nats

让我们向 gnatsd 发送 PING 消息,检查是否一切正常。 再次使用 catnats 发送消息:

printf "PING\r\n" | /srv/nats/bin/catnats --addr 127.0.0.1:4222

您将看到以下输出:

OutputNFO {"server_id":"sY0SSJBNbEw53HxzS9mH1t","version":"0.9.4","go":"go1.6.3","host":"127.0.0.1","port":4222,"auth_required":true,"ssl_required":true,"tls_required":true,"tls_verify":false,"max_payload":1048576}
-ERR 'Authorization Violation'

这告诉我们更改已成功应用,我们现在需要发送正确的用户名和密码才能连接到服务。 让我们再试一次,这次提供用户名 user1 和密码 pass1

printf "PING\r\n" | /srv/nats/bin/catnats --addr 127.0.0.1:4222 --user user1 --pass pass1

这次它起作用了,您可以从以下输出中看到:

OutputINFO {"server_id":"sY0SSJBNbEw53HxzS9mH1t","version":"0.9.4","go":"go1.6.3","host":"127.0.0.1","port":4222,"auth_required":true,"ssl_required":true,"tls_required":true,"tls_verify":false,"max_payload":1048576}
+OK
PONG

现在我们已经将此服务限制为知道用户名和密码的客户端,我们可以重新配置服务以便外部客户端可以连接。

第 7 步 — 向世界开放服务

我们已将 NATS 服务器配置为侦听 127.0.0.1,这是本地接口。 如果我们让它在 0.0.0.0 上收听,那么它将可供全世界使用。 让我们最后一次更新 /srv/nats/gnatsd.config

sudo nano /srv/nats/gnatsd.config

然后更改与 net 设置关联的 IP 地址:

/srv/nats/gnatsd.config

. . .
net: '0.0.0.0'
. . .

保存文件并重启服务:

sudo systemctl restart nats

现在我们的 NATS 服务已准备好用于外部客户端连接。 要了解如何使用它,让我们创建一个简单的监控服务,使用我们的 NATS 服务器作为消息代理。

步骤 8 —(可选)配置服务器过载通知

在本节中,您将创建一个使用 NATS 服务的简单过载监控系统。 如果任何服务器超载,系统将接收服务器的平均负载并将电子邮件发送给管理员。

示例项目将包含以下组件:

  • 您刚刚配置的 NATS 服务。
  • monitor,每 60 秒向 stats.loadaverage 主题发布服务器的主机名、平均负载和处理器计数。 您需要在要监控负载的任何服务器上运行此组件。
  • 一个 notifier,它订阅 stats.loadaverage 主题并接收服务器的主机名、平均负载和处理器计数。 如果主机的平均负载高于某个阈值,则通知器通过 SMTP 服务器将电子邮件发送到预定义的地址。

为简单起见,我们将在同一台服务器上运行所有这些组件,但完成本教程后,您可以尝试在不同的服务器上运行每个组件。

设置监视器

您可以从 /proc/loadavg 读取 Linux 系统上的平均负载。 对于这个项目,我们只对最后一分钟的负载平均值感兴趣,这是输出的第一个字段。 使用此命令获取该值:

cat /proc/loadavg | cut -f1 -d" "

您将看到以下输出:

Output0.11

通过读取 /proc/loadavg 获得的平均负载取决于处理器的数量,因此您必须通过将负载平均除以处理器数量来对其进行标准化。 您可以使用以下命令获取服务器的处理器计数:

getconf _NPROCESSORS_ONLN

您将在终端中看到结果:

Output1

由于我们服务器的默认 shell 无法处理浮点数运算,我们将发送平均负载和处理器数量以及主机名作为消息的有效负载,稍后在通知程序中进行除法。 这是我们将用于构建有效负载的命令:

echo $(hostname) `cat /proc/loadavg | cut -f1 -d" "` `getconf _NPROCESSORS_ONLN`

该命令分别显示主机名、平均负载和处理器数量:

Outputyour_hostname 0.28 1

让我们创建一个 shell 脚本,它将主机名、平均负载和处理器计数发布到我们的 NATS 服务器,主题为 stats.loadaverage。 我们将配置我们的系统以定期运行此脚本。 创建一个名为 ~/publish_load_average.sh 的新文件:

nano ~/publish_load_average.sh

在文件中,添加以下脚本:

~/publish_load_average.sh

NATS_ADDR=127.0.0.1:4222
LOADAVG=$(cat /proc/loadavg | cut -f1 -d" ")
NPROC=$(getconf _NPROCESSORS_ONLN)
SUBJECT="stats.loadaverage"
PAYLOAD=$(echo $(hostname) $LOADAVG $NPROC)
MESSAGE="PUB $SUBJECT ${#PAYLOAD}\r\n${PAYLOAD}\r\n"
printf "$MESSAGE" | /srv/nats/bin/catnats -q --raw --addr $NATS_ADDR --user user1 --pass pass1

此脚本创建消息,然后将其通过管道传送到 catnats,后者将消息发布到 NATS 服务。 我们使用 -q 开关运行 catnats 以抑制任何输出,并且我们使用 --raw 开关因此 catnats 不会尝试解释输入。 如果 NATS 服务位于不同的服务器上,您可以更改 $NATS_ADDR 变量的值。

让我们测试脚本是否将负载平均值发送到 NATS。

以下命令每 5 秒运行一次 ~/publish_load_average.sh。 请注意,我们在行尾使用 & 字符在后台运行命令:

while true; do sh ~/publish_load_average.sh; sleep 5; done &

您将看到输出显示该命令正在后台运行,并带有进程 ID:

Output[1] 14123

注意:在某处记下进程ID,因为稍后您将需要使用该ID来停止命令。


现在连接到 NATS 并订阅主题 stats.loadaverage 以检索负载平均值:

printf "SUB stats.loadaverage 0\r\n" | /srv/nats/bin/catnats --raw --no-exit --pong --user user1 --pass pass1

我们使用 --no-exit 标志来禁用自动退出,并使用 --pong 来保持与 NATS 的连接。 如果一切正确,您应该会得到类似于以下内容的输出,该输出将每 5 秒更新一次:

OutputINFO {"server_id":"A8qJc7mdTy8AWBRhPWACzW","version":"0.8.1","go":"go1.6.2","host":"0.0.0.0","port":4222,"auth_required":true,"ssl_required":true,"tls_required":true,"tls_verify":false,"max_payload":1048576}
+OK
+OK
MSG stats.loadaverage 0 27
your_hostname 0.08 1

CTRL+C退出catnats。 让我们也停止调用 publish_load_average.sh 的循环,因为我们将有更好的方式运行 publish_load_average.sh

kill 14123

我们刚刚采用的方法非常适合测试,但我们不想永久使用它。 我们希望系统运行 publish_load_average.sh 以每分钟运行一次。 为了实现这一点,我们可以添加一个 crontab 条目。 Linux 系统使用 cron,一个可以按照我们指定的时间表运行命令或“作业”的系统。 crontab 命令让我们管理这些作业。 您可以在教程 How To Use Cron To Automate Tasks On a VPS 中了解有关 Cron 的所有信息。

要创建新条目,请执行以下命令:

crontab -e

如果您从未运行过上述命令,您可能会看到以下提示,要求您选择文本编辑器来管理条目:

Outputno crontab for demo - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/ed
  2. /bin/nano        <---- easiest
  3. /usr/bin/vim.basic
  4. /usr/bin/vim.tiny

Choose 1-4 [2]:

键入与您最熟悉的编辑器相对应的数字,然后按 ENTER。 一个文件将显示在您选择的编辑器中。

在打开的文件末尾,添加以下行,但如果您使用的不是 sammy,请替换您的用户名:

*/1 * * * * bash /home/sammy/publish_load_average.sh

上面的条目告诉 cron 每分钟运行我们的 publish_load_average.sh 脚本。 保存文件并关闭编辑器。

现在让我们测试负载平均值的定期发布是否有效:

printf "SUB stats.loadaverage 0\r\n" | /srv/nats/bin/catnats --raw --no-exit --pong --user user1 --pass pass1

等待几分钟,您看到的输出将类似于以下内容:

OutputINFO {"server_id":"A8qJc7mdTy8AWBRhPWACzW","version":"0.8.1","go":"go1.6.2","host":"0.0.0.0","port":4222,"auth_required":true,"ssl_required":true,"tls_required":true,"tls_verify":false,"max_payload":1048576}
+OK
+OK
MSG stats.loadaverage 0 27
your_hostname 0.01 1
MSG stats.loadaverage 0 27
your_hostname 0.00 1

CTRL+C退出catnats

我们已经成功设置了监视器,它正在向我们的 NATS 服务器发送消息。 接下来,我们将设置使用此数据的通知程序。

创建通知程序

让我们创建连接到我们的 NATS 服务并侦听 stats.loadaverage 消息的通知程序。 每当我们的程序收到消息时,它都会计算每个处理器的平均负载。 如果它高于 0.6,即每个处理器的 CPU 利用率为 60%,它会为发布消息的主机设置一个警告标志,并将电子邮件发送到预定义的地址。 如果每个处理器的平均负载小于 0.4,则清除主机的警告标志。 为防止收件箱泛滥,我们会在设置警告标志时发送一封电子邮件。

我们将使用 Node.JS 创建通知程序,因为 Node.js 有一个很棒的 NATS 客户端。 所以,首先安装 Node.js:

sudo apt-get install -y npm

接下来,为通知程序创建目录并切换到它:

mkdir ~/overload_notifier && cd ~/overload_notifier

Node.js 项目使用一个名为 package.json 的文件,其中包含有关项目及其依赖项的信息。 执行以下命令来创建该文件:

npm init -y

然后安装 Node.js 的 NATS 客户端,以及我们将在这个项目中使用的 nodemailer 模块来发送警告电子邮件:

npm install nodemailer@2.4.2 nats@0.6.4 --save-exact

现在我们可以创建通知程序了。 创建文件 notifier.js

nano notifier.js

然后将以下代码添加到文件中:

通知程序.js

var NATS_URL = 'nats://127.0.0.1:4222';
var NATS_USER = 'user1';
var NATS_PASS = 'pass1';
var EMAIL_TO = 'admin@example.com';

请务必更改这些选项以匹配您的 NATS 服务的用户名和密码,以及您的电子邮件地址。

接下来,添加此代码以导入 Node.js NATS 客户端并连接到 gnatsd 服务:

通知程序.js

var tlsOptions = {
  rejectUnauthorized: false,
};
var nats = require('nats').connect({url: NATS_URL,
                                    tls: tlsOptions,
                                    user: NATS_USER,
                                    pass: NATS_PASS});

然后添加此代码以设置邮件程序并连接到将发送电子邮件的 SMTP 服务器。 我们很快就会设置这个服务器:

通知程序.js

var nodemailer = require('nodemailer');
var transport = nodemailer.createTransport('smtp://localhost:2525');

然后添加其余代码来计算平均负载并确定我们是否需要发送通知电子邮件:

通知程序.js

// keep the state of warnings for each host
var warnings = {};

function sendEmail(subject, text) {
    transport.sendMail({
        to: EMAIL_TO,
        subject: subject,
        text: text
    });
}

function processMessage(message) {
    // message fields: host load processor_count
    var fields = message.split(" ");
    var host = fields[0];
    var loadAverage = parseFloat(fields[1]) / parseInt(fields[2]);
    if (loadAverage > 0.6) {
        if (!warnings[host]) {
            // send warning email if one wasn't already sent
            var res = sendEmail('Warning! Server is Overloaded: ' + host,
                                'Load average: ' + loadAverage);
            // set warning for the host
            warnings[host] = true;
        }
    }
    else if (loadAverage < 0.4) {
        if (warnings[host]) {
            // clear the warning
            warnings[host] = false;
        }
    }
}

nats.subscribe('stats.loadaverage', processMessage);

我们订阅消息,每次收到消息时,我们都会执行 processMessage 函数,它会解析我们发送的有效负载并确定平均负载。 如果它太高,我们发送消息,并通过设置基于主机名的标志来跟踪我们之前是否发送过消息。 这样我们就可以在每个主机的基础上跟踪通知。 如果平均负载低于我们的阈值,我们清除该标志。

有了监视器和通知程序,就可以测试我们的示例项目了。

测试项目

让我们来试驾一下。 我们将生成一些人工负载,并检查通知程序是否会在负载过高时发送警告电子邮件。

让我们安装 stress 工具来在我们的服务器上生成 CPU 负载:

sudo apt-get install -y stress

接下来,我们需要设置一个 SMTP 服务器以邮寄来自我们的通知程序的消息。 安装和配置一个成熟的 SMTP 服务器对于这个测试来说是多余的,所以我们将使用一个简单的 SMTP 服务器,它只显示发送给它的电子邮件,而不是实际发送它们。 Python 编程语言有一个 DebuggingServer 模块,我们可以加载它丢弃它收到的电子邮件,但将它们显示在屏幕上,这样我们就可以确保一切正常。 Python 已经安装在我们的 Ubuntu 服务器上,所以这是一个完美的解决方案。

让我们在后台启动调试 SMTP 服务器。 我们将让它监听 localhost 端口 2525,它与我们在 notifier.js 代码中配置的 SMTP 地址相匹配。 执行以下命令启动 SMTP 服务器:

python -m smtpd -n -c DebuggingServer localhost:2525 &

然后使用以下命令在后台启动通知程序:

nodejs ~/overload_notifier/notifier.js &

最后,让我们在服务器的所有处理器上产生一些负载。 使用以下选项执行 stress 命令:

stress --cpu $(getconf _NPROCESSORS_ONLN)

几分钟后,您将看到类似于以下内容的输出,因为 SMTP 服务器开始显示通知程序发送的消息:

Output---------- MESSAGE FOLLOWS ----------
Content-Type: text/plain
To: admin@example.com
Subject: Warning! Server is Overloaded: your_hostname
Message-Id: <1466354822129-04c5d944-0d19670b-780eee12@localhost>
X-Mailer: nodemailer (2.4.2; +http://nodemailer.com/;
 SMTP/2.5.0[client:2.5.0])
Content-Transfer-Encoding: 7bit
Date: Sun, 19 Jun 2016 16:47:02 +0000
MIME-Version: 1.0
X-Peer: 127.0.0.1

Load average: 0.88
------------ END MESSAGE ------------

当服务器上的负载过高时,这可以让您知道您已成功发送电子邮件。

CTRL+C停止产生负载。 您已经完成了示例项目,现在应该知道如何在您自己的环境中为您工作。

结论

在本文中,您了解了 NATS PubSub 消息传递系统,以安全的方式将其安装为服务,并在示例项目中对其进行了测试。 示例项目使用了 Node.JS 客户端,但 NATS 有更多语言和框架的客户端,您可以在 NATS 下载页面 上找到这些客户端。 您可以在其官方文档中了解更多关于NATS的信息。