Skip to content
Snippets Groups Projects
Commit d76b1cd2 authored by James Groffen's avatar James Groffen
Browse files

Add connection pool settings for performance tuning.

parent 1313ddd8
No related branches found
No related tags found
No related merge requests found
...@@ -6,6 +6,7 @@ FEATURES: ...@@ -6,6 +6,7 @@ FEATURES:
* Added a `--enable-request-id` option to inject a request id into the upstream request [#PR392](https://github.com/gambol99/keycloak-proxy/pull/392) * Added a `--enable-request-id` option to inject a request id into the upstream request [#PR392](https://github.com/gambol99/keycloak-proxy/pull/392)
* Added the ability for the proxy to generate self-signed certificates for use via the `--enable-self-signed-tls` [#PR394](https://github.com/gambol99/keycloak-proxy/pull/394) * Added the ability for the proxy to generate self-signed certificates for use via the `--enable-self-signed-tls` [#PR394](https://github.com/gambol99/keycloak-proxy/pull/394)
* Added support for token with multiple audiences in the claims [#PR401](https://github.com/gambol99/keycloak-proxy/pull/401) * Added support for token with multiple audiences in the claims [#PR401](https://github.com/gambol99/keycloak-proxy/pull/401)
* Added `--max-idle-connections` and `--max-idle-connections-per-host` settings to support tuning the http connection pool size for performance needs [#PR405](https://github.com/gambol99/keycloak-proxy/pull/405)
BREAK CHANGES BREAK CHANGES
* Added the http-cookie-only option as default true [#PR397](https://github.com/gambol99/keycloak-proxy/pull/397) * Added the http-cookie-only option as default true [#PR397](https://github.com/gambol99/keycloak-proxy/pull/397)
......
...@@ -124,6 +124,8 @@ GLOBAL OPTIONS: ...@@ -124,6 +124,8 @@ GLOBAL OPTIONS:
--upstream-response-header-timeout value the timeout placed on the response header for upstream (default: 10s) --upstream-response-header-timeout value the timeout placed on the response header for upstream (default: 10s)
--upstream-expect-continue-timeout value the timeout placed on the expect continue for upstream (default: 10s) --upstream-expect-continue-timeout value the timeout placed on the expect continue for upstream (default: 10s)
--verbose switch on debug / verbose logging (default: false) --verbose switch on debug / verbose logging (default: false)
--max-idle-connections max idle upstream / keycloak connections to keep alive, ready for reuse (default: 100)
--max-idle-connections-per-host limits the number of idle connections maintained per host (default: 50)
--enabled-proxy-protocol enable proxy protocol (default: false) --enabled-proxy-protocol enable proxy protocol (default: false)
--server-read-timeout value the server read timeout on the http server (default: 10s) --server-read-timeout value the server read timeout on the http server (default: 10s)
--server-write-timeout value the server write timeout on the http server (default: 10s) --server-write-timeout value the server write timeout on the http server (default: 10s)
......
...@@ -46,6 +46,8 @@ func newDefaultConfig() *Config { ...@@ -46,6 +46,8 @@ func newDefaultConfig() *Config {
Headers: make(map[string]string), Headers: make(map[string]string),
LetsEncryptCacheDir: "./cache/", LetsEncryptCacheDir: "./cache/",
MatchClaims: make(map[string]string), MatchClaims: make(map[string]string),
MaxIdleConns: 100,
MaxIdleConnsPerHost: 50,
OAuthURI: "/oauth", OAuthURI: "/oauth",
OpenIDProviderTimeout: 30 * time.Second, OpenIDProviderTimeout: 30 * time.Second,
PreserveHost: false, PreserveHost: false,
...@@ -84,6 +86,12 @@ func (r *Config) isValid() error { ...@@ -84,6 +86,12 @@ func (r *Config) isValid() error {
if r.Listen == "" { if r.Listen == "" {
return errors.New("you have not specified the listening interface") return errors.New("you have not specified the listening interface")
} }
if r.MaxIdleConns <= 0 {
return errors.New("max-idle-connections must be a number > 0")
}
if r.MaxIdleConnsPerHost < 0 || r.MaxIdleConnsPerHost > r.MaxIdleConns {
return errors.New("maxi-idle-connections-per-host must be a number > 0 and <= max-idle-connections")
}
if r.TLSCertificate != "" && r.TLSPrivateKey == "" { if r.TLSCertificate != "" && r.TLSPrivateKey == "" {
return errors.New("you have not provided a private key") return errors.New("you have not provided a private key")
} }
......
...@@ -63,8 +63,44 @@ func TestIsConfig(t *testing.T) { ...@@ -63,8 +63,44 @@ func TestIsConfig(t *testing.T) {
RedirectionURL: "http://120.0.0.1", RedirectionURL: "http://120.0.0.1",
Upstream: "http://120.0.0.1", Upstream: "http://120.0.0.1",
}, },
},
{
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
Upstream: "http://120.0.0.1",
MaxIdleConns: 100,
MaxIdleConnsPerHost: 50,
},
Ok: true, Ok: true,
}, },
{
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
Upstream: "http://120.0.0.1",
MaxIdleConns: 0,
MaxIdleConnsPerHost: 0,
},
},
{
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientID: "client",
ClientSecret: "client",
RedirectionURL: "http://120.0.0.1",
Upstream: "http://120.0.0.1",
MaxIdleConns: 100,
MaxIdleConnsPerHost: 200,
},
},
{ {
Config: &Config{ Config: &Config{
Listen: ":8080", Listen: ":8080",
...@@ -76,6 +112,8 @@ func TestIsConfig(t *testing.T) { ...@@ -76,6 +112,8 @@ func TestIsConfig(t *testing.T) {
MatchClaims: map[string]string{ MatchClaims: map[string]string{
"test": "&&&[", "test": "&&&[",
}, },
MaxIdleConns: 100,
MaxIdleConnsPerHost: 50,
}, },
}, },
{ {
...@@ -83,6 +121,8 @@ func TestIsConfig(t *testing.T) { ...@@ -83,6 +121,8 @@ func TestIsConfig(t *testing.T) {
Listen: ":8080", Listen: ":8080",
SkipTokenVerification: true, SkipTokenVerification: true,
Upstream: "http://120.0.0.1", Upstream: "http://120.0.0.1",
MaxIdleConns: 100,
MaxIdleConnsPerHost: 50,
}, },
Ok: true, Ok: true,
}, },
...@@ -93,6 +133,8 @@ func TestIsConfig(t *testing.T) { ...@@ -93,6 +133,8 @@ func TestIsConfig(t *testing.T) {
ClientSecret: "client", ClientSecret: "client",
RedirectionURL: "http://120.0.0.1", RedirectionURL: "http://120.0.0.1",
Upstream: "http://120.0.0.1", Upstream: "http://120.0.0.1",
MaxIdleConns: 100,
MaxIdleConnsPerHost: 50,
}, },
}, },
{ {
...@@ -102,6 +144,8 @@ func TestIsConfig(t *testing.T) { ...@@ -102,6 +144,8 @@ func TestIsConfig(t *testing.T) {
ClientID: "client", ClientID: "client",
ClientSecret: "client", ClientSecret: "client",
RedirectionURL: "http://120.0.0.1", RedirectionURL: "http://120.0.0.1",
MaxIdleConns: 100,
MaxIdleConnsPerHost: 50,
}, },
}, },
{ {
...@@ -112,6 +156,8 @@ func TestIsConfig(t *testing.T) { ...@@ -112,6 +156,8 @@ func TestIsConfig(t *testing.T) {
ClientSecret: "client", ClientSecret: "client",
RedirectionURL: "http://120.0.0.1", RedirectionURL: "http://120.0.0.1",
Upstream: "this should fail", Upstream: "this should fail",
MaxIdleConns: 100,
MaxIdleConnsPerHost: 50,
}, },
}, },
{ {
...@@ -123,6 +169,8 @@ func TestIsConfig(t *testing.T) { ...@@ -123,6 +169,8 @@ func TestIsConfig(t *testing.T) {
RedirectionURL: "http://120.0.0.1", RedirectionURL: "http://120.0.0.1",
Upstream: "this should fail", Upstream: "this should fail",
SecureCookie: true, SecureCookie: true,
MaxIdleConns: 100,
MaxIdleConnsPerHost: 50,
}, },
}, },
{ {
...@@ -134,6 +182,8 @@ func TestIsConfig(t *testing.T) { ...@@ -134,6 +182,8 @@ func TestIsConfig(t *testing.T) {
RedirectionURL: "https://120.0.0.1", RedirectionURL: "https://120.0.0.1",
Upstream: "this should fail", Upstream: "this should fail",
SecureCookie: true, SecureCookie: true,
MaxIdleConns: 100,
MaxIdleConnsPerHost: 50,
}, },
Ok: true, Ok: true,
}, },
......
...@@ -312,6 +312,12 @@ type Config struct { ...@@ -312,6 +312,12 @@ type Config struct {
Verbose bool `json:"verbose" yaml:"verbose" usage:"switch on debug / verbose logging"` Verbose bool `json:"verbose" yaml:"verbose" usage:"switch on debug / verbose logging"`
// EnableProxyProtocol controls the proxy protocol // EnableProxyProtocol controls the proxy protocol
EnableProxyProtocol bool `json:"enabled-proxy-protocol" yaml:"enabled-proxy-protocol" usage:"enable proxy protocol"` EnableProxyProtocol bool `json:"enabled-proxy-protocol" yaml:"enabled-proxy-protocol" usage:"enable proxy protocol"`
// MaxIdleConns is the max idle connections to keep alive, ready for reuse
MaxIdleConns int `json:"max-idle-connections" yaml:"max-idle-connections" usage:"max idle upstream / keycloak connections to keep alive, ready for reuse"`
// MaxIdleConnsPerHost limits the number of idle connections maintained per host
MaxIdleConnsPerHost int `json:"max-idle-connections-per-host" yaml:"max-idle-connections-per-host" usage:"limits the number of idle connections maintained per host"`
// ServerReadTimeout is the read timeout on the http server // ServerReadTimeout is the read timeout on the http server
ServerReadTimeout time.Duration `json:"server-read-timeout" yaml:"server-read-timeout" usage:"the server read timeout on the http server"` ServerReadTimeout time.Duration `json:"server-read-timeout" yaml:"server-read-timeout" usage:"the server read timeout on the http server"`
// ServerWriteTimeout is the write timeout on the http server // ServerWriteTimeout is the write timeout on the http server
......
...@@ -613,6 +613,8 @@ func (r *oauthProxy) createUpstreamProxy(upstream *url.URL) error { ...@@ -613,6 +613,8 @@ func (r *oauthProxy) createUpstreamProxy(upstream *url.URL) error {
ResponseHeaderTimeout: r.config.UpstreamResponseHeaderTimeout, ResponseHeaderTimeout: r.config.UpstreamResponseHeaderTimeout,
TLSClientConfig: tlsConfig, TLSClientConfig: tlsConfig,
TLSHandshakeTimeout: r.config.UpstreamTLSHandshakeTimeout, TLSHandshakeTimeout: r.config.UpstreamTLSHandshakeTimeout,
MaxIdleConns: r.config.MaxIdleConns,
MaxIdleConnsPerHost: r.config.MaxIdleConnsPerHost,
} }
return nil return nil
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment