feat(olp): backoff new conn

This commit is contained in:
William Yang 2021-10-05 09:21:32 +02:00
parent 370edac031
commit 6baf2dbd95
7 changed files with 57 additions and 22 deletions

View File

@ -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 ## Default: false
backoff_gc = true 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 {

View File

@ -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))

View File

@ -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)}

View File

@ -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.

View File

@ -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 case emqx_config:get_zone_conf(Zone, [?overload_protection]) of
true -> #{enable := true, backoff_delay := Delay} ->
Delay = emqx_config:get_zone_conf(Zone, [overload_protection, backoff_delay], 1),
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() do_check(Zone, ?FUNCTION_NAME, 'olp.gc').
andalso emqx_config:get_zone_conf(Zone, [overload_protection, enable], false)
andalso emqx_config:get_zone_conf(Zone, [overload_protection, backoff_gc], false).
-spec backoff_hibernation(Zone :: atom()) -> ok | timeout. -spec backoff_hibernation(Zone :: atom()) -> boolean().
backoff_hibernation(Zone) -> backoff_hibernation(Zone) ->
load_ctl:is_overloaded() do_check(Zone, ?FUNCTION_NAME, 'olp.hbn').
andalso emqx_config:get_zone_conf(Zone, [overload_protection, enable], false)
andalso emqx_config:get_zone_conf(Zone, [overload_protection, backoff_hibernation], false). -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

View File

@ -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.

View File

@ -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") ->