Support server node weights.
Support setting a weighting value for each node that will determine the proportion of load balancing requests that it receives in relation to the other defined servers and their weights. Also adds a file describing the worker JSON message versioning. Fixes bug 1117349 Change-Id: Ie1460c165f03b0523ee28d864b74ea9e5858b256
This commit is contained in:
29
WORKER_MSG_FMT_VERSIONS
Normal file
29
WORKER_MSG_FMT_VERSIONS
Normal file
@@ -0,0 +1,29 @@
|
||||
# The worker versions the JSON messages that it comprehends. This version
|
||||
# is used for the DISCOVER message that can be sent by the API server. E.g.,
|
||||
#
|
||||
# { 'hpcs_action': 'DISCOVER' }
|
||||
#
|
||||
# And an example response from the worker:
|
||||
#
|
||||
# {
|
||||
# 'hpcs_action': 'DISCOVER',
|
||||
# 'version': '1.0',
|
||||
# 'hpcs_response': 'PASS'
|
||||
# }
|
||||
#
|
||||
# The version number is set in the method:
|
||||
#
|
||||
# libra.worker.controller._action_discover()
|
||||
#
|
||||
# Version format is: <major>.<minor>
|
||||
#
|
||||
# A change to the <minor> value means that a change has been made, but
|
||||
# we are still backwards compatible. A change to the <major> value means
|
||||
# a significant change was made and we are no longer compatible with older
|
||||
# versions.
|
||||
|
||||
[Version 1.1]
|
||||
- Accept node 'weight' values.
|
||||
|
||||
[Version 1.0]
|
||||
- Initial version.
|
||||
@@ -75,7 +75,7 @@ class LBaaSController(object):
|
||||
version this worker supports.
|
||||
"""
|
||||
# Version of the JSON message format that this worker understands.
|
||||
msg_fmt_version = "1.0"
|
||||
msg_fmt_version = "1.1"
|
||||
self.msg['version'] = msg_fmt_version
|
||||
self.msg[self.RESPONSE_FIELD] = self.RESPONSE_SUCCESS
|
||||
return self.msg
|
||||
|
||||
@@ -48,7 +48,7 @@ class LoadBalancerDriver(object):
|
||||
""" Add a supported protocol and listening port for the instance. """
|
||||
raise NotImplementedError()
|
||||
|
||||
def add_server(self, protocol, host, port):
|
||||
def add_server(self, protocol, host, port, weight):
|
||||
""" Add a server for the protocol for which we will proxy. """
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
@@ -92,9 +92,9 @@ class HAProxyDriver(LoadBalancerDriver):
|
||||
if proto == 'http':
|
||||
output.append(' cookie SERVERID rewrite')
|
||||
|
||||
for (addr, port) in protocfg['servers']:
|
||||
output.append(' server server%d %s:%s' %
|
||||
(serv_num, addr, port))
|
||||
for (addr, port, weight) in protocfg['servers']:
|
||||
output.append(' server server%d %s:%s weight %d' %
|
||||
(serv_num, addr, port, weight))
|
||||
serv_num += 1
|
||||
|
||||
return '\n'.join(output) + '\n'
|
||||
@@ -123,11 +123,20 @@ class HAProxyDriver(LoadBalancerDriver):
|
||||
else:
|
||||
self._bind(proto, '0.0.0.0', port)
|
||||
|
||||
def add_server(self, protocol, host, port):
|
||||
def add_server(self, protocol, host, port, weight=1):
|
||||
proto = protocol.lower()
|
||||
|
||||
try:
|
||||
weight = int(weight)
|
||||
except ValueError:
|
||||
raise Exception("Non-integer 'weight' value: '%s'" % weight)
|
||||
|
||||
if weight > 256:
|
||||
raise Exception("Server 'weight' %d exceeds max of 256" % weight)
|
||||
|
||||
if 'servers' not in self._config[proto]:
|
||||
self._config[proto]['servers'] = []
|
||||
self._config[proto]['servers'].append((host, port))
|
||||
self._config[proto]['servers'].append((host, port, weight))
|
||||
|
||||
def set_algorithm(self, protocol, algo):
|
||||
proto = protocol.lower()
|
||||
|
||||
@@ -41,8 +41,8 @@ class TestHAProxyDriver(testtools.TestCase):
|
||||
self.assertIn('servers', self.driver._config[proto])
|
||||
servers = self.driver._config[proto]['servers']
|
||||
self.assertEqual(len(servers), 2)
|
||||
self.assertEqual(servers[0], ('1.2.3.4', 7777))
|
||||
self.assertEqual(servers[1], ('5.6.7.8', 8888))
|
||||
self.assertEqual(servers[0], ('1.2.3.4', 7777, 1))
|
||||
self.assertEqual(servers[1], ('5.6.7.8', 8888, 1))
|
||||
|
||||
def testSetAlgorithm(self):
|
||||
""" Test the HAProxy set_algorithm() method """
|
||||
@@ -56,3 +56,35 @@ class TestHAProxyDriver(testtools.TestCase):
|
||||
self.assertEqual(self.driver._config[proto]['algorithm'], 'leastconn')
|
||||
e = self.assertRaises(Exception, self.driver.set_algorithm, proto, 99)
|
||||
self.assertEqual("Invalid algorithm: http", e.message)
|
||||
|
||||
def testServerWeightInt(self):
|
||||
""" Test setting integer server weights """
|
||||
proto = 'http'
|
||||
self.driver.add_protocol(proto, None)
|
||||
self.driver.add_server(proto, '1.2.3.4', 7777, 10)
|
||||
servers = self.driver._config[proto]['servers']
|
||||
self.assertEqual(len(servers), 1)
|
||||
self.assertEqual(servers[0], ('1.2.3.4', 7777, 10))
|
||||
|
||||
def testServerWeightStr(self):
|
||||
""" Test setting string server weights """
|
||||
proto = 'http'
|
||||
self.driver.add_protocol(proto, None)
|
||||
self.driver.add_server(proto, '1.2.3.4', 7777, "20")
|
||||
servers = self.driver._config[proto]['servers']
|
||||
self.assertEqual(len(servers), 1)
|
||||
self.assertEqual(servers[0], ('1.2.3.4', 7777, 20))
|
||||
|
||||
def testServerWeightInvalid(self):
|
||||
""" Test setting string server weights """
|
||||
proto = 'http'
|
||||
self.driver.add_protocol(proto, None)
|
||||
e = self.assertRaises(
|
||||
Exception,
|
||||
self.driver.add_server, proto, '1.2.3.4', 7777, 257)
|
||||
self.assertEqual("Server 'weight' 257 exceeds max of 256", e.message)
|
||||
|
||||
e = self.assertRaises(
|
||||
Exception,
|
||||
self.driver.add_server, proto, '1.2.3.4', 7777, "abc")
|
||||
self.assertEqual("Non-integer 'weight' value: 'abc'", e.message)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
fixtures>=0.3.12
|
||||
pep8
|
||||
mock
|
||||
httplib2
|
||||
python-subunit
|
||||
sphinx>=1.1.2
|
||||
testrepository>=0.0.8
|
||||
testtools>=0.9.22
|
||||
|
||||
Reference in New Issue
Block a user