红联Linux门户
Linux帮助

如何在Ubuntu 16.04上安装和配置NATS

发布时间:2017-08-10 11:06:17来源:oschina作者:startkknd,昌伟兄,POT
介绍
NATS是一个开源且高性能的消息系统,它常常被认为是"一个为云服务的中央神经系统".它每秒钟可以传送百万条消息,所以非常适合用来连接微服务和IOT设备。
NATS是一个发布订阅方式的消息系统。在这类系统中,一个或多个消息发布者将特定的主题发送给一个消息中介者,然后消息中介者再将消息分发给任意客户端(或者这个主题的订阅者)。消息发布者不知道也不关心消息订阅者是谁,反之依然。由于我们可以在不影响系统其它部分的情况下增加新的消息发布者和订阅者,这样的架构使得系统的伸缩性变得很好并且可以比较容易地增加系统的容量。这种类型的系统非常适合用来监测服务器和终端设备;终端设备可以发送消息,我们可以订阅这些消息,然后通过邮件或者其他的方式发送消息通知。
在本教程中,我们会安装官方的NATS服务器gnatsd,gnatsd可以提供服务,而且可以以相对安全的方式被访问。我们也会创建一个基本的服务端过载警告系统,它使用gnatsd作为消息中介者,在服务器负载过大时向外部发送邮件。
 
先决条件
要完整地学习本篇教程,你需要:
一个新的Ubuntu 16.04服务器。
一个具有sudo权限的标准用户账号。你可以参考初始化Ubuntu 16.04服务器设置(https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04)进行标准账号的设置。
 
