1. 简介

memberlist 是 Hashicorp 公司开源的 Gossip 库,该库被 Consul 使用,它是 SWIM(THE SWIM MEMBERSHIP PROTOCOL)的扩展实现。


2. 示例

main.go:

go.mod:

在第一个窗口执行:

可看到类似下面的输出:

注意其中的 Local member,后面要用到

在第二个窗口执行:

在第三个窗口执行:

在第四个窗口执行:


3. 基本过程

3.1. 状态

节点的状态有三种:

memberlist.jpeg

1)如果节点 B 无法对节点 A 发出的 PingMsg 进行响应,或响应超时,那么它将被节点 A 标记为 suspect。如果 suspect 持续一段时间(或 A 收到足够多的其它节点关于 B 的 SuspectMsg),节点 A 会在集群中广播 SuspectMsg,告知集群中其它节点:节点 B 很可疑

2)如果节点 B 收到针对它的 SuspectMsg,那么它通过发送 AliveMsg,告知对方:“I'm alive”。在对方节点看来,B 的状态从 suspect 变为 alive

3)如果一段时间内,节点 B 的状态仍然是 suspect,那么对于节点 A 而言,B 的状态会被置为 dead

4)一段时间后,如果节点 B 重新上线,那么它可以通过与种子节点的 Gossip(Push/Pull)重新被认为 alive

3.2. 动作

memberlist 的所有动作都可以在 schedule() 中看到,动作共有 3 种。

state.go:

3.2.1. 动作 1 probe

周期性地探测集群中状态为 alive 和 suspect 的节点。每个周期只探测一个节点。

3.2.2. 动作 2 Push/Pull

周期性地从已知 alive 的集群节点中选择 1 个节点,进行 Push/Pull 交换信息。交换的信息包括两种:

3.2.3. 动作 3 Gossip

广播所有 dead 节点(只广播一次)

3.3. 注意


4. 种子节点的配置

集群中有 A、B、C 三个节点,其中 A 为种子节点,B 和 C 为普通节点。

gossip-seed.png

为避免该问题,需要多配置种子节点,并保证所有种子节点不同时宕机。


参考文档