介绍
Serf 是一种分散式服务编排和服务发现工具,具有极大的错误耐受性和分散性,没有像其他类似工具一样的单一故障点。 Serf 可用于在系统群中触发任何事件,以及执行监控任务。它是建立在 Gossip 协议的顶部,该协议是专为分散式通信而设计的。为了让节点加入 Serf 群集,节点只需要最初知道群集中的另一个节点的地址。一旦节点加入,所有会员信息都在群集中传播。
使用多个VPS
Serf 旨在在多个 VPS 和机器上运行,兼容 nix、 windows 和 Mac OS 系统,本教程将向您展示如何在两个不同的 Ubuntu 服务器上设置 Serf。
在本教程中,服务器将被命名为 SerfNode1和 SerfNode2.您需要知道每个服务器的IP地址;以下IP地址用于代表本教程中的每个VPS。
2.2.2
安装服务器
这将需要在 SerfNode1和 SerfNode2上进行。
下载最新服务包:
1wget https://dl.bintray.com/mitchellh/serf/0.3.0_linux_amd64.zip
安装 unzip 工具来解码包:
1apt-get install unzip
删除 Serf 包:
1unzip 0.3.0_linux_amd64.zip
将 Serf 添加到二进制目录中,这样它可以从任何地方执行:
1mv serf /usr/local/bin
创建一个 Serf 集群
在 SerfNode1上启动第一个Serf节点:
1serf agent -node=**SerfNode1** -bind=1.1.1.1:7496
你应该看到一些类似于下面的输出:
1==> Starting Serf agent...
2==> Starting Serf agent RPC...
3==> Serf agent running!
4 Node name: '**SerfNode1**'
5 Bind addr: '1.1.1.1:7496'
6 RPC addr: '127.0.0.1:7373'
7 Encrypted: false
8 Snapshot: false
9 Profile: lan
10
11==> Log data will now stream in as it occurs:
12
13 2014/01/18 21:57:57 [INFO] Serf agent starting
14 2014/01/18 21:57:57 [WARN] Binding to public address without encryption!
15 2014/01/18 21:57:57 [INFO] serf: EventMemberJoin: **SerfNode1** 1.1.1.1
16 2014/01/18 21:57:58 [INFO] agent: Received event: member-join
注意:节点参数指定节点的名称, bind 表示要连接的 IP 地址和端口。
在 SerfNode2上,我们将在后台启动 Serf 代理:
1serf agent -node=**SerfNode2** -bind=2.2.2.2:7497 -rpc-addr=127.0.0.1:7373 &
注意:&
表示要在背景中执行命令
请告诉 SerfNode2加入 SerfNode1:
1serf join 1.1.1.1:7496
你应该看到类似于以下的输出:
1...
2 2014/01/18 22:03:04 [INFO] serf: EventMemberJoin: **SerfNode2** 2.2.2.2
3 2014/01/18 22:03:05 [INFO] agent: Received event: member-join1922
4...
很棒!你现在有一个小型工作SERF集群。为了设置额外的服务器,你只需要重复我们在 SerfNode2上所做的过程。为了加入SERF集群,你只需要指示VPS加入另一个SERF代理已经在集群中。
事件和事件处理
Serf 是如此惊人的另一个原因是事件处理是多么容易. 让我们先将事件发送到集群。
发送简单的用户事件
在 SerfNode2上,执行以下命令:
1serf event hello
在 SerfNode1上,你应该看到类似于此的东西:
12014/01/16 15:48:05 [INFO] agent: Received event: user-event: hello
Woot!我们刚刚将我们的第一个事件发送到群集中,好吧,这很酷,但这个事件真的没有什么好处。
创建定制事件处理器
现在我们将配置一些自定义事件处理。Serf可以在集群中触发自定义事件,以便启动部署,安全更新,系统配置等。
让我们从一个简单的例子开始。
在 SerfNode1上,通过按 Ctrl + C 停止 Serf 代理,它应该为您提供下面的输出:
12014/01/16 15:58:54 [INFO] agent: requesting serf shutdown
2 2014/01/16 15:58:54 [WARN] Shutdown without a Leave
3 2014/01/16 15:58:54 [INFO] agent: shutdown complete
现在我们将创建一个自定义事件脚本,将写到文件
写入 /usr/src 目录中的文本文件. 当用户发送写
事件时,它将执行该脚本。
事件处理器可以是任何可执行的文件 - 在我们的情况下,我们将使用 bash 文件。
转到 /usr/src 目录:
1cd /usr/src
打开Nano:
1nano handler.sh
使用以下脚本为事件处理器:
1#!/bin/bash
2if [ "${SERF_USER_EVENT}" = "write" ]; then
3 echo "written to file" >> test.txt
4fi
5
6echo "${SERF_USER_EVENT}"
注意: ${SERF_USER_EVENT} 是我们发送的 evnt 的名称,请注意如何使用 if 语句来设置不同的事件。
按 CTRL + X 來輸出 nano
按下 Y 以保存
点击进入
使脚本可执行:
1chmod +x handler.sh
现在我们将重新启动Serf代理,但这次我们将使用我们刚刚创建的事件处理器:
1serf agent -log-level=debug -event-handler=./handler.sh -node=**SerfNode1** -bind=1.1.1.1:7496
(可选步骤)
如果您想为 SerfNode2设置一个自定义事件处理器,您只需执行与 SerfNode1相同的事件处理器创建过程,或者您可以将事件处理器脚本复制到 SerfNode2服务器的 /usr/src 目录并执行以下命令:
在 SerfNode2上,离开 Serf 群集:
1serf leave
导航到 /usr/src 目录:
1cd /usr/src
使用自定义事件处理器在背景中启动 Serf 代理:
1serf agent -log-level=debug -event-handler=./handler.sh -node=**SerfNode2** -bind=2.2.2.2:7496 &
测试事件处理器
在 SerfNode2上,重新加入 SerfNode1:
1serf join 1.1.1.1:7496
执行以下命令:
1serf event write
在 SerfNode1上,切换到 /usr/src directoy:
1cd /usr/src
现在你应该在 directoy 中看到 test.txt 文件. 这个文件是当我们从 SerfNode2中触发 Serf 事件时创建的。
设置免费记忆监控
我们将设置一个自定义事件处理器,将服务器群中的免费内存记录到中央服务器上。
在 SerfNode1上,按 Ctrl + C 离开 Serf 集群。
请确保您在 /usr/src 目录中:
1cd /usr/src
打开 handler.sh 脚本:
1nano handler.sh
将脚本更改为如下:
1#!/bin/bash
2if [ "${SERF_USER_EVENT}" = "mem" ]; then
3 serf event memresponse "$(awk '/MemTotal/ {printf( "%.2f\n", $2 / 1024 ) }' /proc/meminfo) MB from $(wget -qO- http://ipecho.net/plain ; echo) at $(date)"
4fi
按 CTRL + X 來輸出 nano
按下 Y 以保存
点击进入
此脚本将触发 Serf 事件,该事件将以以下格式返回虚拟服务器上的免费内存:
1490 MB from 1.1.1.1 at Sun Jan 19 00:37:22 EST 2014
现在我们需要一种方法来在VPS上登录这一点
在 SerfNode2上,离开 Serf 群集:
1serf leave
请确保您在 /usr/src 目录中:
1cd /usr/src
创建一个操作脚本:
1nano handler.sh
使用以下为脚本:
1#!/bin/bash
2if [ "${SERF_USER_EVENT}" = "memresponse" ]; then
3 cat >> mem.txt
4 echo "\n" >> mem.txt
5fi
按 CTRL + X 來輸出 nano
按下 Y 以保存
点击进入
使脚本可执行:
1chmod +x handler.sh
在 SerfNode1上启动代理:
1serf agent -log-level=debug -event-handler=./handler.sh -node=**SerfNode1** -bind=1.1.1.1:7496
在 SerfNode2上启动代理:
1serf agent -log-level=debug -event-handler=./handler.sh -node=**SerfNode2** -bind=2.2.2.2:7496 &
在 SerfNode2上,重新加入 SerfNode12:
1serf join 1.1.1.1:7496
引发妈妈
事件:
1serf event mem
查看 mem.txt 文件:
1nano mem.txt
现在你有一个功能齐全的内存监控工具,可以分布在多个虚拟服务器上。
Serf 事件详情
以下是创建自定义事件处理脚本时有用的变量,这些变量直接来自 Serf 网站。
SERF_EVENT
是正在发生的事件类型。这将是会员加入、会员离开、会员失败或用户。SERF_SELF_NAME
是执行事件处理器的节点的名称。SERF_SELF_ROLE
是执行事件处理器的节点的角色。SERF_USER_EVENT
是如果SERF_EVENT
是用户
的用户事件类型的名称。
当一个事件被触发时,事件命令的布局如下:
1serf event [SERF_EVENT_NAME] [PAYLOAD]
- 效能负载是事件名称之后的任何东西. 效能负载被脚本解释为 stdin.
- 使用自定义用户事件时,应使用 SERF_USER_EVENT 变量而不是 SERF_EVENT 变量。
结论
Serf 是一个很好的方式来触发各种机器的事件,它是简单的、轻量级的、耐错误的,除了这些功能之外,它是非常分散的,没有任何一个故障点。一些例子使用案例包括:系统配置、部署、安全更新、消息广播和服务器监控。
关于 Serf 的更多信息和文档可以找到 这里。