Optimizing NGINX TLS Time To First Byte (TTTFB)
Maxim Dounin
mdounin at mdounin.ru
Wed Dec 18 16:38:04 UTC 2013
Hello!
On Tue, Dec 17, 2013 at 04:03:27PM -0800, Ilya Grigorik wrote:
[...]
> Although now on closer inspection there seems to be another gotcha in there
> that I overlooked: it's emitting two packets, one is 1389 bytes, and second
> is ~31 extra bytes, which means the actual record is 1429 bytes. Obviously,
> this should be a single packet... and 1400 bytes.
We've discussed this alot here a while ago, and it turns
out that it's very non-trivial task to fill exactly one packet -
as space in packets may vary depending on TCP options used, MTU,
tunnels used on a way to a client, etc.
On the other hand, it looks good enough to have records up to
initial CWND in size without any significant latency changes. And
with IW10 this basically means that anything up to about 14k
should be fine (with RFC3390, something like 4k should be ok).
It also reduces bandwidth costs associated with using multiple
records.
Just in case, below is a patch to play with SSL buffer size:
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1387302972 -14400
# Tue Dec 17 21:56:12 2013 +0400
# Node ID 090a57a2a599049152e87693369b6921efcd6bca
# Parent e7d1a00f06731d7508ec120c1ac91c337d15c669
SSL: ssl_buffer_size directive.
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -190,6 +190,8 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_
return NGX_ERROR;
}
+ ssl->buffer_size = NGX_SSL_BUFSIZE;
+
/* client side options */
SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_SESS_ID_BUG);
@@ -726,6 +728,7 @@ ngx_ssl_create_connection(ngx_ssl_t *ssl
}
sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
+ sc->buffer_size = ssl->buffer_size;
sc->connection = SSL_new(ssl->ctx);
@@ -1222,7 +1225,7 @@ ngx_ssl_send_chain(ngx_connection_t *c,
buf = c->ssl->buf;
if (buf == NULL) {
- buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE);
+ buf = ngx_create_temp_buf(c->pool, c->ssl->buffer_size);
if (buf == NULL) {
return NGX_CHAIN_ERROR;
}
@@ -1231,14 +1234,14 @@ ngx_ssl_send_chain(ngx_connection_t *c,
}
if (buf->start == NULL) {
- buf->start = ngx_palloc(c->pool, NGX_SSL_BUFSIZE);
+ buf->start = ngx_palloc(c->pool, c->ssl->buffer_size);
if (buf->start == NULL) {
return NGX_CHAIN_ERROR;
}
buf->pos = buf->start;
buf->last = buf->start;
- buf->end = buf->start + NGX_SSL_BUFSIZE;
+ buf->end = buf->start + c->ssl->buffer_size;
}
send = buf->last - buf->pos;
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -29,6 +29,7 @@
typedef struct {
SSL_CTX *ctx;
ngx_log_t *log;
+ size_t buffer_size;
} ngx_ssl_t;
@@ -37,6 +38,7 @@ typedef struct {
ngx_int_t last;
ngx_buf_t *buf;
+ size_t buffer_size;
ngx_connection_handler_pt handler;
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -111,6 +111,13 @@ static ngx_command_t ngx_http_ssl_comma
offsetof(ngx_http_ssl_srv_conf_t, ciphers),
NULL },
+ { ngx_string("ssl_buffer_size"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_size_slot,
+ NGX_HTTP_SRV_CONF_OFFSET,
+ offsetof(ngx_http_ssl_srv_conf_t, buffer_size),
+ NULL },
+
{ ngx_string("ssl_verify_client"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_enum_slot,
@@ -424,6 +431,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t
sscf->enable = NGX_CONF_UNSET;
sscf->prefer_server_ciphers = NGX_CONF_UNSET;
+ sscf->buffer_size = NGX_CONF_UNSET_SIZE;
sscf->verify = NGX_CONF_UNSET_UINT;
sscf->verify_depth = NGX_CONF_UNSET_UINT;
sscf->builtin_session_cache = NGX_CONF_UNSET;
@@ -465,6 +473,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *
(NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1
|NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
+ ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
+ NGX_SSL_BUFSIZE);
+
ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
@@ -572,6 +583,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *
return NGX_CONF_ERROR;
}
+ conf->ssl.buffer_size = conf->buffer_size;
+
if (conf->verify) {
if (conf->client_certificate.len == 0 && conf->verify != 3) {
diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h
--- a/src/http/modules/ngx_http_ssl_module.h
+++ b/src/http/modules/ngx_http_ssl_module.h
@@ -26,6 +26,8 @@ typedef struct {
ngx_uint_t verify;
ngx_uint_t verify_depth;
+ size_t buffer_size;
+
ssize_t builtin_session_cache;
time_t session_timeout;
--
Maxim Dounin
http://nginx.org/
More information about the nginx
mailing list