William Yang 4 лет назад
Родитель
Сommit
6baf2dbd95

+ 8 - 2
apps/emqx/etc/emqx.conf

@@ -850,14 +850,20 @@ overload_protection {
  ## Backoff GC enabled
  ## Backoff GC enabled
  ## @doc overload_protection.backoff_gc
  ## @doc overload_protection.backoff_gc
  ## ValueType: Boolean
  ## ValueType: Boolean
- ## Default: true
- backoff_gc = true
+ ## Default: false
+ backoff_gc = false
 
 
  ## Backoff hibernation enabled
  ## Backoff hibernation enabled
  ## @doc overload_protection.backoff_hibernation
  ## @doc overload_protection.backoff_hibernation
  ## ValueType: Boolean
  ## ValueType: Boolean
  ## Default: true
  ## Default: true
  backoff_hibernation = true
  backoff_hibernation = true
+
+ ## Backoff hibernation enabled
+ ## @doc overload_protection.backoff_hibernation
+ ## ValueType: Boolean
+ ## Default: true
+ backoff_new_conn = true
 }
 }
 
 
 force_gc {
 force_gc {

+ 4 - 3
apps/emqx/src/emqx_connection.erl

@@ -317,15 +317,16 @@ exit_on_sock_error(Reason) ->
 %%--------------------------------------------------------------------
 %%--------------------------------------------------------------------
 %% Recv Loop
 %% Recv Loop
 
 
-recvloop(Parent, State = #state{idle_timeout = IdleTimeout}) ->
+recvloop(Parent, State = #state{ idle_timeout = IdleTimeout
+                               , zone = Zone
+                               }) ->
     receive
     receive
         Msg ->
         Msg ->
             handle_recv(Msg, Parent, State)
             handle_recv(Msg, Parent, State)
     after
     after
         IdleTimeout + 100 ->
         IdleTimeout + 100 ->
-            case emqx_olp:is_overloaded() of
+            case emqx_olp:backoff_hibernation(Zone) of
                 true ->
                 true ->
-                    emqx_metrics:inc('olp.hbn'),
                     recvloop(Parent, State);
                     recvloop(Parent, State);
                 false ->
                 false ->
                     hibernate(Parent, cancel_stats_timer(State))
                     hibernate(Parent, cancel_stats_timer(State))

+ 3 - 1
apps/emqx/src/emqx_listeners.erl

@@ -289,7 +289,9 @@ esockd_opts(Type, Opts0) ->
         infinity -> Opts1;
         infinity -> Opts1;
         Rate -> Opts1#{max_conn_rate => Rate}
         Rate -> Opts1#{max_conn_rate => Rate}
     end,
     end,
-    Opts3 = Opts2#{access_rules => esockd_access_rules(maps:get(access_rules, Opts0, []))},
+    Opts3 = Opts2#{ access_rules => esockd_access_rules(maps:get(access_rules, Opts0, []))
+                  , tune_fun => {emqx_olp, backoff_new_conn, [zone(Opts0)]}
+                  },
     maps:to_list(case Type of
     maps:to_list(case Type of
         tcp -> Opts3#{tcp_options => tcp_opts(Opts0)};
         tcp -> Opts3#{tcp_options => tcp_opts(Opts0)};
         ssl -> Opts3#{ssl_options => ssl_opts(Opts0), tcp_options => tcp_opts(Opts0)}
         ssl -> Opts3#{ssl_options => ssl_opts(Opts0), tcp_options => tcp_opts(Opts0)}

+ 2 - 2
apps/emqx/src/emqx_metrics.erl

@@ -190,7 +190,7 @@
          {counter, 'olp.delay.timeout'},
          {counter, 'olp.delay.timeout'},
          {counter, 'olp.hbn'},
          {counter, 'olp.hbn'},
          {counter, 'olp.gc'},
          {counter, 'olp.gc'},
-         {counter, 'olp.close.quic'}
+         {counter, 'olp.new_conn'}
         ]).
         ]).
 
 
 -record(state, {next_idx = 1}).
 -record(state, {next_idx = 1}).
@@ -585,7 +585,7 @@ reserved_idx('olp.delay.ok')                 -> 300;
 reserved_idx('olp.delay.timeout')            -> 301;
 reserved_idx('olp.delay.timeout')            -> 301;
 reserved_idx('olp.hbn')                      -> 302;
 reserved_idx('olp.hbn')                      -> 302;
 reserved_idx('olp.gc')                       -> 303;
 reserved_idx('olp.gc')                       -> 303;
-reserved_idx('olp.close.quic')               -> 304;
+reserved_idx('olp.new_conn')                 -> 304;
 
 
 reserved_idx(_)                              -> undefined.
 reserved_idx(_)                              -> undefined.
 
 

+ 34 - 12
apps/emqx/src/emqx_olp.erl

@@ -19,6 +19,7 @@
         , backoff/1
         , backoff/1
         , backoff_gc/1
         , backoff_gc/1
         , backoff_hibernation/1
         , backoff_hibernation/1
