You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by sh...@apache.org on 2019/09/03 13:54:31 UTC

[trafficserver] branch master updated: Provide stats for the recently introduced HTTP/2 rate limits

This is an automated email from the ASF dual-hosted git repository.

shinrich pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 5ec8112  Provide stats for the recently introduced HTTP/2 rate limits
5ec8112 is described below

commit 5ec81125bd70d31f545cf959b65c4e929d26a192
Author: Valentin Gutierrez <vg...@wikimedia.org>
AuthorDate: Thu Aug 29 00:03:36 2019 +0800

    Provide stats for the recently introduced HTTP/2 rate limits
    
    Provide stats for the limits introduced by 9c09dbc11
---
 .../statistics/core/http-connection.en.rst         | 42 ++++++++++++++++++++++
 proxy/http2/HTTP2.cc                               | 21 +++++++++++
 proxy/http2/HTTP2.h                                |  6 ++++
 proxy/http2/Http2ConnectionState.cc                |  6 ++++
 4 files changed, 75 insertions(+)

diff --git a/doc/admin-guide/monitoring/statistics/core/http-connection.en.rst b/doc/admin-guide/monitoring/statistics/core/http-connection.en.rst
index 411881f..42c680e 100644
--- a/doc/admin-guide/monitoring/statistics/core/http-connection.en.rst
+++ b/doc/admin-guide/monitoring/statistics/core/http-connection.en.rst
@@ -204,3 +204,45 @@ HTTP/2
 
    Represents the total number of closed HTTP/2 connections with high
    error rate which is configured by :ts:cv:`proxy.config.http2.stream_error_rate_threshold`.
+
+.. ts:stat:: global proxy.process.http2.max_settings_per_frame_exceeded integer
+   :type: counter
+
+   Represents the total number of closed HTTP/2 connections for exceeding the
+   maximum allowed number of settings per frame limit which is configured by
+   :ts:cv:`proxy.config.http2.max_settings_per_frame`.
+
+.. ts:stat:: global proxy.process.http2.max_settings_per_minute_exceeded integer
+   :type: counter
+
+   Represents the total number of closed HTTP/2 connections for exceeding the
+   maximum allowed number of settings per minute limit which is configured by
+   :ts:cv:`proxy.config.http2.max_settings_per_minute`.
+
+.. ts:stat:: global proxy.process.http2.max_settings_frames_per_minute_exceeded integer
+   :type: counter
+
+   Represents the total number of closed HTTP/2 connections for exceeding the
+   maximum allowed number of settings frames per minute limit which is configured by
+   :ts:cv:`proxy.config.http2.max_settings_frames_per_minute`.
+
+.. ts:stat:: global proxy.process.http2.max_ping_frames_per_minute_exceeded integer
+   :type: counter
+
+   Represents the total number of closed HTTP/2 connections for exceeding the
+   maximum allowed number of ping frames per minute limit which is configured by
+   :ts:cv:`proxy.config.http2.max_ping_frames_per_minute`.
+
+.. ts:stat:: global proxy.process.http2.max_priority_frames_per_minute_exceeded integer
+   :type: counter
+
+   Represents the total number of closed HTTP/2 connections for exceeding the
+   maximum allowed number of priority frames per minute limit which is configured by
+   :ts:cv:`proxy.config.http2.max_priority_frames_per_minute`.
+
+.. ts:stat:: global proxy.process.http2.insufficient_avg_window_update integer
+   :type: counter
+
+   Represents the total number of closed HTTP/2 connections for not reaching the
+   minimum average window increment limit which is configured by
+   :ts:cv:`proxy.config.http2.min_avg_window_update`.
diff --git a/proxy/http2/HTTP2.cc b/proxy/http2/HTTP2.cc
index 81f741d..6e427bb 100644
--- a/proxy/http2/HTTP2.cc
+++ b/proxy/http2/HTTP2.cc
@@ -62,6 +62,15 @@ static const char *const HTTP2_STAT_SESSION_DIE_INACTIVE_NAME             = "pro
 static const char *const HTTP2_STAT_SESSION_DIE_EOS_NAME                  = "proxy.process.http2.session_die_eos";
 static const char *const HTTP2_STAT_SESSION_DIE_ERROR_NAME                = "proxy.process.http2.session_die_error";
 static const char *const HTTP2_STAT_SESSION_DIE_HIGH_ERROR_RATE_NAME      = "proxy.process.http2.session_die_high_error_rate";
