Class: BigBrother::ActiveActiveCluster
- Inherits:
-
Cluster
- Object
- Cluster
- BigBrother::ActiveActiveCluster
show all
- Defined in:
- lib/big_brother/active_active_cluster.rb
Instance Attribute Summary collapse
Attributes inherited from Cluster
#backend_mode, #check_interval, #fwmark, #nagios, #name, #nodes, #ramp_up_time, #scheduler
Instance Method Summary
collapse
Methods inherited from Cluster
#==, #_add_maintenance_node, #_check_downpage, #_coerce_node, #_notify_nagios, #_remove_maintenance_node, #combined_weight, #down_file_exists?, #downpage_enabled?, #find_node, #has_downpage?, #monitored?, #needs_check?, #resume_monitoring!, #to_s, #up_file_exists?
Constructor Details
Returns a new instance of ActiveActiveCluster.
5
6
7
8
9
10
11
12
13
14
|
# File 'lib/big_brother/active_active_cluster.rb', line 5
def initialize(name, attributes={})
super(name, attributes)
interpol_nodes, local_nodes = @nodes.partition { |node| node.interpol? }
@nodes = @local_nodes = local_nodes
@interpol_node = interpol_nodes.first
@remote_nodes = []
@max_down_ticks = attributes.fetch(:max_down_ticks, 0)
@offset = attributes.fetch(:offset, 10_000)
@non_egress_locations = *attributes.fetch(:non_egress_locations, [])
end
|
Instance Attribute Details
#interpol_node ⇒ Object
Returns the value of attribute interpol_node.
3
4
5
|
# File 'lib/big_brother/active_active_cluster.rb', line 3
def interpol_node
@interpol_node
end
|
#local_nodes ⇒ Object
Returns the value of attribute local_nodes.
3
4
5
|
# File 'lib/big_brother/active_active_cluster.rb', line 3
def local_nodes
@local_nodes
end
|
#max_down_ticks ⇒ Object
Returns the value of attribute max_down_ticks.
3
4
5
|
# File 'lib/big_brother/active_active_cluster.rb', line 3
def max_down_ticks
@max_down_ticks
end
|
#non_egress_locations ⇒ Object
Returns the value of attribute non_egress_locations.
3
4
5
|
# File 'lib/big_brother/active_active_cluster.rb', line 3
def non_egress_locations
@non_egress_locations
end
|
#offset ⇒ Object
Returns the value of attribute offset.
3
4
5
|
# File 'lib/big_brother/active_active_cluster.rb', line 3
def offset
@offset
end
|
#remote_nodes ⇒ Object
Returns the value of attribute remote_nodes.
3
4
5
|
# File 'lib/big_brother/active_active_cluster.rb', line 3
def remote_nodes
@remote_nodes
end
|
Instance Method Details
#_add_nodes(addresses, fwmark) ⇒ Object
104
105
106
107
108
109
|
# File 'lib/big_brother/active_active_cluster.rb', line 104
def _add_nodes(addresses, fwmark)
addresses.each do |address|
BigBrother.logger.info "Adding #{address} to active/active cluster #{self}"
BigBrother.ipvs.start_node(fwmark, address, 0)
end
end
|
#_add_remote_nodes(nodes) ⇒ Object
137
138
139
140
141
142
|
# File 'lib/big_brother/active_active_cluster.rb', line 137
def _add_remote_nodes(nodes)
nodes.each do |node|
BigBrother.ipvs.start_node(fwmark, node.address, node.weight)
@remote_nodes << node
end
end
|
#_adjust_or_remove_remote_node(node) ⇒ Object
111
112
113
114
115
116
117
118
119
120
|
# File 'lib/big_brother/active_active_cluster.rb', line 111
def _adjust_or_remove_remote_node(node)
if node.down_tick_count >= max_down_ticks
BigBrother.ipvs.stop_node(fwmark, node.address)
remote_nodes.delete(node)
else
BigBrother.ipvs.edit_node(fwmark, node.address, 0)
node.weight = 0
node.down_tick_count += 1
end
end
|
#_fetch_remote_nodes ⇒ Object
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# File 'lib/big_brother/active_active_cluster.rb', line 122
def _fetch_remote_nodes
return {} if interpol_node.nil?
regular_remote_cluster = BigBrother::HealthFetcher.interpol_status(interpol_node, fwmark)
relay_remote_cluster = BigBrother::HealthFetcher.interpol_status(interpol_node, _relay_fwmark)
return {} if regular_remote_cluster.empty? || relay_remote_cluster.empty?
regular_remote_cluster.each_with_object({}) do |node, hsh|
next if self.non_egress_locations.include?(node['lb_source_location'])
hsh[node['lb_ip_address']] = BigBrother::Node.new(:address => node['lb_ip_address'], :weight => node['health'])
end
end
|
#_relay_fwmark ⇒ Object
100
101
102
|
# File 'lib/big_brother/active_active_cluster.rb', line 100
def _relay_fwmark
fwmark + offset
end
|
#_remove_nodes(addresses) ⇒ Object
144
145
146
147
148
149
150
|
# File 'lib/big_brother/active_active_cluster.rb', line 144
def _remove_nodes(addresses)
addresses.each do |address|
BigBrother.logger.info "Removing #{address} from active/active cluster #{self}"
BigBrother.ipvs.stop_node(fwmark, address)
BigBrother.ipvs.stop_node(_relay_fwmark, address)
end
end
|
#_update_node(node, new_weight) ⇒ Object
152
153
154
155
|
# File 'lib/big_brother/active_active_cluster.rb', line 152
def _update_node(node, new_weight)
BigBrother.ipvs.edit_node(fwmark, node.address, new_weight)
BigBrother.ipvs.edit_node(_relay_fwmark, node.address, new_weight)
end
|
#cluster_nodes ⇒ Object
63
64
65
|
# File 'lib/big_brother/active_active_cluster.rb', line 63
def cluster_nodes
(nodes + remote_nodes).map(&:address)
end
|
#incorporate_state(cluster) ⇒ Object
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
# File 'lib/big_brother/active_active_cluster.rb', line 71
def incorporate_state(cluster)
ipvs_state = BigBrother.ipvs.running_configuration
if ipvs_state[fwmark.to_s] && ipvs_state[_relay_fwmark.to_s].nil?
BigBrother.logger.info "Adding new active/active LB node #{to_s}"
BigBrother.ipvs.start_cluster(_relay_fwmark, @scheduler)
end
if ipvs_state[fwmark.to_s] && ipvs_state.fetch(_relay_fwmark.to_s, []).empty?
nodes.each do |node|
actual_node = cluster.find_node(node.address, node.port)
BigBrother.ipvs.start_node(_relay_fwmark, actual_node.address, actual_node.weight)
end
end
BigBrother.logger.info "Merging in new active/active cluster #{to_s}"
@remote_nodes = cluster.remote_nodes if cluster.is_a?(BigBrother::ActiveActiveCluster)
super(cluster)
end
|
#local_cluster_nodes ⇒ Object
67
68
69
|
# File 'lib/big_brother/active_active_cluster.rb', line 67
def local_cluster_nodes
nodes.map(&:address)
end
|
#monitor_nodes ⇒ Object
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
# File 'lib/big_brother/active_active_cluster.rb', line 33
def monitor_nodes
super
fresh_remote_nodes = _fetch_remote_nodes
remote_nodes.each do |node|
if new_node = fresh_remote_nodes[node.address]
next if new_node.weight == node.weight
BigBrother.ipvs.edit_node(fwmark, node.address, new_node.weight)
node.weight = new_node.weight
else
_adjust_or_remove_remote_node(node)
end
end
_add_remote_nodes(fresh_remote_nodes.values - remote_nodes)
end
|
#start_monitoring! ⇒ Object
16
17
18
19
20
21
22
23
24
25
26
|
# File 'lib/big_brother/active_active_cluster.rb', line 16
def start_monitoring!
BigBrother.logger.info "Starting monitoring on active/active cluster #{to_s}"
BigBrother.ipvs.start_cluster(@fwmark, @scheduler)
BigBrother.ipvs.start_cluster(_relay_fwmark, @scheduler)
local_nodes.each do |node|
BigBrother.ipvs.start_node(@fwmark, node.address, BigBrother::Node::INITIAL_WEIGHT)
BigBrother.ipvs.start_node(_relay_fwmark, node.address, BigBrother::Node::INITIAL_WEIGHT)
end
@monitored = true
end
|
#stop_monitoring! ⇒ Object
28
29
30
31
|
# File 'lib/big_brother/active_active_cluster.rb', line 28
def stop_monitoring!
super
BigBrother.ipvs.stop_cluster(_relay_fwmark)
end
|
#stop_relay_fwmark ⇒ Object
92
93
94
95
96
97
98
|
# File 'lib/big_brother/active_active_cluster.rb', line 92
def stop_relay_fwmark
nodes.each do |node|
BigBrother.ipvs.stop_node(_relay_fwmark, node.address)
end
BigBrother.ipvs.stop_cluster(_relay_fwmark)
end
|
#synchronize! ⇒ Object
50
51
52
53
54
55
56
57
58
59
60
61
|
# File 'lib/big_brother/active_active_cluster.rb', line 50
def synchronize!
ipvs_state = BigBrother.ipvs.running_configuration
@remote_nodes = _fetch_remote_nodes.values if @remote_nodes == []
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, fwmark)
_add_nodes(local_cluster_nodes - running_nodes, _relay_fwmark)
end
end
|