diff options
| author | Haw Loeung <[email protected]> | 2023-04-12 23:13:10 +0000 |
|---|---|---|
| committer | Canonical IS Mergebot <[email protected]> | 2023-04-12 23:13:10 +0000 |
| commit | 17b3f36cc4a16f47d9ab3697d058ad8a71eb2396 (patch) | |
| tree | 371509f78e1eb1daad7548e95eee9e3dbe8e38cf | |
| parent | 2d4a14b89bcc54f23f067b95a5dd53f084f6ff46 (diff) | |
| parent | 913574a7f928222be364355fdfc4ba963cd9ff5b (diff) | |
Allow overriding maxconn for sites/locations without backends - LP:2015989
Reviewed-on: https://code.launchpad.net/~hloeung/content-cache-charm/+git/content-cache-charm/+merge/440894
Reviewed-by: James Simpson <[email protected]>
| -rw-r--r-- | reactive/content_cache.py | 12 | ||||
| -rw-r--r-- | tests/unit/files/content_cache_rendered_haproxy_test_output_override_maxconns.txt | 92 | ||||
| -rw-r--r-- | tests/unit/test_content_cache.py | 28 |
3 files changed, 128 insertions, 4 deletions
diff --git a/reactive/content_cache.py b/reactive/content_cache.py index 4a81b89..af08e8f 100644 --- a/reactive/content_cache.py +++ b/reactive/content_cache.py @@ -302,6 +302,7 @@ def configure_haproxy(): # NOQA: C901 LP#1825084 for location, loc_conf in site_conf.get('locations', {}).items(): new_cached_loc_conf = {} new_cached_loc_conf['backends'] = ['127.0.0.1:{}'.format(cache_port)] + # For the caching layer here, we want the default, low, # 2s no matter what. This is so it'll notice when the # caching layer (nginx) is back up quicker. @@ -309,14 +310,18 @@ def configure_haproxy(): # NOQA: C901 LP#1825084 # Also, for caching layer, we want higher fall count as it's less # likely the caching layer is down, 2 mins here (inter * fall). new_cached_loc_conf['backend-fall-count'] = 60 + + new_cached_loc_conf['backend-check-method'] = 'GET' + new_cached_loc_conf['backend-check-path'] = '/_status/content-cache-check' + + backend_maxconn = loc_conf.get('backend-maxconn', 200) + new_cached_loc_conf['backend-maxconn'] = backend_maxconn + new_cached_loc_conf['backend-options'] = site_conf.get('haproxy-extra-configs', []) # Rather than enable haproxy's 'option forwardfor' we want to replace # the X-F-F header in case it's spoofed. new_cached_loc_conf['backend-options'].insert(0, 'http-request set-header X-Forwarded-For %[src]') - new_cached_loc_conf['backend-check-method'] = 'GET' - new_cached_loc_conf['backend-check-path'] = '/_status/content-cache-check' - # No backends if not site_conf['locations'][location].get('backends'): if not new_conf[cached_site]['locations']: @@ -338,7 +343,6 @@ def configure_haproxy(): # NOQA: C901 LP#1825084 if 'backend_port' in loc_conf: new_loc_conf['backend_port'] = loc_conf['backend_port'] - backend_maxconn = loc_conf.get('backend-maxconn', 200) new_loc_conf['backend-maxconn'] = backend_maxconn # Default to backend_maxconn times the no. of provided # backends, so 1-to-1 mapping. diff --git a/tests/unit/files/content_cache_rendered_haproxy_test_output_override_maxconns.txt b/tests/unit/files/content_cache_rendered_haproxy_test_output_override_maxconns.txt new file mode 100644 index 0000000..d12a2a4 --- /dev/null +++ b/tests/unit/files/content_cache_rendered_haproxy_test_output_override_maxconns.txt @@ -0,0 +1,92 @@ +global + nbthread 4 + maxconn 8192 + log /dev/log local0 + log /dev/log local1 notice + chroot /var/lib/haproxy + stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners + stats timeout 30s + server-state-file /run/haproxy/saved-server-state + user haproxy + group haproxy + daemon + + # LP#1874386: Work around lingering HAProxy processes as per LP:1874386 + # and kill them off. + hard-stop-after 15m + + # Default SSL material locations + ca-base /etc/ssl/certs + crt-base /etc/ssl/private + + # Default ciphers to use on SSL-enabled listening sockets. + # For more information, see ciphers(1SSL). This list is from: + # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ + # An alternative list with additional directives can be obtained from + # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy + ssl-default-bind-ciphers ECDHE+AESGCM:ECDHE+AES256:ECDHE+AES128:!SSLv3:!TLSv1 + ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 + # We'll eventually disable DHE (LP#1825321), but for now, bump DH params + tune.ssl.default-dh-param 2048 + + # Increase the SSL/TLS session cache from the default 20k. But + # rather than hardcode values, let's just set it to match + # global_max_connections (which by default is calculated using + # num. of CPU cores and num. of configured sites). Each entry + # requires ~200 bytes so on a host with say 32 CPUs, 10 sites, + # each with 2000 max conns will only consume around 122 Mbytes + # (32 * 10 * 2000 * 200), which is not much. + tune.ssl.cachesize 8192 + +defaults + log global + maxconn 8192 + mode http + option dontlognull + timeout connect 5s + timeout client 50s + timeout server 50s + errorfile 400 /etc/haproxy/errors/400.http + errorfile 403 /etc/haproxy/errors/403.http + errorfile 408 /etc/haproxy/errors/408.http + errorfile 500 /etc/haproxy/errors/500.http + errorfile 502 /etc/haproxy/errors/502.http + errorfile 503 /etc/haproxy/errors/503.http + errorfile 504 /etc/haproxy/errors/504.http + load-server-state-from-file global + unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid + unique-id-header X-Cache-Request-ID + log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r %ID" + +resolvers dns + nameserver dns1 127.0.0.53:53 + resolve_retries 3 + timeout resolve 3s + timeout retry 3s + accepted_payload_size 8192 + +listen stats + bind 127.0.0.1:10000 + acl allowed_cidr src 127.0.0.0/8 + http-request deny unless allowed_cidr + + mode http + stats enable + stats uri / + stats realm Haproxy\ Statistics + stats auth haproxy:biometricsarenotsecret + stats refresh 3 + + +listen cached-site1-local + bind 0.0.0.0:80 + bind :::80 + capture request header X-Cache-Request-ID len 60 + default_backend backend-cached-site1-local + +backend backend-cached-site1-local + option httpchk GET /_status/content-cache-check HTTP/1.1\r\nHost:\ site1.local\r\nUser-Agent:\ haproxy/httpchk + http-request set-header Host site1.local + http-request set-header X-Forwarded-For %[src] + balance leastconn + server server_1 127.0.0.1:6080 check inter 2s rise 2 fall 60 maxconn 1234 diff --git a/tests/unit/test_content_cache.py b/tests/unit/test_content_cache.py index feba416..52c3eed 100644 --- a/tests/unit/test_content_cache.py +++ b/tests/unit/test_content_cache.py @@ -627,6 +627,34 @@ site1.local: @mock.patch('charms.reactive.set_flag') @mock.patch('lib.haproxy.HAProxyConf.save_server_state') @mock.patch('reactive.content_cache.update_logrotate') + def test_configure_haproxy_sites_override_maxconns(self, logrotation, save_s_state, set_flag, opened_ports): + config = ''' +site1.local: + locations: + /: + backend-maxconn: 1234 +''' + self.mock_config.return_value = {'haproxy_hard_stop_after': '15m', 'max_connections': 8192, 'sites': config} + with mock.patch('lib.haproxy.HAProxyConf.conf_file', new_callable=mock.PropertyMock) as mock_conf_file: + mock_conf_file.return_value = os.path.join(self.tmpdir, 'haproxy.cfg') + opened_ports.return_value = ['443/tcp'] + content_cache.configure_haproxy() + + with open( + 'tests/unit/files/content_cache_rendered_haproxy_test_output_override_maxconns.txt', + 'r', + encoding='utf-8', + ) as f: + want = f.read() + with open(os.path.join(self.tmpdir, 'haproxy.cfg'), 'r', encoding='utf-8') as f: + got = f.read() + self.assertEqual(got, want) + + @freezegun.freeze_time("2019-03-22", tz_offset=0) + @mock.patch('charmhelpers.core.hookenv.opened_ports') + @mock.patch('charms.reactive.set_flag') + @mock.patch('lib.haproxy.HAProxyConf.save_server_state') + @mock.patch('reactive.content_cache.update_logrotate') def test_configure_haproxy_sites_load_balancing_algorithm(self, logrotation, save_s_state, set_flag, opened_ports): with open('tests/unit/files/config_test_config.txt', 'r', encoding='utf-8') as f: config = f.read() |