+        , backoff_new_conn/1
         ]).
         ]).
 
 
 
 
@@ -28,15 +29,16 @@
         , off/0
         , off/0
         ]).
         ]).
 
 
+-define(overload_protection, overload_protection).
+
 -spec is_overloaded() -> boolean().
 -spec is_overloaded() -> boolean().
 is_overloaded() ->
 is_overloaded() ->
   load_ctl:is_overloaded().
   load_ctl:is_overloaded().
 
 
 -spec backoff(Zone :: atom()) -> ok | false | timeout.
 -spec backoff(Zone :: atom()) -> ok | false | timeout.
 backoff(Zone) ->
 backoff(Zone) ->
-  case emqx_config:get_zone_conf(Zone, [overload_protection, enable], false) of
-    true ->
-      Delay = emqx_config:get_zone_conf(Zone, [overload_protection, backoff_delay], 1),
+  case emqx_config:get_zone_conf(Zone, [?overload_protection]) of
+    #{enable := true, backoff_delay := Delay} ->
       case load_ctl:maydelay(Delay) of
       case load_ctl:maydelay(Delay) of
         false -> false;
         false -> false;
         ok ->
         ok ->
@@ -46,21 +48,26 @@ backoff(Zone) ->
           emqx_metrics:inc('olp.delay.timeout'),
           emqx_metrics:inc('olp.delay.timeout'),
           timeout
           timeout
       end;
       end;
-    false ->
+    _ ->
       ok
       ok
   end.
   end.
 
 
--spec backoff_gc(Zone :: atom()) -> ok | timeout.
+-spec backoff_gc(Zone :: atom()) -> boolean().
 backoff_gc(Zone) ->
 backoff_gc(Zone) ->
-  load_ctl:is_overloaded()
-    andalso emqx_config:get_zone_conf(Zone, [overload_protection, enable], false)
-    andalso emqx_config:get_zone_conf(Zone, [overload_protection, backoff_gc], false).
+  do_check(Zone, ?FUNCTION_NAME, 'olp.gc').
 
 
--spec backoff_hibernation(Zone :: atom()) -> ok | timeout.
+-spec backoff_hibernation(Zone :: atom()) -> boolean().
 backoff_hibernation(Zone) ->
 backoff_hibernation(Zone) ->
-  load_ctl:is_overloaded()
-    andalso emqx_config:get_zone_conf(Zone, [overload_protection, enable], false)
-    andalso emqx_config:get_zone_conf(Zone, [overload_protection, backoff_hibernation], false).
+  do_check(Zone, ?FUNCTION_NAME, 'olp.hbn').
+
+-spec backoff_new_conn(Zone :: atom()) -> ok | {error, overloaded}.
+backoff_new_conn(Zone) ->
+  case do_check(Zone, ?FUNCTION_NAME, 'olp.new_conn') of
+    true ->
+      {error, overloaded};
+    false ->
+      ok
+  end.
 
 
 -spec status() -> any().
 -spec status() -> any().
 status() ->
 status() ->
@@ -74,6 +81,21 @@ off() ->
 on() ->
 on() ->
  load_ctl:restart_runq_flagman().
  load_ctl:restart_runq_flagman().
 
 
+%%% Internals
+do_check(Zone, Key, CntName) ->
+  case load_ctl:is_overloaded() of
+    true ->
+      case emqx_config:get_zone_conf(Zone, [?overload_protection]) of
+        #{enable := true, Key := true} ->
+          emqx_metrics:inc(CntName),
+          true;
+        _ ->
+          false
+      end;
+    false -> false
+  end.
+
+
 %%%_* Emacs ====================================================================
 %%%_* Emacs ====================================================================
 %%% Local Variables:
 %%% Local Variables:
 %%% allout-layout: t
 %%% allout-layout: t

+ 1 - 1
apps/emqx/src/emqx_quic_connection.erl

@@ -46,7 +46,7 @@ new_conn(Conn, S) ->
                     {error, stream_accept_error}
                     {error, stream_accept_error}
             end;
             end;
         true ->
         true ->
-            emqx_metrics:inc('olp.close.quic'),
+            emqx_metrics:inc('olp.new_conn'),
             {error, overloaded}
             {error, overloaded}
     end.
     end.
 
 

+ 5 - 1
apps/emqx/src/emqx_schema.erl

@@ -406,12 +406,16 @@ fields("overload_protection") ->
            })}
            })}
     , {"backoff_gc",
     , {"backoff_gc",
        sc(boolean(),
        sc(boolean(),
-          #{ default => true
+          #{ default => false
            })}
            })}
     , {"backoff_hibernation",
     , {"backoff_hibernation",
        sc(boolean(),
        sc(boolean(),
           #{ default => true
           #{ default => true
            })}
            })}
+    , {"backoff_new_conn",
+       sc(boolean(),
+          #{ default => true
+           })}
     ];
     ];
 
 
 fields("conn_congestion") ->
 fields("conn_congestion") ->