第一步 — 下载NATS服务器
首先,我们要下载gnatsd服务器,并确保能正确无误地在我们的系统上运行。
编写本教程时,最新的gnatsd稳定版本是0.9.4。你可以查看NATS download page(http://nats.io/download) 以获取最新版,根据你的需要,如果你想使用更新的版本的话,可以键入下面的命令。
首先,使用非root账号登录到你的服务器:
ssh sammy@your_server_ip
然后,确保当前目录为自己的用户home目录:
cd
接着,使用wget命令将gnatsd下载到你的服务器:
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 --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监听的端口是4222,监听的地址是0.0.0.0(即所有接口)。使用--port参数,你可以改变端口,使用--addr可以改变监听的地址。我们使用--addr 127.0.0.1参数运行gnatsd,意思是仅仅在我们自己的服务器上可用,而外部的客户端无法访问。在后面的教程中,我们将提高gnatsd的安全性,使得全世界都可以访问它。
键入CTRL+C关闭gnatsd。
既然你已经知道了gnatsd的使用方法,那么我们就来用更正式的方式对其进行设置。
 
第二步 — 创建目录结构和配置文件
在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
Output
Adding 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赋值给nats系统用户。这样的话系统用户就不能登录和创建根文件夹。同时我们创建了一个nats组。
我们现在让nats用户和组拥有/srv文件夹:
sudo chown -R nats:nats /srv
我们已经创建好了nats用户和组,下面继续创建NATS服务。
 
第四步 — 使gnatsd作为一个服务来运行
我们希望gnatsd能在系统启动时以及系统崩溃重启时自动运行。可以使用systemd来处理这个问题。
systemd是Linux系统中的服务管理器。它负责在系统启动时开启服务,根据需要重启服务以及在系统关闭时以一种可控的方式关闭服务。
为了定义如何以及何时启动NATS服务,我们需要创建一个服务配置文件。用户创建的服务文件位于/etc/systemd/system,因此创建文件:
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
我们刚刚使用了nc来和gnatsd通信。nc是一个命令行工具,它可以和TCP或UDP服务器通信。我们使用的命令会打印类似下面这样的输出:
Output
INFO {"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
你会看到下面的输出,这就确保了服务已被安装:
Output
Created symlink from /etc/systemd/system/multi-user.target.wants/nats.service to /etc/systemd/system/nats.service.
我们成功地配置了gnatsd作为一个服务来运行。现在我们配置其安全性,使它可以被外部客户端访问。
 
第五步 — 到 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.key 和 gnatsd.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
这一次,命令会输出下面的信息:
Output
INFO {"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
可以看到下面的输出则表明连接是安全的:
Output
INFO {"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 时需要用户名和密码。
 
第六步 — 要求身份认证
默认情况下 NATS 服务没有要求身份认证。只是在私网中访问服务的时候是没有问题的,但是要让 NATS 服务在互联网上可访问就应该启用身份认证。gnatsd 支持用户名和密码的认证,很容易启用。
打开  /srv/nats/gnatsd.config 文件:
sudo nano /srv/nats/gnatsd.config
添加一个新的认证部分来指定凭据。这里使用 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
发送一个 PING 消息到 gnatsd 来检查是否万事大吉。再一次,使用 catnats 来发送消息:
printf "PING\r\n" | /srv/nats/bin/catnats --addr 127.0.0.1:4222
可以看到以下输出:
Output
NFO {"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
如果看到下面的输出,就表示可以正常工作了:
Output
INFO {"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
现在已经将服务限制为知道用户名和密码的客户端才能连接,接下来可以再配置一下服务使得外部客户端可以连接。
 
第七步 —  向全世界开放服务
我们配置了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服务器作为消息的发布者。
 
第八步 — (可选) 配置服务器过载通知
在本节中,将利用NATS服务创建一个简单的过载监控系统。系统将会收到每个服务器的平均负载并在任一服务器过载时向管理员发送邮件。
示例项目由以下几部分组成:
配置的NATS服务。
一个监控器,它将会每60秒向 stats.loadaverage 主体发布服务器的主机名、平均负载以及处理器数量。在所有需要监控负载的服务器上都需要运行这个组件。
一个通知器,它从 stats.loadaverage 主体接收服务器的主机名、平均负载以及处理器数量。如果某一主机的平均负载超过某一阈值时,通知器会发送邮件到预设地址的SMTP服务器。  
为了简单起见,我们把所有组件都运行在同一台服务器上,不过在完成这个教程之后,你可以尝试将每个组件运行在不同的服务器上。
 
设置监控器
在Linux系统中,可以从 /proc/loadavg 文件中读取平均负载。在这个项目中,我们只对最后一分钟的平均负载感兴趣(输出中的第一个字段)。可以使用下面这个命令获取这个值:
cat /proc/loadavg | cut -f1 -d" "
输出如下:
Output
0.11
由于通过读取 /proc/loadavg 文件来获取到的平均负载是依赖于处理器数量的,所以要用平均负载除以处理器数量来获取一个标准值。 可以使用下面这个命令来获取服务器的处理器数量:
getconf _NPROCESSORS_ONLN
终端上显示的结果如下:
Output
1
由于服务器的默认shell无法处理浮点数计算,所以同时将平均负载和处理器数量连同主机名一起作为消息的内容发送出去,稍后在通知器中再做消息内容的拆分。下面是用来构造消息内容的命令:
echo $(hostname) `cat /proc/loadavg | cut -f1 -d" "` `getconf _NPROCESSORS_ONLN`
命令会分别显示主机名、平均负载和处理器数量:
Output
your_hostname 0.28 1
下面创建一个shell脚本来向具有 stats.loadaverage 主体的NATS服务器发布主机名、平均负载以及处理器数量。这个脚本需要通过系统配置来定时执行。创建一个名为~/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服务)。运行 catnats 命令时,使用 -q 开关来关闭输出,使用 --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秒更新一次):
Output
INFO {"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(https://www.digitalocean.com/community/tutorials/how-to-use-cron-to-automate-tasks-on-a-vps) 中了解到关于 Cron 的一切。
执行这个命令来创建一个新的条目:
crontab -e
如果之气从没执行过上面这条命令,你将会看到下面这个请你选择一个文本编辑器来管理条目的提示:
Output
no 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]:
键入你用起来感觉最舒服的编辑器对应的数字,然后回车。一个文件的内容会显示在刚才选择的编辑器中。
在打开的文件末尾添加下面的这一行内容,但是如果你使用了和 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
等几分钟,就可以看到类似下面的输出:
Output
INFO {"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
然后将下面的代码添加到文件中:
notifier.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 服务:
notifier.js
var tlsOptions = {
rejectUnauthorized: false,
};
var nats = require('nats').connect({url: NATS_URL,
tls: tlsOptions,
user: NATS_USER,
pass: NATS_PASS});
然后添加下面的代码来设置发件人并连接到发送邮件的 SMTP 服务器。可以很快地设置好这个服务器:
notifier.js
var nodemailer = require('nodemailer');
var transport = nodemailer.createTransport('smtp://localhost:2525');
然后添加余下的代码来计算平均负载,并确定是否需要发送一封通知邮件:
notifier.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 模块来丢弃收到的邮件,但是可以将邮件显示在屏幕上,这样就可以确认项目是否正常工作了。Ubuntu 服务器已经安装了 Python,所以这是一个完美的解决方案。
在后台启动调试 SMTP 服务器。可是使其监听之前在 notifier.js 代码中配置的 SMTP 地址——本地的 2525 端口。执行下面这个命令来启动 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发布订阅消息系统,把该系统作为一个服务,用一种安全的方式安装它,并在一个示例项目里做测试。这个示例项目使用了Node.JS客户端,但是NATS还有其他的客户端。这些客户端使用了其他的语言和框架,你可以通过NATS download page(http://nats.io/download)查看。你也可以通过官方文档official documentation(http://nats.io/documentation/)学习到更多知识。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/32280.html