+static const char *const HTTP2_STAT_MAX_SETTINGS_PER_FRAME_EXCEEDED_NAME  = "proxy.process.http2.max_settings_per_frame_exceeded";
+static const char *const HTTP2_STAT_MAX_SETTINGS_PER_MINUTE_EXCEEDED_NAME = "proxy.process.http2.max_settings_per_minute_exceeded";
+static const char *const HTTP2_STAT_MAX_SETTINGS_FRAMES_PER_MINUTE_EXCEEDED_NAME =
+  "proxy.process.http2.max_settings_frames_per_minute_exceeded";
+static const char *const HTTP2_STAT_MAX_PING_FRAMES_PER_MINUTE_EXCEEDED_NAME =
+  "proxy.process.http2.max_ping_frames_per_minute_exceeded";
+static const char *const HTTP2_STAT_MAX_PRIORITY_FRAMES_PER_MINUTE_EXCEEDED_NAME =
+  "proxy.process.http2.max_priority_frames_per_minute_exceeded";
+static const char *const HTTP2_STAT_INSUFFICIENT_AVG_WINDOW_UPDATE_NAME = "proxy.process.http2.insufficient_avg_window_update";
 
 union byte_pointer {
   byte_pointer(void *p) : ptr(p) {}
@@ -820,6 +829,18 @@ Http2::init()
                      static_cast<int>(HTTP2_STAT_SESSION_DIE_ERROR), RecRawStatSyncSum);
   RecRegisterRawStat(http2_rsb, RECT_PROCESS, HTTP2_STAT_SESSION_DIE_HIGH_ERROR_RATE_NAME, RECD_INT, RECP_PERSISTENT,
                      static_cast<int>(HTTP2_STAT_SESSION_DIE_HIGH_ERROR_RATE), RecRawStatSyncSum);
+  RecRegisterRawStat(http2_rsb, RECT_PROCESS, HTTP2_STAT_MAX_SETTINGS_PER_FRAME_EXCEEDED_NAME, RECD_INT, RECP_PERSISTENT,
+                     static_cast<int>(HTTP2_STAT_MAX_SETTINGS_PER_FRAME_EXCEEDED), RecRawStatSyncSum);
+  RecRegisterRawStat(http2_rsb, RECT_PROCESS, HTTP2_STAT_MAX_SETTINGS_PER_MINUTE_EXCEEDED_NAME, RECD_INT, RECP_PERSISTENT,
+                     static_cast<int>(HTTP2_STAT_MAX_SETTINGS_PER_MINUTE_EXCEEDED), RecRawStatSyncSum);
+  RecRegisterRawStat(http2_rsb, RECT_PROCESS, HTTP2_STAT_MAX_SETTINGS_FRAMES_PER_MINUTE_EXCEEDED_NAME, RECD_INT, RECP_PERSISTENT,
+                     static_cast<int>(HTTP2_STAT_MAX_SETTINGS_FRAMES_PER_MINUTE_EXCEEDED), RecRawStatSyncSum);
+  RecRegisterRawStat(http2_rsb, RECT_PROCESS, HTTP2_STAT_MAX_PING_FRAMES_PER_MINUTE_EXCEEDED_NAME, RECD_INT, RECP_PERSISTENT,
+                     static_cast<int>(HTTP2_STAT_MAX_PING_FRAMES_PER_MINUTE_EXCEEDED), RecRawStatSyncSum);
+  RecRegisterRawStat(http2_rsb, RECT_PROCESS, HTTP2_STAT_MAX_PRIORITY_FRAMES_PER_MINUTE_EXCEEDED_NAME, RECD_INT, RECP_PERSISTENT,
+                     static_cast<int>(HTTP2_STAT_MAX_PRIORITY_FRAMES_PER_MINUTE_EXCEEDED), RecRawStatSyncSum);
+  RecRegisterRawStat(http2_rsb, RECT_PROCESS, HTTP2_STAT_INSUFFICIENT_AVG_WINDOW_UPDATE_NAME, RECD_INT, RECP_PERSISTENT,
+                     static_cast<int>(HTTP2_STAT_INSUFFICIENT_AVG_WINDOW_UPDATE), RecRawStatSyncSum);
 }
 
 #if TS_HAS_TESTS
diff --git a/proxy/http2/HTTP2.h b/proxy/http2/HTTP2.h
index 85e2669..083eda4 100644
--- a/proxy/http2/HTTP2.h
+++ b/proxy/http2/HTTP2.h
@@ -84,6 +84,12 @@ enum {
   HTTP2_STAT_SESSION_DIE_EOS,
   HTTP2_STAT_SESSION_DIE_ERROR,
   HTTP2_STAT_SESSION_DIE_HIGH_ERROR_RATE,
+  HTTP2_STAT_MAX_SETTINGS_PER_FRAME_EXCEEDED,
+  HTTP2_STAT_MAX_SETTINGS_PER_MINUTE_EXCEEDED,
+  HTTP2_STAT_MAX_SETTINGS_FRAMES_PER_MINUTE_EXCEEDED,
+  HTTP2_STAT_MAX_PING_FRAMES_PER_MINUTE_EXCEEDED,
+  HTTP2_STAT_MAX_PRIORITY_FRAMES_PER_MINUTE_EXCEEDED,
+  HTTP2_STAT_INSUFFICIENT_AVG_WINDOW_UPDATE,
 
   HTTP2_N_STATS // Terminal counter, NOT A STAT INDEX.
 };
