def run(management_port, config, backend=_DEFAULT_BACKEND, update_period=_DEFAULT_UPDATE_PERIOD, max_update_frequency=_DEFAULT_MAX_UPDATE_FREQUENCY, weight_adjustment_delay_seconds=_DEFAULT_WEIGHT_ADJUSTMENT_DELAY_SEC, registration_class=_DEFAULT_REGISTRATION_CLASS, registration_arg=_DEFAULT_REGISTRATION_KWARGS, metric_publisher_class=_DEFAULT_METRIC_PUBLISHER_CLASS, metric_publisher_arg=_DEFAULT_METRIC_PUBLISHER_KWARGS, mirror_source=_DEFAULT_MIRROR_SOURCE, mirror_ports=_DEFAULT_MIRROR_PORTS, mirror_max_qps=_DEFAULT_MIRROR_MAX_QPS, mirror_max_update_frequency=_DEFAULT_MIRROR_MAX_UPDATE_FREQUENCY, mirror_pid_path=_MIRROR_PID_PATH, sentry_dsn=None, setup=False): """Run the Aurproxy load balancer manager. Args: management_port - int - port for the manager application to listen on for Aurora lifecycle queries and events (/health, /quitquit, etc.). config - JSON String - Load balancer configuration. See README.md for detailed documentation. backend - Load balancer manager backend to use. EG: "nginx". update_period - int - frequency with which the need to update is checked. max_update_frequency - int - minimum number of seconds between updates. weight_adjustment_delay_seconds - int - number of seconds to wait before starting configured share adjusters. May not want them running immediately after aurproxy deploys. registration_class - str - Python class path for registration class. registration_arg - list(str) - List of equal-sign-delimited string kwarg pairs. Example: ["domain=myapp.mydomain.com", "type=A"] metric_publisher_class - str - Python class path for metrics publisher class. metric_publisher_arg - list(str) - List of equal-sign-delimited string kwarg pairs. Example: ["source=cluster.role.environment.job"] mirror_source - JSON String - Source configuration for gor repeater to which http traffic should be mirrored. mirror_ports - Comma separated integer string - Local ports to mirror. Example: "8080,8081" mirror_max_qps - Max QPS to mirror to gor repeater. mirror_max_update_frequency - integer - number of seconds between updates of mirror configuration. sentry_dsn - str - Sentry DSN for error logging. setup - bool - When run in setup mode, aurproxy will render a configuration for the managed load balancer once and then exit. Run aurproxy once in setup mode to set up the load balancer, then start aurproxy and the load balancer together. """ # Set up sentry error logging if sentry_dsn: setup_sentry(sentry_dsn) # Load config try: proxy_config = json.loads(config) except (TypeError, ValueError): raise commandr.CommandrUsageError('Invalid JSON configuration specified via --config') # Set up updater try: proxy_updater = ProxyUpdater(backend, proxy_config, update_period, max_update_frequency) except AurProxyConfigException as exc: raise commandr.CommandrUsageError( 'Invalid configuration: {}'.format(str(exc)), ) # Set up mirroring mirror_updater = None if mirror_source: mirror_updater = load_mirror_updater(mirror_source, mirror_ports, mirror_max_qps, mirror_max_update_frequency, _MIRROR_COMMAND_TEMPLATE_PATH, mirror_pid_path) if setup: proxy_updater.set_up() if mirror_updater: mirror_updater.set_up() else: # Set up metrics set_root_prefix('aurproxy') if metric_publisher_class: _setup_metrics(metric_publisher_class, metric_publisher_arg) # Set up registration if registration_class: try: registerer = load_cli_plugin(registration_class, registration_arg) registerer.add() register_shutdown_handler(registerer.remove) except Exception: logger.exception('Registration failure.') raise # Start the updaters and extract blueprints proxy_updater.start(weight_adjustment_delay_seconds) blueprints = proxy_updater.blueprints if mirror_updater: mirror_updater.start() blueprints += mirror_updater.blueprints _start_web(management_port, sentry_dsn, blueprints)
def run(management_port, config, backend=_DEFAULT_BACKEND, update_period=_DEFAULT_UPDATE_PERIOD, max_update_frequency=_DEFAULT_MAX_UPDATE_FREQUENCY, weight_adjustment_delay_seconds=_DEFAULT_WEIGHT_ADJUSTMENT_DELAY_SEC, registration_class=_DEFAULT_REGISTRATION_CLASS, registration_arg=_DEFAULT_REGISTRATION_KWARGS, metric_publisher_class=_DEFAULT_METRIC_PUBLISHER_CLASS, metric_publisher_arg=_DEFAULT_METRIC_PUBLISHER_KWARGS, mirror_source=_DEFAULT_MIRROR_SOURCE, mirror_ports=_DEFAULT_MIRROR_PORTS, mirror_max_qps=_DEFAULT_MIRROR_MAX_QPS, mirror_max_update_frequency=_DEFAULT_MIRROR_MAX_UPDATE_FREQUENCY, mirror_pid_path=_MIRROR_PID_PATH, sentry_dsn=None, setup=False): """Run the Aurproxy load balancer manager. Args: management_port - int - port for the manager application to listen on for Aurora lifecycle queries and events (/health, /quitquit, etc.). config - JSON String or file:// location of a JSON document - Load balancer configuration. See README.md for detailed documentation. backend - Load balancer manager backend to use. EG: "nginx". update_period - int - frequency with which the need to update is checked. max_update_frequency - int - minimum number of seconds between updates. weight_adjustment_delay_seconds - int - number of seconds to wait before starting configured share adjusters. May not want them running immediately after aurproxy deploys. registration_class - str - Python class path for registration class. registration_arg - list(str) - List of equal-sign-delimited string kwarg pairs. Example: ["domain=myapp.mydomain.com", "type=A"] metric_publisher_class - str - Python class path for metrics publisher class. metric_publisher_arg - list(str) - List of equal-sign-delimited string kwarg pairs. Example: ["source=cluster.role.environment.job"] mirror_source - JSON String - Source configuration for gor repeater to which http traffic should be mirrored. mirror_ports - Comma separated integer string - Local ports to mirror. Example: "8080,8081" mirror_max_qps - Max QPS to mirror to gor repeater. mirror_max_update_frequency - integer - number of seconds between updates of mirror configuration. sentry_dsn - str - Sentry DSN for error logging. setup - bool - When run in setup mode, aurproxy will render a configuration for the managed load balancer once and then exit. Run aurproxy once in setup mode to set up the load balancer, then start aurproxy and the load balancer together. """ # Set up sentry error logging if sentry_dsn: setup_sentry(sentry_dsn) # Load config try: if config.startswith('file://'): with open(config.split('file://', 1)[1]) as config_fh: proxy_config = json.load(config_fh) else: proxy_config = json.loads(config) except (TypeError, ValueError): raise commandr.CommandrUsageError( 'Invalid JSON configuration specified via --config') except IOError as err: raise commandr.CommandrUsageError('Failed to read --config file: %s' % err) # Set up updater try: proxy_updater = ProxyUpdater(backend, proxy_config, update_period, max_update_frequency) except AurProxyConfigException as exc: raise commandr.CommandrUsageError( 'Invalid configuration: {}'.format(str(exc)), ) # Set up mirroring mirror_updater = None if mirror_source: mirror_updater = load_mirror_updater(mirror_source, mirror_ports, mirror_max_qps, mirror_max_update_frequency, _MIRROR_COMMAND_TEMPLATE_PATH, mirror_pid_path) if setup: proxy_updater.set_up() if mirror_updater: mirror_updater.set_up() else: # Set up metrics set_root_prefix('aurproxy') if metric_publisher_class: _setup_metrics(metric_publisher_class, metric_publisher_arg) # Set up registration if registration_class: try: registerer = load_cli_plugin(registration_class, registration_arg) registerer.add() register_shutdown_handler(registerer.remove) except Exception: logger.exception('Registration failure.') raise # Start the updaters and extract blueprints proxy_updater.start(weight_adjustment_delay_seconds) blueprints = proxy_updater.blueprints if mirror_updater: mirror_updater.start() blueprints += mirror_updater.blueprints _start_web(management_port, sentry_dsn, blueprints)
def test_proxy_updater(self): arg_sets = [] for add_s_a in [True, False]: config, scope = build_proxy_configuration(add_share_adjusters=add_s_a) arg_sets.append((config, scope, add_s_a)) try: ProxyBackendProvider.register(TstProxyBackend) for config, scope, add_share_adjusters in arg_sets: config, scope = build_proxy_configuration(add_share_adjusters=True) now = datetime.now() proxy_updater = ProxyUpdater(backend=TstProxyBackend.NAME, config=config, update_period=0, max_update_frequency=0) # Newly initialized proxy updater should need to update self.assertTrue(proxy_updater._should_update(now)) proxy_updater._try_update(now) self.assertFalse(proxy_updater._should_update(now)) # Newly started proxy updater should need to update proxy_updater.start(weight_adjustment_delay_seconds=0) self.assertTrue(proxy_updater._should_update(now)) proxy_updater._try_update(now) self.assertFalse(proxy_updater._should_update(now)) # Proxy updater that has been signaled by a source should need to # update scope.source.add(SourceEndpoint('127.0.0.1', 8080)) self.assertTrue(proxy_updater._should_update(now)) proxy_updater._try_update(now) self.assertFalse(proxy_updater._should_update(now)) if add_share_adjusters: # Proxy updater that has been signaled by a share_adjuster should # need to update scope.share_adjuster.set_share(.5) self.assertTrue(proxy_updater._should_update(now)) proxy_updater._try_update(now) self.assertFalse(proxy_updater._should_update(now)) finally: ProxyBackendProvider.unregister(TstProxyBackend)
def run(management_port, config, backend=_DEFAULT_BACKEND, update_period=_DEFAULT_UPDATE_PERIOD, max_update_frequency=_DEFAULT_MAX_UPDATE_FREQUENCY, weight_adjustment_delay_seconds=_DEFAULT_WEIGHT_ADJUSTMENT_DELAY_SEC, registration_class=_DEFAULT_REGISTRATION_CLASS, registration_arg=_DEFAULT_REGISTRATION_KWARGS, metric_publisher_class=_DEFAULT_METRIC_PUBLISHER_CLASS, metric_publisher_arg=_DEFAULT_METRIC_PUBLISHER_KWARGS, sentry_dsn=None, setup=False): """Run the Aurproxy load balancer manager. Args: management_port - int - port for the manager application to listen on for Aurora lifecycle queries and events (/health, /quitquit, etc.). config - JSON String - Load balancer configuration. See README.md for detailed documentation. backend - Load balancer manager backend to use. EG: "nginx". update_period - int - frequency with which the need to update is checked. max_update_frequency - int - minimum number of seconds between updates. weight_adjustment_delay_seconds - int - number of seconds to wait before starting configured share adjusters. May not want them running immediately after aurproxy deploys. registration_class - str - Python class path for registration class. registration_arg - list(str) - List of equal-sign-delimited string kwarg pairs. Example: ["domain=myapp.mydomain.com", "type=A"] metric_publisher_class - str - Python class path for metrics publisher class. metric_publisher_arg - list(str) - List of equal-sign-delimited string kwarg pairs. Example: ["source=cluster.role.environment.job"] sentry_dsn - str - Sentry DSN for error logging. setup - bool - When run in setup mode, aurproxy will render a configuration for the managed load balancer once and then exit. Run aurproxy once in setup mode to set up the load balancer, then start aurproxy and the load balancer together. """ # Set up sentry error logging if sentry_dsn: setup_sentry(sentry_dsn) # Load config proxy_config = json.loads(config) # Set up updater proxy_updater = ProxyUpdater(backend, proxy_config, update_period, max_update_frequency) if setup: proxy_updater.set_up() else: # Set up metrics set_root_prefix('aurproxy') if metric_publisher_class: try: publisher = load_cli_plugin(metric_publisher_class, metric_publisher_arg) add_publisher(publisher) except Exception: logger.exception('Metrics failure.') raise # Set up registration if registration_class: try: registerer = load_cli_plugin(registration_class, registration_arg) registerer.add() register_shutdown_handler(registerer.remove) except Exception: logger.exception('Registration failure.') raise # Start the proxy updater. proxy_updater.start(weight_adjustment_delay_seconds) # Set up management application app = Flask(__name__) app.register_blueprint(lifecycle_blueprint) if sentry_dsn: app = setup_sentry_wsgi(app, sentry_dsn) http_server = WSGIServer(('0.0.0.0', int(management_port)), app) http_server.serve_forever()