Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.x: speed up node startup by avoid loading all modules during boot #10989

Merged
merged 1 commit into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions deps/rabbit/src/rabbit.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,20 @@ do_run_postlaunch_phase(Plugins) ->
?LOG_DEBUG(""),
?LOG_DEBUG("== Plugins (postlaunch phase) =="),

%% Before loading plugins, set the prometheus collectors and
%% instrumenters to the empty list. By default, prometheus will attempt
%% to find all implementers of its collector and instrumenter
%% behaviours by scanning all available modules during application
%% start. This can take significant time (on the order of seconds) due
%% to the large number of modules available.
%%
%% * Collectors: the `rabbitmq_prometheus' plugin explicitly registers
%% all collectors.
%% * Instrumenters: no instrumenters are used.
_ = application:load(prometheus),
ok = application:set_env(prometheus, collectors, [default]),
ok = application:set_env(prometheus, instrumenters, []),

%% However, we want to run their boot steps and actually start
%% them one by one, to ensure a dependency is fully started
%% before a plugin which depends on it gets a chance to start.
Expand Down
17 changes: 13 additions & 4 deletions deps/rabbitmq_management/src/rabbit_mgmt_dispatcher.erl
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,18 @@ build_module_routes(Ignore) ->
Routes = [Module:dispatcher() || Module <- modules(Ignore)],
[{"/api" ++ Path, Mod, Args} || {Path, Mod, Args} <- lists:append(Routes)].

modules(IgnoreApps) ->
[Module || {App, Module, Behaviours} <-
modules(IgnoreApps0) ->
Apps0 = rabbit_misc:rabbitmq_related_apps(),
Apps = case IgnoreApps0 of
[] ->
Apps0;
_ ->
IgnoreApps = sets:from_list(IgnoreApps0, [{version, 2}]),
lists:filter(
fun(App) -> not sets:is_element(App, IgnoreApps) end,
Apps0)
end,
[Module || {_App, Module, Behaviours} <-
%% Sort rabbitmq_management modules first. This is
%% a microoptimization because most files belong to
%% this application. Making it first avoids several
Expand All @@ -76,8 +86,7 @@ modules(IgnoreApps) ->
(_, {rabbitmq_management, _, _}) -> false;
({A, _, _}, {B, _, _}) -> A =< B
end,
rabbit_misc:all_module_attributes(behaviour)),
not lists:member(App, IgnoreApps),
rabbit_misc:module_attributes_from_apps(behaviour, Apps)),
lists:member(rabbit_mgmt_extension, Behaviours)].

module_app(Module) ->
Expand Down
Loading