A scriptable load generator for MQTT
Start 100 clients connecting to localhost with 10ms pause in between.
Clients publish a 1kb-size message every 10ms to topic t/%clientid%
.
Run steady traffic for 30s and then exit:
emqttb --loiter 30s \
@pub --topic 't/%n' --conninterval 10ms --pubinterval 10ms --num-clients 100 --size 1kb \
@g --host 127.0.0.1
Same with shortened arguments:
emqttb -L 30s @pub -t 't/%n' -I 10ms -i 10ms -N 100 -s 1kb @g -h 127.0.0.1
Start 10 clients that subscribe to a wildcard topic and run steady traffic for 30s:
emqttb --loiter 30s \
@sub --topic 't/#' --conninterval 10ms --num-clients 10 \
@g --host 127.0.0.1
Same with shortened arguments:
emqttb -L 30s @sub -t 't/#' -I 10ms -N 10 @g -h 127.0.0.1
Combine the above scenarios in a single command:
emqttb -L 30s @pub -t 't/%n' -I 10ms -i 10ms -N 100 -s 1kb \
@sub -t 't/#' -I 10ms -N 10 @g -h 127.0.0.1
EMQTTB executable accepts named CLI arguments (such as --foo
or -f
positional arguments and actions.
Actions are special CLI arguments that start with @
character (e.g. @my-action
).
Actions correspond to different load-generation scenarios, such as @pub
and @sub
, client group configurations and autorates.
Each CLI action defines its own scope of named and positional CLI arguments. Positional arguments are always specified after named arguments within the scope. There is also a global scope of arguments that don’t belong to any action. Global arguments are specified before the very first action.
Example:
emqttb --foo --bar 1 positional1 positional2 @action1 --foo 1 positional1 @action2 ...
|___________| |_____________________| |_________________|
|regular args positional args | action1 scope
|___________________________________|
global scope
Additional features:
-
Boolean flag arguments can be set to false by adding
no-
prefix, for example--no-pushgw
-
Short boolean flags can be set to false using
+
sigil instead of-
emqttb tries to keep the standard output clean, so all the logs generated by the workers and MQTT clients are forwarded to /tmp/emqttb.log
file.
Most errors and messages are found there.
-
Worker is a process that corresponds to a single MQTT client
-
Behavior is a callback module containing functions that workers run in a loop
-
Group is a supervised colletion of workers running the same behavior and sharing the same configuration. Group manager controls the number of workers, restarts failed workers and implements ramp up/down logic.
-
Scenario is a callback module that creates several worker groups and manupulates group configuration using autorate.
-
Autorate a process that adjusts group parameters (such as number of workers in the group, or worker configuration) based on constants or dynamic parameters, e.g. available RAM or CPU load, observed latency and so on.
Load generation scenarios (such as @pub
and @sub
) don’t explicitly specify how the clients should connect to the MQTT broker.
These settings are delegated to clinet group configuration action (@g
).
Each group configuration has an id. EMQTTB always creates a default group with id=default
.
All scenarios use it by default.
Scenarios use group configuration for each client group they create.
For example, @pub
scenario creates only one group for publishers which is specified by --group
or -g
CLI argument.
Usually this scenario is invoked with implicit default
group configuration:
emqttb @pub -t foo @g -h localhost
It is equivalent to the following command:
emqttb @pub -t foo --group default @g --group default -h localhost
Sometimes it is necessary to use different group configurations for different scenarios. For example, imagine we need to test pub/sub scenario where publishers use websocket connections and subscribers use MQTT, or we want to test bridging between MQTT brokers that have different hostnames. It can be achieved like this:
emqttb @pub -t 'foo/%n' -g wss \
@sub -t 'foo/#' -g mqtt \
@g -g wss -h localhost --transport ws --ssl \
@g -g mqtt -h localhost --transport sock
EMQTTB can export metrics to Prometheus using pushgateway or scraping REST endpoint.
Scraping endpoint is enabled automatically when the script is started with --restapi
global flag.
Pushgateway should be enabled explicitly:
emqttb --pushgw --pushgw-url http://localhost:9091
There is a ready-to-use grafana dashboard for emqttb: emqttb-dashboard.json. Also there is a fully ready docker images that include Grafana and Postgres with all the necessary schemas and dashboards for emqttb and emqx performance analysis: github.com/ieQu1/grafana-dashboards.
Additionally, EMQTTB can add annotations to grafana dashboards when scenarios start, advance to a next stage or finish.
This requires a Grafana API key with Editor
role.
Once the key is obtained, it can be used like this:
export EMQTTB_METRICS__GRAFANA__API_KEY="Bearer eyJrIjoiNmhSdTFnWGJlaE9tZXQ2YXI4WlEyUGNSMXFMb1oyUXkiLCJuIjoiZW1xdHRiIiwiaWQiOjF9"
export EMQTTB_METRICS__GRAFANA__URL="http://localhost:3000"
emqttb --grafana ...
Requirements:
-
make
-
cmake (for quicer)
If you want to build HTML documentation and manpages, it’s necessary to install the following tools:
-
asciidoctor (lee dependency)
-
xsltproc
-
docbook-xsl
-
java (jre is enough)
This can be omitted by running export CAN_BUILD_DOCS=false
.
git clone [email protected]:emqx/emqttb.git
cd emqttb
make release
Assuming you already have Homebrew installed.
brew install erlang rebar3 cmake java asciidoctor xsltproc docbook-xsl
git clone [email protected]:emqx/emqttb.git
cd emqttb
export MANPAGE_STYLESHEET=$(brew --prefix docbook-xsl)/docbook-xsl/manpages/docbook.xsl
make release
It is possible to get information about CLI actions by running emqttb --help <command>
.
For example, the following command will show manual page about @pub
scenario:
emqttb --help pub
emqttb also serves the documentation in HTML format directly from the REST endpoint (emqttb --restapi
).
It is available at the following URL: http://localhost:8017/doc/index.html