summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Klishin <mklishin@pivotal.io>2015-10-23 01:23:53 +0300
committerMichael Klishin <mklishin@pivotal.io>2015-10-23 01:23:53 +0300
commitad461b30e9c0104277dff7ec937354d1fc1e64d5 (patch)
tree7bd77f399c15b91b2cb319d8ec9dae10cd40ef6d
parent2bc39429a943957d64b29a1c7a70a8e787e2cd18 (diff)
parent1474424ed873b756438bc6a1a3e0fcebb8e9c958 (diff)
downloadrabbitmq-server-git-ad461b30e9c0104277dff7ec937354d1fc1e64d5.tar.gz
Merge branch 'stable'
-rw-r--r--docs/rabbitmq.config.example4
-rw-r--r--docs/rabbitmqctl.1.xml15
-rw-r--r--src/rabbit_control_main.erl6
-rw-r--r--src/vm_memory_monitor.erl28
-rw-r--r--test/src/rabbit_tests.erl12
5 files changed, 55 insertions, 10 deletions
diff --git a/docs/rabbitmq.config.example b/docs/rabbitmq.config.example
index dd1a4e6c87..6be9504b8b 100644
--- a/docs/rabbitmq.config.example
+++ b/docs/rabbitmq.config.example
@@ -193,6 +193,10 @@
%%
%% {vm_memory_high_watermark, 0.4},
+ %% Alternatively, we can set a limit (in megabytes) of RAM used by the node.
+ %%
+ %% {vm_memory_high_watermark, {absolute, 1024}},
+
%% Fraction of the high watermark limit at which queues start to
%% page message out to disc in order to free up memory.
%%
diff --git a/docs/rabbitmqctl.1.xml b/docs/rabbitmqctl.1.xml
index 74ef71108e..43d00418e6 100644
--- a/docs/rabbitmqctl.1.xml
+++ b/docs/rabbitmqctl.1.xml
@@ -1930,6 +1930,21 @@
</variablelist>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><cmdsynopsis><command>set_vm_memory_high_watermark absolute</command> <arg choice="req"><replaceable>memory_limit_mb</replaceable></arg></cmdsynopsis></term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>memory_limit_mb</term>
+ <listitem><para>
+ The new memory limit at which flow control is
+ triggered, expressed in MB as an integer number
+ greater than or equal to 0.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect2>
</refsect1>
diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl
index fe0563bbc7..59223dc19b 100644
--- a/src/rabbit_control_main.erl
+++ b/src/rabbit_control_main.erl
@@ -410,6 +410,12 @@ action(set_vm_memory_high_watermark, Node, [Arg], _Opts, Inform) ->
Inform("Setting memory threshold on ~p to ~p", [Node, Frac]),
rpc_call(Node, vm_memory_monitor, set_vm_memory_high_watermark, [Frac]);
+action(set_vm_memory_high_watermark, Node, ["absolute", Arg], _Opts, Inform) ->
+ Limit = list_to_integer(Arg),
+ Inform("Setting memory threshold on ~p to ~pMB", [Node, Limit]),
+ rpc_call(Node, vm_memory_monitor, set_vm_memory_high_watermark,
+ [{absolute, Limit}]);
+
action(set_permissions, Node, [Username, CPerm, WPerm, RPerm], Opts, Inform) ->
VHost = proplists:get_value(?VHOST_OPT, Opts),
Inform("Setting permissions for user \"~s\" in vhost \"~s\"",
diff --git a/src/vm_memory_monitor.erl b/src/vm_memory_monitor.erl
index bf9a77c174..fe68f50239 100644
--- a/src/vm_memory_monitor.erl
+++ b/src/vm_memory_monitor.erl
@@ -52,7 +52,7 @@
-record(state, {total_memory,
memory_limit,
- memory_fraction,
+ memory_config_limit,
timeout,
timer,
alarmed,
@@ -63,6 +63,7 @@
-ifdef(use_specs).
+-type(vm_memory_high_watermark() :: (float() | {'absolute', integer()})).
-spec(start_link/1 :: (float()) -> rabbit_types:ok_pid_or_error()).
-spec(start_link/3 :: (float(), fun ((any()) -> 'ok'),
fun ((any()) -> 'ok')) -> rabbit_types:ok_pid_or_error()).
@@ -70,8 +71,8 @@
-spec(get_vm_limit/0 :: () -> non_neg_integer()).
-spec(get_check_interval/0 :: () -> non_neg_integer()).
-spec(set_check_interval/1 :: (non_neg_integer()) -> 'ok').
--spec(get_vm_memory_high_watermark/0 :: () -> float()).
--spec(set_vm_memory_high_watermark/1 :: (float()) -> 'ok').
+-spec(get_vm_memory_high_watermark/0 :: () -> vm_memory_high_watermark()).
+-spec(set_vm_memory_high_watermark/1 :: (vm_memory_high_watermark()) -> 'ok').
-spec(get_memory_limit/0 :: () -> non_neg_integer()).
-endif.
@@ -128,11 +129,12 @@ init([MemFraction, AlarmFuns]) ->
alarm_funs = AlarmFuns },
{ok, set_mem_limits(State, MemFraction)}.
-handle_call(get_vm_memory_high_watermark, _From, State) ->
- {reply, State#state.memory_fraction, State};
+handle_call(get_vm_memory_high_watermark, _From,
+ #state{memory_config_limit = MemLimit} = State) ->
+ {reply, MemLimit, State};
-handle_call({set_vm_memory_high_watermark, MemFraction}, _From, State) ->
- {reply, ok, set_mem_limits(State, MemFraction)};
+handle_call({set_vm_memory_high_watermark, MemLimit}, _From, State) ->
+ {reply, ok, set_mem_limits(State, MemLimit)};
handle_call(get_check_interval, _From, State) ->
{reply, State#state.timeout, State};
@@ -166,7 +168,7 @@ code_change(_OldVsn, State, _Extra) ->
%% Server Internals
%%----------------------------------------------------------------------------
-set_mem_limits(State, MemFraction) ->
+set_mem_limits(State, MemLimit) ->
case erlang:system_info(wordsize) of
4 ->
error_logger:warning_msg(
@@ -206,12 +208,18 @@ set_mem_limits(State, MemFraction) ->
_ ->
TotalMemory
end,
- MemLim = trunc(MemFraction * UsableMemory),
+ MemLim = interpret_limit(MemLimit, UsableMemory),
error_logger:info_msg("Memory limit set to ~pMB of ~pMB total.~n",
[trunc(MemLim/?ONE_MB), trunc(TotalMemory/?ONE_MB)]),
internal_update(State #state { total_memory = TotalMemory,
memory_limit = MemLim,
- memory_fraction = MemFraction}).
+ memory_config_limit = MemLimit}).
+
+interpret_limit({'absolute', MemLim}, UsableMemory) ->
+ %% Absolute memory is provided in MB
+ min(MemLim * ?ONE_MB, UsableMemory);
+interpret_limit(MemFraction, UsableMemory) ->
+ trunc(MemFraction * UsableMemory).
internal_update(State = #state { memory_limit = MemLimit,
alarmed = Alarmed,
diff --git a/test/src/rabbit_tests.erl b/test/src/rabbit_tests.erl
index e7df47a3d8..44bf3da5f2 100644
--- a/test/src/rabbit_tests.erl
+++ b/test/src/rabbit_tests.erl
@@ -91,6 +91,7 @@ all_tests0() ->
passed = test_configurable_server_properties(),
passed = vm_memory_monitor_tests:all_tests(),
passed = credit_flow_test:test_credit_flow_settings(),
+ passed = test_memory_high_watermark(),
passed = on_disk_store_tunable_parameter_validation_test:test_msg_store_parameter_validation(),
passed = password_hashing_tests:test_password_hashing(),
passed = credit_flow_test:test_credit_flow_settings(),
@@ -3218,3 +3219,14 @@ test_configurable_server_properties() ->
nop(_) -> ok.
nop(_, _) -> ok.
+
+test_memory_high_watermark() ->
+ %% set vm memory high watermark
+ HWM = vm_memory_monitor:get_vm_memory_high_watermark(),
+ %% this will trigger an alarm (memory unit is MB)
+ ok = control_action(set_vm_memory_high_watermark, ["absolute", "2"]),
+ [{{resource_limit,memory,_},[]}] = rabbit_alarm:get_alarms(),
+ %% reset
+ ok = control_action(set_vm_memory_high_watermark, [float_to_list(HWM)]),
+
+ passed.