1package memberlist 2 3import ( 4 "io" 5 "log" 6 "os" 7 "time" 8) 9 10type Config struct { 11 // The name of this node. This must be unique in the cluster. 12 Name string 13 14 // Configuration related to what address to bind to and ports to 15 // listen on. The port is used for both UDP and TCP gossip. 16 // It is assumed other nodes are running on this port, but they 17 // do not need to. 18 BindAddr string 19 BindPort int 20 21 // Configuration related to what address to advertise to other 22 // cluster members. Used for nat traversal. 23 AdvertiseAddr string 24 AdvertisePort int 25 26 // ProtocolVersion is the configured protocol version that we 27 // will _speak_. This must be between ProtocolVersionMin and 28 // ProtocolVersionMax. 29 ProtocolVersion uint8 30 31 // TCPTimeout is the timeout for establishing a TCP connection with 32 // a remote node for a full state sync. 33 TCPTimeout time.Duration 34 35 // IndirectChecks is the number of nodes that will be asked to perform 36 // an indirect probe of a node in the case a direct probe fails. Memberlist 37 // waits for an ack from any single indirect node, so increasing this 38 // number will increase the likelihood that an indirect probe will succeed 39 // at the expense of bandwidth. 40 IndirectChecks int 41 42 // RetransmitMult is the multiplier for the number of retransmissions 43 // that are attempted for messages broadcasted over gossip. The actual 44 // count of retransmissions is calculated using the formula: 45 // 46 // Retransmits = RetransmitMult * log(N+1) 47 // 48 // This allows the retransmits to scale properly with cluster size. The 49 // higher the multiplier, the more likely a failed broadcast is to converge 50 // at the expense of increased bandwidth. 51 RetransmitMult int 52 53 // SuspicionMult is the multiplier for determining the time an 54 // inaccessible node is considered suspect before declaring it dead. 55 // The actual timeout is calculated using the formula: 56 // 57 // SuspicionTimeout = SuspicionMult * log(N+1) * ProbeInterval 58 // 59 // This allows the timeout to scale properly with expected propagation 60 // delay with a larger cluster size. The higher the multiplier, the longer 61 // an inaccessible node is considered part of the cluster before declaring 62 // it dead, giving that suspect node more time to refute if it is indeed 63 // still alive. 64 SuspicionMult int 65 66 // PushPullInterval is the interval between complete state syncs. 67 // Complete state syncs are done with a single node over TCP and are 68 // quite expensive relative to standard gossiped messages. Setting this 69 // to zero will disable state push/pull syncs completely. 70 // 71 // Setting this interval lower (more frequent) will increase convergence 72 // speeds across larger clusters at the expense of increased bandwidth 73 // usage. 74 PushPullInterval time.Duration 75 76 // ProbeInterval and ProbeTimeout are used to configure probing 77 // behavior for memberlist. 78 // 79 // ProbeInterval is the interval between random node probes. Setting 80 // this lower (more frequent) will cause the memberlist cluster to detect 81 // failed nodes more quickly at the expense of increased bandwidth usage. 82 // 83 // ProbeTimeout is the timeout to wait for an ack from a probed node 84 // before assuming it is unhealthy. This should be set to 99-percentile 85 // of RTT (round-trip time) on your network. 86 ProbeInterval time.Duration 87 ProbeTimeout time.Duration 88 89 // DisableTcpPings will turn off the fallback TCP pings that are attempted 90 // if the direct UDP ping fails. These get pipelined along with the 91 // indirect UDP pings. 92 DisableTcpPings bool 93 94 // GossipInterval and GossipNodes are used to configure the gossip 95 // behavior of memberlist. 96 // 97 // GossipInterval is the interval between sending messages that need 98 // to be gossiped that haven't been able to piggyback on probing messages. 99 // If this is set to zero, non-piggyback gossip is disabled. By lowering 100 // this value (more frequent) gossip messages are propagated across 101 // the cluster more quickly at the expense of increased bandwidth. 102 // 103 // GossipNodes is the number of random nodes to send gossip messages to 104 // per GossipInterval. Increasing this number causes the gossip messages 105 // to propagate across the cluster more quickly at the expense of 106 // increased bandwidth. 107 GossipInterval time.Duration 108 GossipNodes int 109 110 // EnableCompression is used to control message compression. This can 111 // be used to reduce bandwidth usage at the cost of slightly more CPU 112 // utilization. This is only available starting at protocol version 1. 113 EnableCompression bool 114 115 // SecretKey is used to initialize the primary encryption key in a keyring. 116 // The primary encryption key is the only key used to encrypt messages and 117 // the first key used while attempting to decrypt messages. Providing a 118 // value for this primary key will enable message-level encryption and 119 // verification, and automatically install the key onto the keyring. 120 // The value should be either 16, 24, or 32 bytes to select AES-128, 121 // AES-192, or AES-256. 122 SecretKey []byte 123 124 // The keyring holds all of the encryption keys used internally. It is 125 // automatically initialized using the SecretKey and SecretKeys values. 126 Keyring *Keyring 127 128 // Delegate and Events are delegates for receiving and providing 129 // data to memberlist via callback mechanisms. For Delegate, see 130 // the Delegate interface. For Events, see the EventDelegate interface. 131 // 132 // The DelegateProtocolMin/Max are used to guarantee protocol-compatibility 133 // for any custom messages that the delegate might do (broadcasts, 134 // local/remote state, etc.). If you don't set these, then the protocol 135 // versions will just be zero, and version compliance won't be done. 136 Delegate Delegate 137 DelegateProtocolVersion uint8 138 DelegateProtocolMin uint8 139 DelegateProtocolMax uint8 140 Events EventDelegate 141 Conflict ConflictDelegate 142 Merge MergeDelegate 143 Ping PingDelegate 144 Alive AliveDelegate 145 146 // DNSConfigPath points to the system's DNS config file, usually located 147 // at /etc/resolv.conf. It can be overridden via config for easier testing. 148 DNSConfigPath string 149 150 // LogOutput is the writer where logs should be sent. If this is not 151 // set, logging will go to stderr by default. You cannot specify both LogOutput 152 // and Logger at the same time. 153 LogOutput io.Writer 154 155 // Logger is a custom logger which you provide. If Logger is set, it will use 156 // this for the internal logger. If Logger is not set, it will fall back to the 157 // behavior for using LogOutput. You cannot specify both LogOutput and Logger 158 // at the same time. 159 Logger *log.Logger 160} 161 162// DefaultLANConfig returns a sane set of configurations for Memberlist. 163// It uses the hostname as the node name, and otherwise sets very conservative 164// values that are sane for most LAN environments. The default configuration 165// errs on the side of caution, choosing values that are optimized 166// for higher convergence at the cost of higher bandwidth usage. Regardless, 167// these values are a good starting point when getting started with memberlist. 168func DefaultLANConfig() *Config { 169 hostname, _ := os.Hostname() 170 return &Config{ 171 Name: hostname, 172 BindAddr: "0.0.0.0", 173 BindPort: 7946, 174 AdvertiseAddr: "", 175 AdvertisePort: 7946, 176 ProtocolVersion: ProtocolVersion2Compatible, 177 TCPTimeout: 10 * time.Second, // Timeout after 10 seconds 178 IndirectChecks: 3, // Use 3 nodes for the indirect ping 179 RetransmitMult: 4, // Retransmit a message 4 * log(N+1) nodes 180 SuspicionMult: 5, // Suspect a node for 5 * log(N+1) * Interval 181 PushPullInterval: 30 * time.Second, // Low frequency 182 ProbeTimeout: 500 * time.Millisecond, // Reasonable RTT time for LAN 183 ProbeInterval: 1 * time.Second, // Failure check every second 184 DisableTcpPings: false, // TCP pings are safe, even with mixed versions 185 186 GossipNodes: 3, // Gossip to 3 nodes 187 GossipInterval: 200 * time.Millisecond, // Gossip more rapidly 188 189 EnableCompression: true, // Enable compression by default 190 191 SecretKey: nil, 192 Keyring: nil, 193 194 DNSConfigPath: "/etc/resolv.conf", 195 } 196} 197 198// DefaultWANConfig works like DefaultConfig, however it returns a configuration 199// that is optimized for most WAN environments. The default configuration is 200// still very conservative and errs on the side of caution. 201func DefaultWANConfig() *Config { 202 conf := DefaultLANConfig() 203 conf.TCPTimeout = 30 * time.Second 204 conf.SuspicionMult = 6 205 conf.PushPullInterval = 60 * time.Second 206 conf.ProbeTimeout = 3 * time.Second 207 conf.ProbeInterval = 5 * time.Second 208 conf.GossipNodes = 4 // Gossip less frequently, but to an additional node 209 conf.GossipInterval = 500 * time.Millisecond 210 return conf 211} 212 213// DefaultLocalConfig works like DefaultConfig, however it returns a configuration 214// that is optimized for a local loopback environments. The default configuration is 215// still very conservative and errs on the side of caution. 216func DefaultLocalConfig() *Config { 217 conf := DefaultLANConfig() 218 conf.TCPTimeout = time.Second 219 conf.IndirectChecks = 1 220 conf.RetransmitMult = 2 221 conf.SuspicionMult = 3 222 conf.PushPullInterval = 15 * time.Second 223 conf.ProbeTimeout = 200 * time.Millisecond 224 conf.ProbeInterval = time.Second 225 conf.GossipInterval = 100 * time.Millisecond 226 return conf 227} 228 229// Returns whether or not encryption is enabled 230func (c *Config) EncryptionEnabled() bool { 231 return c.Keyring != nil && len(c.Keyring.GetKeys()) > 0 232} 233