Class: BigBrother::Cluster
- Inherits:
-
Object
- Object
- BigBrother::Cluster
show all
- Defined in:
- lib/big_brother/cluster.rb
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
#initialize(name, attributes = {}) ⇒ Cluster
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# File 'lib/big_brother/cluster.rb', line 5
def initialize(name, attributes = {})
@name = name
@fwmark = attributes[:fwmark]
@scheduler = attributes[:scheduler]
@check_interval = attributes.fetch(:check_interval, 1)
@monitored = false
@nodes = attributes.fetch(:nodes, []).map { |node_config| _coerce_node(node_config) }
@last_check = Time.new(0)
@up_file = BigBrother::StatusFile.new('up', @name)
@down_file = BigBrother::StatusFile.new('down', @name)
@ramp_up_time = attributes.fetch(:ramp_up_time, 60)
@has_downpage = attributes[:has_downpage]
@nagios = attributes[:nagios]
@backend_mode = attributes[:backend_mode]
end
|
Instance Attribute Details
#backend_mode ⇒ Object
Returns the value of attribute backend_mode.
3
4
5
|
# File 'lib/big_brother/cluster.rb', line 3
def backend_mode
@backend_mode
end
|
#check_interval ⇒ Object
Returns the value of attribute check_interval.
3
4
5
|
# File 'lib/big_brother/cluster.rb', line 3
def check_interval
@check_interval
end
|
#fwmark ⇒ Object
Returns the value of attribute fwmark.
3
4
5
|
# File 'lib/big_brother/cluster.rb', line 3
def fwmark
@fwmark
end
|
#nagios ⇒ Object
Returns the value of attribute nagios.
3
4
5
|
# File 'lib/big_brother/cluster.rb', line 3
def nagios
@nagios
end
|
#name ⇒ Object
Returns the value of attribute name.
3
4
5
|
# File 'lib/big_brother/cluster.rb', line 3
def name
@name
end
|
#nodes ⇒ Object
Returns the value of attribute nodes.
3
4
5
|
# File 'lib/big_brother/cluster.rb', line 3
def nodes
@nodes
end
|
#ramp_up_time ⇒ Object
Returns the value of attribute ramp_up_time.
3
4
5
|
# File 'lib/big_brother/cluster.rb', line 3
def ramp_up_time
@ramp_up_time
end
|
#scheduler ⇒ Object
Returns the value of attribute scheduler.
3
4
5
|
# File 'lib/big_brother/cluster.rb', line 3
def scheduler
@scheduler
end
|
Instance Method Details
#==(other) ⇒ Object
107
108
109
|
# File 'lib/big_brother/cluster.rb', line 107
def ==(other)
fwmark == other.fwmark
end
|
#_add_maintenance_node ⇒ Object
134
135
136
137
|
# File 'lib/big_brother/cluster.rb', line 134
def _add_maintenance_node
BigBrother.logger.info "Adding downpage to cluster #{self}"
BigBrother.ipvs.start_node(fwmark, '169.254.254.254', 1)
end
|
#_add_nodes(addresses) ⇒ Object
127
128
129
130
131
132
|
# File 'lib/big_brother/cluster.rb', line 127
def _add_nodes(addresses)
addresses.each do |address|
BigBrother.logger.info "Adding #{address} to cluster #{self}"
BigBrother.ipvs.start_node(fwmark, address, 0)
end
end
|
#_check_downpage ⇒ Object
139
140
141
142
143
144
145
146
147
148
|
# File 'lib/big_brother/cluster.rb', line 139
def _check_downpage
total_health = @nodes.collect{ |n| n.weight || 0 }.reduce(:+)
if total_health <= 0
_add_maintenance_node unless downpage_enabled?
@downpage_enabled = true
else
_remove_maintenance_node if downpage_enabled?
@downpage_enabled = false
end
end
|
#_coerce_node(node_config) ⇒ Object
21
22
23
|
# File 'lib/big_brother/cluster.rb', line 21
def _coerce_node(node_config)
node_config.is_a?(Node) ? node_config : Node.new(node_config)
end
|
#_notify_nagios ⇒ Object
150
151
152
153
154
155
156
157
158
159
160
161
|
# File 'lib/big_brother/cluster.rb', line 150
def _notify_nagios
nodes_down = @nodes.count{|n| n.weight == 0}
return if @last_node_count == nodes_down
if ((nodes_down / @nodes.count.to_f) >= 0.5)
BigBrother.nagios.send_critical(nagios[:host], nagios[:check], "50% of nodes are down", nagios[:server])
elsif nodes_down > 0
BigBrother.nagios.send_warning(nagios[:host], nagios[:check], "a node is down", nagios[:server])
else
BigBrother.nagios.send_ok(nagios[:host], nagios[:check], "all nodes up", nagios[:server])
end
@last_node_count = nodes_down
end
|
#_remove_maintenance_node ⇒ Object
163
164
165
|
# File 'lib/big_brother/cluster.rb', line 163
def _remove_maintenance_node
BigBrother.ipvs.stop_node(fwmark, '127.0.0.1')
end
|
#_remove_nodes(addresses) ⇒ Object
167
168
169
170
171
172
|
# File 'lib/big_brother/cluster.rb', line 167
def _remove_nodes(addresses)
addresses.each do |address|
BigBrother.logger.info "Removing #{address} to cluster #{self}"
BigBrother.ipvs.stop_node(fwmark, address)
end
end
|
#_update_node(node, new_weight) ⇒ Object
174
175
176
|
# File 'lib/big_brother/cluster.rb', line 174
def _update_node(node, new_weight)
BigBrother.ipvs.edit_node(fwmark, node.address, new_weight)
end
|
#cluster_nodes ⇒ Object
79
80
81
|
# File 'lib/big_brother/cluster.rb', line 79
def cluster_nodes
nodes.map(&:address)
end
|
#combined_weight ⇒ Object
25
26
27
|
# File 'lib/big_brother/cluster.rb', line 25
def combined_weight
nodes.inject(0) { |sum, node| sum + node.weight.to_i }
end
|
#down_file_exists? ⇒ Boolean
115
116
117
|
# File 'lib/big_brother/cluster.rb', line 115
def down_file_exists?
@down_file.exists?
end
|
#downpage_enabled? ⇒ Boolean
29
30
31
|
# File 'lib/big_brother/cluster.rb', line 29
def downpage_enabled?
@downpage_enabled
end
|
#find_node(address, port) ⇒ Object
33
34
35
|
# File 'lib/big_brother/cluster.rb', line 33
def find_node(address, port)
nodes.find{|node| node.address == address && node.port == port}
end
|
#has_downpage? ⇒ Boolean
37
38
39
|
# File 'lib/big_brother/cluster.rb', line 37
def has_downpage?
@has_downpage
end
|
#incorporate_state(another_cluster) ⇒ Object
119
120
121
122
123
124
125
|
# File 'lib/big_brother/cluster.rb', line 119
def incorporate_state(another_cluster)
nodes.each do |node|
node.incorporate_state(another_cluster.find_node(node.address, node.port))
end
self
end
|
#monitor_nodes ⇒ Object
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
# File 'lib/big_brother/cluster.rb', line 88
def monitor_nodes
@last_check = Time.now
return unless monitored?
@nodes.each do |node|
new_weight = node.monitor(self)
if new_weight != node.weight
_update_node(node, new_weight)
node.weight = new_weight
end
end
_check_downpage if has_downpage?
_notify_nagios if nagios
end
|
#monitored? ⇒ Boolean
41
42
43
|
# File 'lib/big_brother/cluster.rb', line 41
def monitored?
@monitored
end
|
#needs_check? ⇒ Boolean
83
84
85
86
|
# File 'lib/big_brother/cluster.rb', line 83
def needs_check?
return false unless monitored?
@last_check + @check_interval < Time.now
end
|
#resume_monitoring! ⇒ Object
63
64
65
66
|
# File 'lib/big_brother/cluster.rb', line 63
def resume_monitoring!
BigBrother.logger.info "Resuming monitoring on cluster #{to_s}"
@monitored = true
end
|
#start_monitoring! ⇒ Object
#stop_monitoring! ⇒ Object
55
56
57
58
59
60
61
|
# File 'lib/big_brother/cluster.rb', line 55
def stop_monitoring!
BigBrother.logger.info "Stopping monitoring on cluster #{to_s}"
BigBrother.ipvs.stop_cluster(@fwmark)
@monitored = false
@nodes.each(&:invalidate_weight!)
end
|
#synchronize! ⇒ Object
68
69
70
71
72
73
74
75
76
77
|
# File 'lib/big_brother/cluster.rb', line 68
def synchronize!
ipvs_state = BigBrother.ipvs.running_configuration
if ipvs_state.has_key?(fwmark.to_s)
resume_monitoring!
running_nodes = ipvs_state[fwmark.to_s]
_remove_nodes(running_nodes - cluster_nodes)
_add_nodes(cluster_nodes - running_nodes)
end
end
|
#to_s ⇒ Object
103
104
105
|
# File 'lib/big_brother/cluster.rb', line 103
def to_s
"#{@name} (#{@fwmark})"
end
|
#up_file_exists? ⇒ Boolean
111
112
113
|
# File 'lib/big_brother/cluster.rb', line 111
def up_file_exists?
@up_file.exists?
end
|