diff --git a/proxy/http2/Http2ConnectionState.cc b/proxy/http2/Http2ConnectionState.cc
index c538070..f19f217 100644
--- a/proxy/http2/Http2ConnectionState.cc
+++ b/proxy/http2/Http2ConnectionState.cc
@@ -421,6 +421,7 @@ rcv_priority_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
   cstate.increment_received_priority_frame_count();
   // Close this conection if its priority frame count received exceeds a limit
   if (cstate.get_received_priority_frame_count() > Http2::max_priority_frames_per_minute) {
+    HTTP2_INCREMENT_THREAD_DYN_STAT(HTTP2_STAT_MAX_PRIORITY_FRAMES_PER_MINUTE_EXCEEDED, this_ethread());
     Http2StreamDebug(cstate.ua_session, stream_id,
                      "Observed too frequent priority changes: %u priority changes within a last minute",
                      cstate.get_received_priority_frame_count());
@@ -537,6 +538,7 @@ rcv_settings_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
   cstate.increment_received_settings_frame_count();
   // Close this conection if its SETTINGS frame count exceeds a limit
   if (cstate.get_received_settings_frame_count() > Http2::max_settings_frames_per_minute) {
+    HTTP2_INCREMENT_THREAD_DYN_STAT(HTTP2_STAT_MAX_SETTINGS_FRAMES_PER_MINUTE_EXCEEDED, this_ethread());
     Http2StreamDebug(cstate.ua_session, stream_id, "Observed too frequent SETTINGS frames: %u frames within a last minute",
                      cstate.get_received_settings_frame_count());
     return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_ENHANCE_YOUR_CALM,
@@ -575,6 +577,7 @@ rcv_settings_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
   uint32_t n_settings = 0;
   while (nbytes < frame.header().length) {
     if (n_settings >= Http2::max_settings_per_frame) {
+      HTTP2_INCREMENT_THREAD_DYN_STAT(HTTP2_STAT_MAX_SETTINGS_PER_FRAME_EXCEEDED, this_ethread());
       Http2StreamDebug(cstate.ua_session, stream_id, "Observed too many settings in a frame");
       return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_ENHANCE_YOUR_CALM,
                         "recv settings too many settings in a frame");
@@ -615,6 +618,7 @@ rcv_settings_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
   cstate.increment_received_settings_count(n_settings);
   // Close this conection if its settings count received exceeds a limit
   if (cstate.get_received_settings_count() > Http2::max_settings_per_minute) {
+    HTTP2_INCREMENT_THREAD_DYN_STAT(HTTP2_STAT_MAX_SETTINGS_PER_MINUTE_EXCEEDED, this_ethread());
     Http2StreamDebug(cstate.ua_session, stream_id, "Observed too frequent setting changes: %u settings within a last minute",
                      cstate.get_received_settings_count());
     return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_ENHANCE_YOUR_CALM,
@@ -668,6 +672,7 @@ rcv_ping_frame(Http2ConnectionState &cstate, const Http2Frame &frame)
   cstate.increment_received_ping_frame_count();
   // Close this conection if its ping count received exceeds a limit
   if (cstate.get_received_ping_frame_count() > Http2::max_ping_frames_per_minute) {
+    HTTP2_INCREMENT_THREAD_DYN_STAT(HTTP2_STAT_MAX_PING_FRAMES_PER_MINUTE_EXCEEDED, this_ethread());
     Http2StreamDebug(cstate.ua_session, stream_id, "Observed too frequent PING frames: %u PING frames within a last minute",
                      cstate.get_received_ping_frame_count());
     return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_ENHANCE_YOUR_CALM,
@@ -1998,6 +2003,7 @@ Http2ConnectionState::increment_client_rwnd(size_t amount)
   double sum = std::accumulate(this->_recent_rwnd_increment.begin(), this->_recent_rwnd_increment.end(), 0.0);
   double avg = sum / this->_recent_rwnd_increment.size();
   if (avg < Http2::min_avg_window_update) {
+    HTTP2_INCREMENT_THREAD_DYN_STAT(HTTP2_STAT_INSUFFICIENT_AVG_WINDOW_UPDATE, this_ethread());
     return Http2ErrorCode::HTTP2_ERROR_ENHANCE_YOUR_CALM;
   }
   return Http2ErrorCode::HTTP2_ERROR_NO_ERROR;