Merge pull request #771 from emqtt/emq20

Move docs/* to emqtt/docs_en project
This commit is contained in:
Feng Lee 2016-11-20 19:55:55 +08:00 committed by GitHub
commit a8a3812575
38 changed files with 4 additions and 7984 deletions

View File

@ -1 +0,0 @@
Move to docs/source/changes.rst

0
deps/.placeholder vendored
View File

View File

@ -1,177 +0,0 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ErlangMQTTBroker.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ErlangMQTTBroker.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/ErlangMQTTBroker"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ErlangMQTTBroker"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

View File

@ -1,11 +1,11 @@
http://emqttd.io/docs/v2/
or
http://docs.emqtt.com/
or
http://emqttd-docs.rtfd.org
or
http://emqttd.io/docs

View File

@ -1,242 +0,0 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
set I18NSPHINXOPTS=%SPHINXOPTS% source
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\ErlangMQTTBroker.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\ErlangMQTTBroker.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %BUILDDIR%/..
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %BUILDDIR%/..
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
:end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

View File

@ -1,45 +0,0 @@
.. _advanced:
========
Advanced
========
*EMQ* 2.0-rc.2 release supports `Local Subscription` and `Shared Subscription`.
------------------
Local Subscription
------------------
The *EMQ* broker will not create global routes for `Local Subscription`, and only dispatch MQTT messages on local node.
.. code-block:: shell
mosquitto_sub -t '$local/topic'
mosquitto_pub -t 'topic'
Usage: subscribe a topic with `$local/` prefix.
-------------------
Shared Subscription
-------------------
Shared Subscription supports Load balancing to distribute MQTT messages between multiple subscribers in the same group::
---------
| | --Msg1--> Subscriber1
Publisher--Msg1,Msg2,Msg3-->| EMQ | --Msg2--> Subscriber2
| | --Msg3--> Subscriber3
---------
Two ways to create a shared subscription:
+-----------------+-------------------------------------------+
| Prefix | Examples |
+-----------------+-------------------------------------------+
| $queue/ | mosquitto_sub -t '$queue/topic |
+-----------------+-------------------------------------------+
| $share/<group>/ | mosquitto_sub -t '$share/group/topic |
+-----------------+-------------------------------------------+

View File

@ -1,129 +0,0 @@
.. _bridge::
======
Bridge
======
---------------
EMQ Node Bridge
---------------
Two or more *EMQ* brokers could be bridged together. Bridges forward MQTT messages from one broker node to another::
--------- --------- ---------
Publisher --> | node1 | --Bridge Forward--> | node2 | --Bridge Forward--> | node3 | --> Subscriber
--------- --------- ---------
Configure Bridge
----------------
Suppose that we create two *EMQ* brokers on localhost:
+---------+---------------------+-----------+
| Name | Node | MQTT Port |
+---------+---------------------+-----------+
| emqttd1 | emqttd1@127.0.0.1 | 1883 |
+---------+---------------------+-----------+
| emqttd2 | emqttd2@127.0.0.1 | 2883 |
+---------+---------------------+-----------+
Create a bridge that forwards all the 'sensor/#' messages from emqttd1 to emqttd2.
1. Start Brokers
................
.. code-block:: bash
cd emqttd1/ && ./bin/emqttd start
cd emqttd2/ && ./bin/emqttd start
2. Create bridge: emqttd1--sensor/#-->emqttd2
.............................................
.. code-block:: bash
$ cd emqttd1 && ./bin/emqttd_ctl bridges start emqttd2@127.0.0.1 sensor/#
bridge is started.
$ ./bin/emqttd_ctl bridges list
bridge: emqttd1@127.0.0.1--sensor/#-->emqttd2@127.0.0.1
3. Test the bridge
...................
.. code-block:: bash
#emqttd2
mosquitto_sub -t sensor/# -p 2883 -d
#emqttd1
mosquitto_pub -t sensor/1/temperature -m "37.5" -d
4. Delete the bridge
.....................
.. code-block:: bash
./bin/emqttd_ctl bridges stop emqttd2@127.0.0.1 sensor/#
--------------
EMQ Bridge CLI
--------------
.. code-block:: bash
#query bridges
./bin/emqttd_ctl bridges list
#start bridge
./bin/emqttd_ctl bridges start <Node> <Topic>
#start bridge with options
./bin/emqttd_ctl bridges start <Node> <Topic> <Options>
#stop bridge
./bin/emqttd_ctl bridges stop <Node> <Topic>
-----------------
mosquitto Bridge
-----------------
Bridge mosquitto to emqttd broker::
------------- -----------------
Sensor ----> | mosquitto | --Bridge--> | |
------------- | EMQ |
------------- | Cluster |
Sensor ----> | mosquitto | --Bridge--> | |
------------- -----------------
mosquitto.conf
--------------
Suppose that we start an emqttd broker on localost:2883, and mosquitto on localhost:1883.
A bridge configured in mosquitto.conf::
connection emqttd
address 127.0.0.1:2883
topic sensor/# out 2
# Set the version of the MQTT protocol to use with for this bridge. Can be one
# of mqttv31 or mqttv311. Defaults to mqttv31.
bridge_protocol_version mqttv311
-----------
rsmb Bridge
-----------
Bridge RSMB to EMQ broker, same settings as mosquitto.
broker.cfg::
connection emqttd
addresses 127.0.0.1:2883
topic sensor/#

File diff suppressed because it is too large Load Diff

View File

@ -1,276 +0,0 @@
.. _cluster:
==========
Clustering
==========
----------------------
Distributed Erlang/OTP
----------------------
Erlang/OTP is a concurrent, fault-tolerant, distributed programming platform. A distributed Erlang/OTP system consists of a number of Erlang runtime systems called 'node'. Nodes connect to each other with TCP/IP sockets and communicate by Message Passing.
.. code::
--------- ---------
| Node1 | --------| Node2 |
--------- ---------
| \ / |
| \ / |
| / \ |
| / \ |
--------- ---------
| Node3 | --------| Node4 |
--------- ---------
Node
----
An erlang runtime system called 'node' is identified by a unique name like email addreass. Erlang nodes communicate with each other by the name.
Suppose we start four Erlang nodes on localhost:
.. code-block:: bash
erl -name node1@127.0.0.1
erl -name node2@127.0.0.1
erl -name node3@127.0.0.1
erl -name node4@127.0.0.1
connect all the nodes::
(node1@127.0.0.1)1> net_kernel:connect_node('node2@127.0.0.1').
true
(node1@127.0.0.1)2> net_kernel:connect_node('node3@127.0.0.1').
true
(node1@127.0.0.1)3> net_kernel:connect_node('node4@127.0.0.1').
true
(node1@127.0.0.1)4> nodes().
['node2@127.0.0.1','node3@127.0.0.1','node4@127.0.0.1']
epmd
----
epmd(Erlang Port Mapper Daemon) is a daemon service that is responsible for mapping node names to machine addresses(TCP sockets). The daemon is started automatically on every host where an Erlang node started.
.. code-block:: bash
(node1@127.0.0.1)6> net_adm:names().
{ok,[{"node1",62740},
{"node2",62746},
{"node3",62877},
{"node4",62895}]}
Cookie
------
Erlang nodes authenticate each other by a magic cookie when communicating. The cookie could be configured by::
1. $HOME/.erlang.cookie
2. erl -setcookie <Cookie>
.. NOTE:: Content of this chapter is from: http://erlang.org/doc/reference_manual/distributed.html
--------------
Cluster Design
--------------
The cluster architecture of emqttd broker is based on distrubuted Erlang/OTP and Mnesia database.
The cluster design could be summarized by the following two rules:
1. When a MQTT client SUBSCRIBE a Topic on a node, the node will tell all the other nodes in the cluster: I subscribed a Topic.
2. When a MQTT Client PUBLISH a message to a node, the node will lookup the Topic table and forward the message to nodes that subscribed the Topic.
Finally there will be a global route table(Topic -> Node) that replicated to all nodes in the cluster::
topic1 -> node1, node2
topic2 -> node3
topic3 -> node2, node4
Topic Trie and Route Table
--------------------------
Every node in the cluster will store a topic trie and route table in mnesia database.
Suppose that we create subscriptions:
+----------------+-------------+----------------------------+
| Client | Node | Topics |
+================+=============+============================+
| client1 | node1 | t/+/x, t/+/y |
+----------------+-------------+----------------------------+
| client2 | node2 | t/# |
+----------------+-------------+----------------------------+
| client3 | node3 | t/+/x, t/a |
+----------------+-------------+----------------------------+
Finally the topic trie and route table in the cluster::
--------------------------
| t |
| / \ |
| + # |
| / \ |
| x y |
--------------------------
| t/+/x -> node1, node3 |
| t/+/y -> node1 |
| t/# -> node2 |
| t/a -> node3 |
--------------------------
Message Route and Deliver
--------------------------
The brokers in the cluster route messages by topic trie and route table, deliver messages to MQTT clients by subscriptions. Subscriptions are mapping from topic to subscribers, are stored only in the local node, will not be replicated to other nodes.
Suppose client1 PUBLISH a message to the topic 't/a', the message Route and Deliver process::
title: Message Route and Deliver
client1->node1: Publish[t/a]
node1-->node2: Route[t/#]
node1-->node3: Route[t/a]
node2-->client2: Deliver[t/#]
node3-->client3: Deliver[t/a]
.. image:: _static/images/route.png
-------------
Cluster Setup
-------------
Suppose we deploy two nodes cluster on s1.emqtt.io, s2.emqtt.io:
+--------------------------+-----------------+---------------------+
| Node | Host(FQDN) | IP and Port |
+--------------------------+-----------------+---------------------+
| emqttd@s1.emqtt.io or | s1.emqtt.io | 192.168.0.10:1883 |
| emqttd@192.168.0.10 | | |
+--------------------------+-----------------+---------------------+
| emqttd@s2.emqtt.io or | s2.emqtt.io | 192.168.0.20:1883 |
| emqttd@192.168.0.20 | | |
+--------------------------+-----------------+---------------------+
.. WARNING:: The node name is Name@Host, where Host is IP address or the fully qualified host name.
emqttd@s1.emqtt.io setting
--------------------------
emqttd/etc/emq.conf::
node.name = emqttd@s1.emqtt.io
node.name = emqttd@192.168.0.10
.. WARNING:: The name cannot be changed after node joined the cluster.
emqttd@s2.emqtt.io setting
--------------------------
emqttd/etc/emq.conf::
node.name = emqttd@s2.emqtt.io
node.name = emqttd@192.168.0.20
Join the cluster
----------------
Start the two broker nodes, and 'cluster join ' on emqttd@s2.emqtt.io::
$ ./bin/emqttd_ctl cluster join emqttd@s1.emqtt.io
Join the cluster successfully.
Cluster status: [{running_nodes,['emqttd@s1.emqtt.io','emqttd@s2.emqtt.io']}]
Or 'cluster join' on emqttd@s1.emqtt.io::
$ ./bin/emqttd_ctl cluster join emqttd@s2.emqtt.io
Join the cluster successfully.
Cluster status: [{running_nodes,['emqttd@s1.emqtt.io','emqttd@s2.emqtt.io']}]
Query the cluster status::
$ ./bin/emqttd_ctl cluster status
Cluster status: [{running_nodes,['emqttd@s1.emqtt.io','emqttd@s2.emqtt.io']}]
Leave the cluster
-----------------
Two ways to leave the cluster:
1. leave: this node leaves the cluster
2. remove: remove other nodes from the cluster
emqttd@s2.emqtt.io node tries to leave the cluster::
$ ./bin/emqttd_ctl cluster leave
Or remove emqttd@s2.emqtt.io node from the cluster on emqttd@s1.emqtt.io::
$ ./bin/emqttd_ctl cluster remove emqttd@s2.emqtt.io
--------------------
Session across Nodes
--------------------
The persistent MQTT sessions (clean session = false) are across nodes in the cluster.
If a persistent MQTT client connected to node1 first, then disconnected and connects to node2, the MQTT connection and session will be located on different nodes::
node1
-----------
|-->| session |
| -----------
node2 |
-------------- |
client-->| connection |<--|
--------------
------------
The Firewall
------------
If there is a firewall between clustered nodes, the cluster requires to open 4369 port used by epmd daemon, and a port segment for nodes' communication.
Configure the port segment in releases/2.0/sys.config, for example:
.. code-block:: erlang
[{kernel, [
...
{inet_dist_listen_min, 20000},
{inet_dist_listen_max, 21000}
]},
...
------------------
Network Partitions
------------------
The emqttd 1.0 cluster requires reliable network to avoid network partitions. The cluster will not recover from a network partition automatically.
If a network partition occures, there will be critical logs in log/emqttd_error.log::
Mnesia inconsistent_database event: running_partitioned_network, emqttd@host
To recover from a network partition, you have to stop the nodes in a partition, clean the 'data/mneisa' of these nodes and reboot to join the cluster again.
-----------------------
Consistent Hash and DHT
-----------------------
Consistent Hash and DHT are popular in the design of NoSQL databases. Cluster of emqttd broker could support 10 million size of global routing table now. We could use the Consistent Hash or DHT to partition the routing table, and evolve the cluster to larger size.

View File

@ -1,9 +0,0 @@
.. _coap:
=============
CoAP Protocol
=============
.. todo:: CoAP Protocol Introduction...

View File

@ -1,785 +0,0 @@
.. _commands::
========
Commands
========
The './bin/emqttd_ctl' command line could be used to query and administrate the *EMQ* broker.
.. WARNING:: Cannot work on Windows
.. _command_status::
------
status
------
Show running status of the broker::
$ ./bin/emqttd_ctl status
Node 'emqttd@127.0.0.1' is started
emqttd 2.0 is running
.. _command_broker::
------
broker
------
Query basic information, statistics and metrics of the broker.
+----------------+-------------------------------------------------+
| broker | Show version, description, uptime of the broker |
+----------------+-------------------------------------------------+
| broker pubsub | Show status of the core pubsub process |
+----------------+-------------------------------------------------+
| broker stats | Show statistics of client, session, topic, |
| | subscription and route of the broker |
+----------------+-------------------------------------------------+
| broker metrics | Show metrics of MQTT bytes, packets, messages |
| | sent/received. |
+----------------+-------------------------------------------------+
Query version, description and uptime of the broker::
$ ./bin/emqttd_ctl broker
sysdescr : Erlang MQTT Broker
version : 0.15.0
uptime : 1 hours, 25 minutes, 24 seconds
datetime : 2016-01-16 13:17:32
broker stats
------------
Query statistics of MQTT Client, Session, Topic, Subscription and Route::
$ ./bin/emqttd_ctl broker stats
clients/count : 1
clients/max : 1
queues/count : 0
queues/max : 0
retained/count : 2
retained/max : 2
routes/count : 2
routes/reverse : 2
sessions/count : 0
sessions/max : 0
subscriptions/count : 1
subscriptions/max : 1
topics/count : 54
topics/max : 54
broker metrics
--------------
Query metrics of Bytes, MQTT Packets and Messages(sent/received)::
$ ./bin/emqttd_ctl broker metrics
bytes/received : 297
bytes/sent : 40
messages/dropped : 348
messages/qos0/received : 0
messages/qos0/sent : 0
messages/qos1/received : 0
messages/qos1/sent : 0
messages/qos2/received : 0
messages/qos2/sent : 0
messages/received : 0
messages/retained : 2
messages/sent : 0
packets/connack : 5
packets/connect : 5
packets/disconnect : 0
packets/pingreq : 0
packets/pingresp : 0
packets/puback/received : 0
packets/puback/sent : 0
packets/pubcomp/received: 0
packets/pubcomp/sent : 0
packets/publish/received: 0
packets/publish/sent : 0
packets/pubrec/received : 0
packets/pubrec/sent : 0
packets/pubrel/received : 0
packets/pubrel/sent : 0
packets/received : 9
packets/sent : 9
packets/suback : 4
packets/subscribe : 4
packets/unsuback : 0
packets/unsubscribe : 0
.. _command_cluster::
-------
cluster
-------
Cluster two or more emqttd brokers.
+-----------------------+--------------------------------+
| cluster join <Node> | Join the cluster |
+-----------------------+--------------------------------+
| cluster leave | Leave the cluster |
+-----------------------+--------------------------------+
| cluster remove <Node> | Remove a node from the cluster |
+-----------------------+--------------------------------+
| cluster status | Query cluster status and nodes |
+-----------------------+--------------------------------+
Suppose we create two emqttd nodes on localhost and cluster them:
+-----------+---------------------+-------------+
| Folder | Node | MQTT Port |
+-----------+---------------------+-------------+
| emqttd1 | emqttd1@127.0.0.1 | 1883 |
+-----------+---------------------+-------------+
| emqttd2 | emqttd2@127.0.0.1 | 2883 |
+-----------+---------------------+-------------+
Start emqttd1 node::
cd emqttd1 && ./bin/emqttd start
Start emqttd2 node::
cd emqttd2 && ./bin/emqttd start
Under emqttd2 folder::
$ ./bin/emqttd_ctl cluster join emqttd1@127.0.0.1
Join the cluster successfully.
Cluster status: [{running_nodes,['emqttd1@127.0.0.1','emqttd2@127.0.0.1']}]
Query cluster status::
$ ./bin/emqttd_ctl cluster status
Cluster status: [{running_nodes,['emqttd2@127.0.0.1','emqttd1@127.0.0.1']}]
Message Route between nodes::
# Subscribe topic 'x' on emqttd1 node
mosquitto_sub -t x -q 1 -p 1883
# Publish to topic 'x' on emqttd2 node
mosquitto_pub -t x -q 1 -p 2883 -m hello
emqttd2 leaves the cluster::
cd emqttd2 && ./bin/emqttd_ctl cluster leave
Or remove emqttd2 from the cluster on emqttd1 node::
cd emqttd1 && ./bin/emqttd_ctl cluster remove emqttd2@127.0.0.1
.. _command_clients::
-------
clients
-------
Query MQTT clients connected to the broker:
+-------------------------+----------------------------------+
| clients list | List all MQTT clients |
+-------------------------+----------------------------------+
| clients show <ClientId> | Show a MQTT Client |
+-------------------------+----------------------------------+
| clients kick <ClientId> | Kick out a MQTT client |
+-------------------------+----------------------------------+
clients lists
-------------
Query All MQTT clients connected to the broker::
$ ./bin/emqttd_ctl clients list
Client(mosqsub/43832-airlee.lo, clean_sess=true, username=test, peername=127.0.0.1:64896, connected_at=1452929113)
Client(mosqsub/44011-airlee.lo, clean_sess=true, username=test, peername=127.0.0.1:64961, connected_at=1452929275)
...
Properties of the Client:
+--------------+---------------------------------------------------+
| clean_sess | Clean Session Flag |
+--------------+---------------------------------------------------+
| username | Username of the client |
+--------------+---------------------------------------------------+
| peername | Peername of the TCP connection |
+--------------+---------------------------------------------------+
| connected_at | The timestamp when client connected to the broker |
+--------------+---------------------------------------------------+
clients show <ClientId>
-----------------------
Show a specific MQTT Client::
./bin/emqttd_ctl clients show "mosqsub/43832-airlee.lo"
Client(mosqsub/43832-airlee.lo, clean_sess=true, username=test, peername=127.0.0.1:64896, connected_at=1452929113)
clients kick <ClientId>
-----------------------
Kick out a MQTT Client::
./bin/emqttd_ctl clients kick "clientid"
.. _command_sessions::
--------
sessions
--------
Query all MQTT sessions. The broker will create a session for each MQTT client. Persistent Session if clean_session flag is true, transient session otherwise.
+--------------------------+-------------------------------+
| sessions list | List all Sessions |
+--------------------------+-------------------------------+
| sessions list persistent | Query all persistent Sessions |
+--------------------------+-------------------------------+
| sessions list transient | Query all transient Sessions |
+--------------------------+-------------------------------+
| sessions show <ClientId> | Show a session |
+--------------------------+-------------------------------+
sessions list
-------------
Query all sessions::
$ ./bin/emqttd_ctl sessions list
Session(clientid, clean_sess=false, max_inflight=100, inflight_queue=0, message_queue=0, message_dropped=0, awaiting_rel=0, awaiting_ack=0, awaiting_comp=0, created_at=1452935508)
Session(mosqsub/44101-airlee.lo, clean_sess=true, max_inflight=100, inflight_queue=0, message_queue=0, message_dropped=0, awaiting_rel=0, awaiting_ack=0, awaiting_comp=0, created_at=1452935401)
Properties of Session:
TODO:??
+-------------------+----------------------------------------------------------------+
| clean_sess | clean sess flag. false: persistent, true: transient |
+-------------------+----------------------------------------------------------------+
| max_inflight | Inflight window (Max number of messages delivering) |
+-------------------+----------------------------------------------------------------+
| inflight_queue | Inflight Queue Size |
+-------------------+----------------------------------------------------------------+
| message_queue | Message Queue Size |
+-------------------+----------------------------------------------------------------+
| message_dropped | Number of Messages Dropped for queue is full |
+-------------------+----------------------------------------------------------------+
| awaiting_rel | The number of QoS2 messages received and waiting for PUBREL |
+-------------------+----------------------------------------------------------------+
| awaiting_ack | The number of QoS1/2 messages delivered and waiting for PUBACK |
+-------------------+----------------------------------------------------------------+
| awaiting_comp | The number of QoS2 messages delivered and waiting for PUBCOMP |
+-------------------+----------------------------------------------------------------+
| created_at | Timestamp when the session is created |
+-------------------+----------------------------------------------------------------+
sessions list persistent
------------------------
Query all persistent sessions::
$ ./bin/emqttd_ctl sessions list persistent
Session(clientid, clean_sess=false, max_inflight=100, inflight_queue=0, message_queue=0, message_dropped=0, awaiting_rel=0, awaiting_ack=0, awaiting_comp=0, created_at=1452935508)
sessions list transient
-----------------------
Query all transient sessions::
$ ./bin/emqttd_ctl sessions list transient
Session(mosqsub/44101-airlee.lo, clean_sess=true, max_inflight=100, inflight_queue=0, message_queue=0, message_dropped=0, awaiting_rel=0, awaiting_ack=0, awaiting_comp=0, created_at=1452935401)
sessions show <ClientId>
------------------------
Show a session::
$ ./bin/emqttd_ctl sessions show clientid
Session(clientid, clean_sess=false, max_inflight=100, inflight_queue=0, message_queue=0, message_dropped=0, awaiting_rel=0, awaiting_ack=0, awaiting_comp=0, created_at=1452935508)
.. _command_routes::
------
routes
------
Show routing table of the broker.
routes list
-----------
List all routes::
$ ./bin/emqttd_ctl routes list
t2/# -> emqttd2@127.0.0.1
t/+/x -> emqttd2@127.0.0.1,emqttd@127.0.0.1
routes show <Topic>
-------------------
Show a route::
$ ./bin/emqttd_ctl routes show t/+/x
t/+/x -> emqttd2@127.0.0.1,emqttd@127.0.0.1
.. _command_topics::
------
topics
------
Query topic table of the broker.
topics list
-----------
Query all the topics::
$ ./bin/emqttd_ctl topics list
$SYS/brokers/emqttd@127.0.0.1/metrics/packets/subscribe: static
$SYS/brokers/emqttd@127.0.0.1/stats/subscriptions/max: static
$SYS/brokers/emqttd2@127.0.0.1/stats/subscriptions/count: static
...
topics show <Topic>
-------------------
Show a topic::
$ ./bin/emqttd_ctl topics show '$SYS/brokers'
$SYS/brokers: static
.. _command_subscriptions::
-------------
subscriptions
-------------
Query the subscription table of the broker:
+--------------------------------------------+--------------------------------------+
| subscriptions list | List all subscriptions |
+--------------------------------------------+--------------------------------------+
| subscriptions show <ClientId> | Show a subscription |
+--------------------------------------------+--------------------------------------+
subscriptions list
------------------
Query all subscriptions::
$ ./bin/emqttd_ctl subscriptions list
mosqsub/91042-airlee.lo -> t/y:1
mosqsub/90475-airlee.lo -> t/+/x:2
subscriptions list static
-------------------------
List all static subscriptions::
$ ./bin/emqttd_ctl subscriptions list static
clientid -> new_topic:1
subscriptions show <ClientId>
-----------------------------
Show the subscriptions of a MQTT client::
$ ./bin/emqttd_ctl subscriptions show clientid
clientid: [{<<"x">>,1},{<<"topic2">>,1},{<<"topic3">>,1}]
.. _command_plugins::
-------
plugins
-------
List, load or unload plugins of emqttd broker.
+---------------------------+-------------------------+
| plugins list | List all plugins |
+---------------------------+-------------------------+
| plugins load <Plugin> | Load Plugin |
+---------------------------+-------------------------+
| plugins unload <Plugin> | Unload (Plugin) |
+---------------------------+-------------------------+
plugins list
------------
List all plugins::
$ ./bin/emqttd_ctl plugins list
Plugin(emq_auth_clientid, version=2.0, description=Authentication with ClientId/Password, active=false)
Plugin(emq_auth_http, version=2.0, description=Authentication/ACL with HTTP API, active=false)
Plugin(emq_auth_ldap, version=2.0, description=Authentication/ACL with LDAP, active=false)
Plugin(emq_auth_mongo, version=2.0, description=Authentication/ACL with MongoDB, active=false)
Plugin(emq_auth_mysql, version=2.0, description=Authentication/ACL with MySQL, active=false)
Plugin(emq_auth_pgsql, version=2.0, description=Authentication/ACL with PostgreSQL, active=false)
Plugin(emq_auth_redis, version=2.0, description=Authentication/ACL with Redis, active=false)
Plugin(emq_auth_username, version=2.0, description=Authentication with Username/Password, active=false)
Plugin(emq_coap, version=0.2, description=CoAP Gateway, active=false)
Plugin(emq_dashboard, version=2.0, description=Dashboard, active=true)
Plugin(emq_mod_rewrite, version=2.0, description=EMQ Rewrite Module, active=false)
Plugin(emq_plugin_template, version=2.0, description=EMQ Plugin Template, active=false)
Plugin(emq_recon, version=2.0, description=Recon Plugin, active=false)
Plugin(emq_reloader, version=3.0, description=Reloader Plugin, active=false)
Plugin(emq_sn, version=0.2, description=MQTT-SN Gateway, active=false)
Plugin(emq_stomp, version=2.0, description=Stomp Protocol Plugin, active=false)
Properties of a plugin:
+-------------+--------------------------+
| version | Plugin Version |
+-------------+--------------------------+
| description | Plugin Description |
+-------------+--------------------------+
| active | If the plugin is Loaded |
+-------------+--------------------------+
Load <Plugin>
-------------
Load a Plugin::
$ ./bin/emqttd_ctl plugins load emq_recon
Start apps: [recon,emq_recon]
Plugin emq_recon loaded successfully.
Unload <Plugin>
---------------
Unload a Plugin::
$ ./bin/emqttd_ctl plugins unload emq_recon
Plugin emq_recon unloaded successfully.
.. _command_bridges::
-------
bridges
-------
Bridge two or more *EMQ* brokers::
--------- ---------
Publisher --> | node1 | --Bridge Forward--> | node2 | --> Subscriber
--------- ---------
commands for bridge:
+----------------------------------------+------------------------------+
| bridges list | List all bridges |
+----------------------------------------+------------------------------+
| bridges options | Show bridge options |
+----------------------------------------+------------------------------+
| bridges start <Node> <Topic> | Create a bridge |
+----------------------------------------+------------------------------+
| bridges start <Node> <Topic> <Options> | Create a bridge with options |
+----------------------------------------+------------------------------+
| bridges stop <Node> <Topic> | Delete a bridge |
+----------------------------------------+------------------------------+
Suppose we create a bridge between emqttd1 and emqttd2 on localhost:
+---------+---------------------+-----------+
| Name | Node | MQTT Port |
+---------+---------------------+-----------+
| emqttd1 | emqttd1@127.0.0.1 | 1883 |
+---------+---------------------+-----------+
| emqttd2 | emqttd2@127.0.0.1 | 2883 |
+---------+---------------------+-----------+
The bridge will forward all the the 'sensor/#' messages from emqttd1 to emqttd2::
$ ./bin/emqttd_ctl bridges start emqttd2@127.0.0.1 sensor/#
bridge is started.
$ ./bin/emqttd_ctl bridges list
bridge: emqttd1@127.0.0.1--sensor/#-->emqttd2@127.0.0.1
The the 'emqttd1--sensor/#-->emqttd2' bridge::
#emqttd2 node
mosquitto_sub -t sensor/# -p 2883 -d
#emqttd1节点上
mosquitto_pub -t sensor/1/temperature -m "37.5" -d
bridges options
---------------
Show bridge options::
$ ./bin/emqttd_ctl bridges options
Options:
qos = 0 | 1 | 2
prefix = string
suffix = string
queue = integer
Example:
qos=2,prefix=abc/,suffix=/yxz,queue=1000
bridges stop <Node> <Topic>
---------------------------
Delete the emqttd1--sensor/#-->emqttd2 bridge::
$ ./bin/emqttd_ctl bridges stop emqttd2@127.0.0.1 sensor/#
bridge is stopped.
.. _command_vm::
--
vm
--
Query the load, cpu, memory, processes and IO information of the Erlang VM.
+-------------+-----------------------------------+
| vm all | Query all |
+-------------+-----------------------------------+
| vm load | Query VM Load |
+-------------+-----------------------------------+
| vm memory | Query Memory Usage |
+-------------+-----------------------------------+
| vm process | Query Number of Erlang Processes |
+-------------+-----------------------------------+
| vm io | Query Max Fds of VM |
+-------------+-----------------------------------+
vm load
-------
Query load::
$ ./bin/emqttd_ctl vm load
cpu/load1 : 2.21
cpu/load5 : 2.60
cpu/load15 : 2.36
vm memory
---------
Query memory::
$ ./bin/emqttd_ctl vm memory
memory/total : 23967736
memory/processes : 3594216
memory/processes_used : 3593112
memory/system : 20373520
memory/atom : 512601
memory/atom_used : 491955
memory/binary : 51432
memory/code : 13401565
memory/ets : 1082848
vm process
----------
Query number of erlang processes::
$ ./bin/emqttd_ctl vm process
process/limit : 8192
process/count : 221
vm io
-----
Query max, active file descriptors of IO::
$ ./bin/emqttd_ctl vm io
io/max_fds : 2560
io/active_fds : 1
.. _command_trace::
-----
trace
-----
Trace MQTT packets, messages(sent/received) by ClientId or Topic.
+-----------------------------------+-----------------------------------+
| trace list | List all the traces |
+-----------------------------------+-----------------------------------+
| trace client <ClientId> <LogFile> | Trace a client |
+-----------------------------------+-----------------------------------+
| trace client <ClientId> off | Stop tracing the client |
+-----------------------------------+-----------------------------------+
| trace topic <Topic> <LogFile> | Trace a topic |
+-----------------------------------+-----------------------------------+
| trace topic <Topic> off | Stop tracing the topic |
+-----------------------------------+-----------------------------------+
trace client <ClientId> <LogFile>
---------------------------------
Start to trace a client::
$ ./bin/emqttd_ctl trace client clientid log/clientid_trace.log
trace client clientid successfully.
trace client <ClientId> off
---------------------------
Stop tracing the client::
$ ./bin/emqttd_ctl trace client clientid off
stop tracing client clientid successfully.
trace topic <Topic> <LogFile>
-----------------------------
Start to trace a topic::
$ ./bin/emqttd_ctl trace topic topic log/topic_trace.log
trace topic topic successfully.
trace topic <Topic> off
-----------------------
Stop tracing the topic::
$ ./bin/emqttd_ctl trace topic topic off
stop tracing topic topic successfully.
trace list
----------
List all traces::
$ ./bin/emqttd_ctl trace list
trace client clientid -> log/clientid_trace.log
trace topic topic -> log/topic_trace.log
.. _command_listeners::
---------
listeners
---------
Show all the TCP listeners::
$ ./bin/emqttd_ctl listeners
listener on mqtt:ws:8083
acceptors : 4
max_clients : 64
current_clients : 0
shutdown_count : []
listener on mqtt:ssl:8883
acceptors : 4
max_clients : 512
current_clients : 0
shutdown_count : []
listener on mqtt:tcp:1883
acceptors : 8
max_clients : 1024
current_clients : 0
shutdown_count : []
listener on dashboard:http:18083
acceptors : 2
max_clients : 512
current_clients : 0
shutdown_count : []
listener parameters:
+-----------------+--------------------------------------+
| acceptors | TCP Acceptor Pool |
+-----------------+--------------------------------------+
| max_clients | Max number of clients |
+-----------------+--------------------------------------+
| current_clients | Count of current clients |
+-----------------+--------------------------------------+
| shutdown_count | Statistics of client shutdown reason |
+----------------+---------------------------------------+
.. _command_mnesia::
------
mnesia
------
Show system_info of mnesia database.
------
admins
------
The 'admins' CLI is used to add/del admin account, which is registered by the dashboard plugin.
+------------------------------------+-----------------------------+
| admins add <Username> <Password> | Add admin account |
+------------------------------------+-----------------------------+
| admins passwd <Username> <Password>| Reset admin password |
+------------------------------------+-----------------------------+
| admins del <Username> | Delete admin account |
+------------------------------------+-----------------------------+
admins add
----------
Add admin account::
$ ./bin/emqttd_ctl admins add root public
ok
admins passwd
-------------
Reset password::
$ ./bin/emqttd_ctl admins passwd root private
ok
admins del
----------
Delete admin account::
$ ./bin/emqttd_ctl admins del root
ok

View File

@ -1,337 +0,0 @@
# -*- coding: utf-8 -*-
#
# Erlang MQTT Broker documentation build configuration file, created by
# sphinx-quickstart on Mon Feb 22 00:46:47 2016.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.coverage',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'EMQ 2.0 - Erlang MQTT Broker'
copyright = u'2016, Feng Lee'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '2.0'
# The full version, including alpha/beta/rc tags.
release = '2.0-rc.2'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'ErlangMQTTBrokerdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'ErlangMQTTBroker.tex', u'EMQ 2.0 Documentation',
u'Feng Lee', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'erlangmqttbroker', u'EMQ 2.0 Documentation',
[u'Feng Lee'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'ErlangMQTTBroker', u'Erlang MQTT Broker Documentation',
u'Feng Lee', 'ErlangMQTTBroker', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
# -- Options for Epub output ----------------------------------------------
# Bibliographic Dublin Core info.
epub_title = u'Erlang MQTT Broker'
epub_author = u'Feng Lee'
epub_publisher = u'Feng Lee'
epub_copyright = u'2016, Feng Lee'
# The basename for the epub file. It defaults to the project name.
#epub_basename = u'Erlang MQTT Broker'
# The HTML theme for the epub output. Since the default themes are not optimized
# for small screen space, using the same theme for HTML and epub output is
# usually not wise. This defaults to 'epub', a theme designed to save visual
# space.
#epub_theme = 'epub'
# The language of the text. It defaults to the language option
# or en if the language is not set.
#epub_language = ''
# The scheme of the identifier. Typical schemes are ISBN or URL.
#epub_scheme = ''
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#epub_identifier = ''
# A unique identification for the text.
#epub_uid = ''
# A tuple containing the cover image and cover page html template filenames.
#epub_cover = ()
# A sequence of (type, uri, title) tuples for the guide element of content.opf.
#epub_guide = ()
# HTML files that should be inserted before the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_pre_files = []
# HTML files shat should be inserted after the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_post_files = []
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
# The depth of the table of contents in toc.ncx.
#epub_tocdepth = 3
# Allow duplicate toc entries.
#epub_tocdup = True
# Choose between 'default' and 'includehidden'.
#epub_tocscope = 'default'
# Fix unsupported image types using the PIL.
#epub_fix_images = False
# Scale large images.
#epub_max_image_width = 0
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#epub_show_urls = 'inline'
# If false, no index is generated.
#epub_use_index = True
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'http://docs.python.org/': None}

View File

@ -1,548 +0,0 @@
.. _configuration:
=============
Configuration
=============
The main configuration files of the EMQ broker are under 'etc/' folder:
+----------------------+-----------------------------------+
| File | Description |
+----------------------+-----------------------------------+
| etc/emq.conf | EMQ 2.0 Configuration File |
+----------------------+-----------------------------------+
| etc/acl.conf | The default ACL File |
+----------------------+-----------------------------------+
| etc/plugins/\*.conf | Config Files of Plugins |
+----------------------+-----------------------------------+
---------------------
EMQ 2.0 Config Syntax
---------------------
The *EMQ* 2.0-rc.2 release integrated with `cuttlefish` library, and adopt a more user-friendly `k = v` syntax for configuration file:
.. code-block:: properties
## Node name
node.name = emqttd@127.0.0.1
...
## Max ClientId Length Allowed.
mqtt.max_clientid_len = 1024
...
The configuration files will be preprocessed and translated to Erlang `app.config` before the EMQ broker started::
---------------------- 2.0/schema/*.schema -------------------
| etc/emq.conf | ----------------- \|/ | data/app.config |
| + | --> mergeconf --> | data/app.conf | --> cuttlefish generate --> | |
| etc/plugins/*.conf | ----------------- | data/vm.args |
---------------------- -------------------
------------------------
OS Environment Variables
------------------------
+-------------------+----------------------------------------+
| EMQ_NODE_NAME | Erlang node name |
+-------------------+----------------------------------------+
| EMQ_NODE_COOKIE | Cookie for distributed erlang node |
+-------------------+----------------------------------------+
| EMQ_MAX_PORTS | Maximum number of opened sockets |
+-------------------+----------------------------------------+
| EMQ_TCP_PORT | MQTT TCP Listener Port, Default: 1883 |
+-------------------+----------------------------------------+
| EMQ_SSL_PORT | MQTT SSL Listener Port, Default: 8883 |
+-------------------+----------------------------------------+
| EMQ_HTTP_PORT | HTTP/WebSocket Port, Default: 8083 |
+-------------------+----------------------------------------+
| EMQ_HTTPS_PORT | HTTPS/WebSocket Port, Default: 8084 |
+-------------------+----------------------------------------+
-------------------
EMQ Node and Cookie
-------------------
The node name and cookie of *EMQ* should be configured when clustering:
.. code-block:: properties
## Node name
node.name = emqttd@127.0.0.1
## Cookie for distributed node
node.cookie = emq_dist_cookie
-------------------
Erlang VM Arguments
-------------------
Configure and Optimize Erlang VM:
.. code-block:: properties
## SMP support: enable, auto, disable
node.smp = auto
## Enable kernel poll
node.kernel_poll = on
## async thread pool
node.async_threads = 32
## Erlang Process Limit
node.process_limit = 256000
## Sets the maximum number of simultaneously existing ports for this system
node.max_ports = 65536
## Set the distribution buffer busy limit (dist_buf_busy_limit)
node.dist_buffer_size = 32MB
## Max ETS Tables.
## Note that mnesia and SSL will create temporary ets tables.
node.max_ets_tables = 256000
## Tweak GC to run more often
node.fullsweep_after = 1000
## Crash dump
node.crash_dump = log/crash.dump
## Distributed node ticktime
node.dist_net_ticktime = 60
## Distributed node port range
## node.dist_listen_min = 6000
## node.dist_listen_max = 6999
The two most important parameters for Erlang VM:
+--------------------------+---------------------------------------------------------------------------+
| node.process_limit | Max number of Erlang proccesses. A MQTT client consumes two proccesses. |
| | The value should be larger than max_clients * 2 |
+--------------------------+---------------------------------------------------------------------------+
| node.max_ports | Max number of Erlang Ports. A MQTT client consumes one port. |
| | The value should be larger than max_clients. |
+--------------------------+---------------------------------------------------------------------------+
------------------
Log Level and File
------------------
Console Log
-----------
.. code-block:: properties
## Console log. Enum: off, file, console, both
log.console = console
## Console log level. Enum: debug, info, notice, warning, error, critical, alert, emergency
log.console.level = error
## Console log file
## log.console.file = log/console.log
Error Log
---------
.. code-block:: properties
## Error log file
log.error.file = log/error.log
Crash Log
---------
.. code-block:: properties
## Enable the crash log. Enum: on, off
log.crash = on
log.crash.file = log/crash.log
------------------------
MQTT Protocol Parameters
------------------------
Maximum ClientId Length
-----------------------
.. code-block:: properties
## Max ClientId Length Allowed.
mqtt.max_clientid_len = 1024
Maximum Packet Size
-------------------
.. code-block:: properties
## Max Packet Size Allowed, 64K by default.
mqtt.max_packet_size = 64KB
MQTT Client Idle Timeout
------------------------
.. code-block:: properties
## Client Idle Timeout (Second)
mqtt.client_idle_timeout = 30
----------------------------
Allow Anonymous and ACL File
----------------------------
Allow Anonymous
---------------
.. code-block:: properties
## Allow Anonymous authentication
mqtt.allow_anonymous = true
Default ACL File
----------------
Enable the default ACL module:
.. code-block:: properties
## Default ACL File
mqtt.acl_file = etc/acl.conf
Define ACL rules in etc/acl.conf. The rules by default:
.. code-block:: erlang
%% Allow 'dashboard' to subscribe '$SYS/#'
{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.
%% Allow clients from localhost to subscribe any topics
{allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
%% Deny clients to subscribe '$SYS#' and '#'
{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.
%% Allow all by default
{allow, all}.
An ACL rule is an Erlang tuple. The Access control module of *EMQ* broker matches the rule one by one from top to bottom::
--------- --------- ---------
Client -> | Rule1 | --nomatch--> | Rule2 | --nomatch--> | Rule3 | --> Default
--------- --------- ---------
| | |
match match match
\|/ \|/ \|/
allow | deny allow | deny allow | deny
-----------------------
MQTT Session Parameters
-----------------------
.. code-block:: properties
## Max number of QoS 1 and 2 messages that can be “inflight” at one time.
## 0 means no limit
mqtt.session.max_inflight = 100
## Retry interval for redelivering QoS1/2 messages.
mqtt.session.retry_interval = 60
## Awaiting PUBREL Timeout
mqtt.session.await_rel_timeout = 20
## Max Packets that Awaiting PUBREL, 0 means no limit
mqtt.session.max_awaiting_rel = 0
## Statistics Collection Interval(seconds)
mqtt.session.collect_interval = 0
## Expired after 1 day:
## w - week
## d - day
## h - hour
## m - minute
## s - second
mqtt.session.expired_after = 1d
+------------------------------+----------------------------------------------------------+
| session.max_inflight | Max number of QoS1/2 messages that can be delivered in |
| | the same time |
+------------------------------+----------------------------------------------------------+
| session.retry_interval | Retry interval for unacked QoS1/2 messages. |
+------------------------------+----------------------------------------------------------+
| session.await_rel_timeout | Awaiting PUBREL Timeout |
+------------------------------+----------------------------------------------------------+
| session.max_awaiting_rel | Max number of Packets that Awaiting PUBREL |
+------------------------------+----------------------------------------------------------+
| session.collect_interval | Interval of Statistics Collection |
+------------------------------+----------------------------------------------------------+
| session.expired_after | Expired after (unit: minute) |
+------------------------------+----------------------------------------------------------+
------------------
MQTT Message Queue
------------------
The message queue of session stores:
1. Offline messages for persistent session.
2. Pending messages for inflight window is full
Queue parameters:
.. code-block:: properties
## Type: simple | priority
mqtt.queue.type = simple
## Topic Priority: 0~255, Default is 0
## mqtt.queue.priority = topic/1=10,topic/2=8
## Max queue length. Enqueued messages when persistent client disconnected,
## or inflight window is full.
mqtt.queue.max_length = infinity
## Low-water mark of queued messages
mqtt.queue.low_watermark = 20%
## High-water mark of queued messages
mqtt.queue.high_watermark = 60%
## Queue Qos0 messages?
mqtt.queue.qos0 = true
+----------------------+---------------------------------------------------+
| queue.type | Queue type: simple or priority |
+----------------------+---------------------------------------------------+
| queue.priority | Topic priority |
+----------------------+---------------------------------------------------+
| queue.max_length | Max Queue size, infinity means no limit |
+----------------------+---------------------------------------------------+
| queue.low_watermark | Low watermark |
+----------------------+---------------------------------------------------+
| queue.high_watermark | High watermark |
+----------------------+---------------------------------------------------+
| queue.qos0 | If Qos0 message queued? |
+----------------------+---------------------------------------------------+
----------------------
Sys Interval of Broker
----------------------
.. code-block:: properties
## System Interval of publishing broker $SYS Messages
mqtt.broker.sys_interval = 60
-----------------
PubSub Parameters
-----------------
.. code-block:: properties
## PubSub Pool Size. Default should be scheduler numbers.
mqtt.pubsub.pool_size = 8
mqtt.pubsub.by_clientid = true
##TODO: Subscribe Asynchronously
mqtt.pubsub.async = true
----------------------
MQTT Bridge Parameters
----------------------
.. code-block:: properties
## Bridge Queue Size
mqtt.bridge.max_queue_len = 10000
## Ping Interval of bridge node. Unit: Second
mqtt.bridge.ping_down_interval = 1
-------------------
Plugins' Etc Folder
-------------------
.. code-block:: properties
## Dir of plugins' config
mqtt.plugins.etc_dir = etc/plugins/
## File to store loaded plugin names.
mqtt.plugins.loaded_file = data/loaded_plugins
--------------
MQTT Listeners
--------------
Configure the TCP listeners for MQTT, MQTT(SSL), HTTP and HTTPS Protocols.
The most important parameter for MQTT listener is `max_clients`: max concurrent clients allowed.
The TCP Ports occupied by the *EMQ* broker by default:
+-----------+-----------------------------------+
| 1883 | MQTT Port |
+-----------+-----------------------------------+
| 8883 | MQTT(SSL) Port |
+-----------+-----------------------------------+
| 8083 | MQTT(WebSocket), HTTP API Port |
+-----------+-----------------------------------+
Listener Parameters:
+-----------------------------+-------------------------------------------------------+
| mqtt.listener.*.acceptors | TCP Acceptor Pool |
+-----------------------------+-------------------------------------------------------+
| mqtt.listener.*.max_clients | Maximum number of concurrent TCP connections allowed |
+-----------------------------+-------------------------------------------------------+
| mqtt.listener.*.rate_limit | Maximum number of concurrent TCP connections allowed |
+-----------------------------+-------------------------------------------------------+
TCP Listener - 1883
-------------------
.. code-block:: properties
## TCP Listener: 1883, 127.0.0.1:1883, ::1:1883
mqtt.listener.tcp = 1883
## Size of acceptor pool
mqtt.listener.tcp.acceptors = 8
## Maximum number of concurrent clients
mqtt.listener.tcp.max_clients = 1024
## Rate Limit. Format is 'burst,rate', Unit is KB/Sec
## mqtt.listener.tcp.rate_limit = 100,10
## TCP Socket Options
mqtt.listener.tcp.backlog = 1024
## mqtt.listener.tcp.recbuf = 4096
## mqtt.listener.tcp.sndbuf = 4096
## mqtt.listener.tcp.buffer = 4096
## mqtt.listener.tcp.nodelay = true
SSL Listener - 8883
-------------------
.. code-block:: properties
## SSL Listener: 8883, 127.0.0.1:8883, ::1:8883
mqtt.listener.ssl = 8883
## Size of acceptor pool
mqtt.listener.ssl.acceptors = 4
## Maximum number of concurrent clients
mqtt.listener.ssl.max_clients = 512
## Rate Limit. Format is 'burst,rate', Unit is KB/Sec
## mqtt.listener.ssl.rate_limit = 100,10
## Configuring SSL Options
mqtt.listener.ssl.handshake_timeout = 15
mqtt.listener.ssl.keyfile = etc/certs/key.pem
mqtt.listener.ssl.certfile = etc/certs/cert.pem
## mqtt.listener.ssl.cacertfile = etc/certs/cacert.pem
## mqtt.listener.ssl.verify = verify_peer
## mqtt.listener.ssl.fail_if_no_peer_cert = true
HTTP/WS Listener - 8083
-----------------------
.. code-block:: properties
## HTTP and WebSocket Listener
mqtt.listener.http = 8083
mqtt.listener.http.acceptors = 4
mqtt.listener.http.max_clients = 64
HTTPS/WSS Listener - 8084
-------------------------
.. code-block:: properties
## HTTP(SSL) Listener
mqtt.listener.https = 8084
mqtt.listener.https.acceptors = 4
mqtt.listener.https.max_clients = 64
mqtt.listener.https.handshake_timeout = 15
mqtt.listener.https.certfile = etc/certs/cert.pem
mqtt.listener.https.keyfile = etc/certs/key.pem
## mqtt.listener.https.cacertfile = etc/certs/cacert.pem
## mqtt.listener.https.verify = verify_peer
## mqtt.listener.https.fail_if_no_peer_cert = true
--------------
System Monitor
--------------
.. code-block:: properties
## Long GC, don't monitor in production mode for:
sysmon.long_gc = false
## Long Schedule(ms)
sysmon.long_schedule = 240
## 8M words. 32MB on 32-bit VM, 64MB on 64-bit VM.
sysmon.large_heap = 8MB
## Busy Port
sysmon.busy_port = false
## Busy Dist Port
sysmon.busy_dist_port = true
--------------------------
Plugin Configuration Files
--------------------------
+----------------------------------------+-----------------------------------+
| File | Description |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_auth_username.conf | Username/Password Auth Plugin |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_auth_clientid.conf | ClientId Auth Plugin |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_auth_http.conf | HTTP Auth/ACL Plugin Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_auth_mongo.conf | MongoDB Auth/ACL Plugin Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_auth_mysql.conf | MySQL Auth/ACL Plugin Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_auth_pgsql.conf | Postgre Auth/ACL Plugin Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_auth_redis.conf | Redis Auth/ACL Plugin Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_coap.conf | CoAP Protocol Plugin Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_mod_presence.conf | Presence Module Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_mod_retainer.conf | Retainer Module Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_mod_rewrite.config | Rewrite Module Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_mod_subscription.conf | Subscription Module Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_dashboard.conf | Dashboard Plugin Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_plugin_template.conf | Template Plugin Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_recon.conf | Recon Plugin Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_reloader.conf | Reloader Plugin Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_sn.conf | MQTT-SN Protocal Plugin Config |
+----------------------------------------+-----------------------------------+
| etc/plugins/emq_stomp.conf | Stomp Protocl Plugin Config |
+----------------------------------------+-----------------------------------+

View File

@ -1,532 +0,0 @@
.. _design:
======
Design
======
.. _design_architecture:
------------
Architecture
------------
The *EMQ* broker 1.0 is more like a network Switch or Router, not a traditional enterprise message queue. Compared to a network router that routes packets based on IP or MPLS label, the *EMQ* broker routes MQTT messages based on topic trie.
.. image:: _static/images/concept.png
The *EMQ* 2.0 seperated the Message Flow Plane and Monitor/Control Plane, the Architecture is something like::
Control Plane
--------------------
| |
FrontEnd -> | Flow Plane | -> BackEnd
| |
Session Router
---------------------
Monitor Plane
Design Philosophy
-----------------
1. Focus on handling millions of MQTT connections and routing MQTT messages between clustered nodes.
2. Embrace Erlang/OTP, The Soft-Realtime, Low-Latency, Concurrent and Fault-Tolerant Platform.
3. Layered Design: Connection, Session, PubSub and Router Layers.
4. Separate the Message Flow Plane and the Control/Management Plane.
5. Stream MQTT messages to various backends including MQ or databases.
System Layers
-------------
1. Connection Layer
Handle TCP and WebSocket connections, encode/decode MQTT packets.
2. Session Layer
Process MQTT PUBLISH/SUBSCRIBE Packets received from client, and deliver MQTT messages to client.
3. PubSub Layer
Dispatch MQTT messages to subscribers in a node.
4. Routing(Distributed) Layer
Route MQTT messages among clustered nodes.
----------------
Connection Layer
----------------
This layer is built on the `eSockd`_ library which is a general Non-blocking TCP/SSL Socket Server:
* Acceptor Pool and Asynchronous TCP Accept
* Parameterized Connection Module
* Max connections management
* Allow/Deny by peer address or CIDR
* Keepalive Support
* Rate Limit based on The Leaky Bucket Algorithm
* Fully Asynchronous TCP RECV/SEND
This layer is also responsible for encoding/decoding MQTT frames:
1. Parse MQTT frames received from client
2. Serialize MQTT frames sent to client
3. MQTT Connection Keepalive
Main erlang modules of this layer:
+------------------+--------------------------+
| Module | Description |
+==================+==========================+
| emqttd_client | TCP Client |
+------------------+--------------------------+
| emqttd_ws_client | WebSocket Client |
+------------------+--------------------------+
| emqttd_protocol | MQTT Protocol Handler |
+------------------+--------------------------+
| emqttd_parser | MQTT Frame Parser |
+------------------+--------------------------+
| emqttd_serializer| MQTT Frame Serializer |
+------------------+--------------------------+
-------------
Session Layer
-------------
The session layer processes MQTT packets received from client and delivers PUBLISH packets to client.
A MQTT session will store the subscriptions and inflight messages in memory:
1. The Clients subscriptions.
2. Inflight qos1/2 messages sent to the client but unacked, QoS 2 messages which
have been sent to the Client, but have not been completely acknowledged.
3. Inflight qos2 messages received from client and waiting for PUBREL. QoS 2
messages which have been received from the Client, but have not been
completely acknowledged.
4. All qos1, qos2 messages published to when client is disconnected.
MQueue and Inflight Window
--------------------------
Concept of Message Queue and Inflight Window::
|<----------------- Max Len ----------------->|
-----------------------------------------------
IN -> | Messages Queue | Inflight Window | -> Out
-----------------------------------------------
|<--- Win Size --->|
1. Inflight Window to store the messages delivered and await for PUBACK.
2. Enqueue messages when the inflight window is full.
3. If the queue is full, drop qos0 messages if store_qos0 is true, otherwise drop the oldest one.
The larger the inflight window size is, the higher the throughput is. The smaller the window size is, the more strict the message order is.
PacketId and MessageId
----------------------
The 16-bit PacketId is defined by MQTT Protocol Specification, used by client/server to PUBLISH/PUBACK packets. A GUID(128-bit globally unique Id) will be generated by the broker and assigned to a MQTT message.
Format of the globally unique message id::
--------------------------------------------------------
| Timestamp | NodeID + PID | Sequence |
|<------- 64bits ------->|<--- 48bits --->|<- 16bits ->|
--------------------------------------------------------
1. Timestamp: erlang:system_time if Erlang >= R18, otherwise os:timestamp
2. NodeId: encode node() to 2 bytes integer
3. Pid: encode pid to 4 bytes integer
4. Sequence: 2 bytes sequence in one process
The PacketId and MessageId in a End-to-End Message PubSub Sequence::
PktId <-- Session --> MsgId <-- Router --> MsgId <-- Session --> PktId
------------
PubSub Layer
------------
The PubSub layer maintains a subscription table and is responsible to dispatch MQTT messages to subscribers.
.. image:: _static/images/dispatch.png
MQTT messages will be dispatched to the subscriber's session, which finally delivers the messages to client.
-------------
Routing Layer
-------------
The routing(distributed) layer maintains and replicates the global Topic Trie and Routing Table. The topic tire is composed of wildcard topics created by subscribers. The Routing Table maps a topic to nodes in the cluster.
For example, if node1 subscribed 't/+/x' and 't/+/y', node2 subscribed 't/#' and node3 subscribed 't/a', there will be a topic trie and route table::
-------------------------
| t |
| / \ |
| + # |
| / \ |
| x y |
-------------------------
| t/+/x -> node1, node3 |
| t/+/y -> node1 |
| t/# -> node2 |
| t/a -> node3 |
-------------------------
The routing layer would route MQTT messages among clustered nodes by topic trie match and routing table lookup:
.. image:: _static/images/route.png
The routing design follows two rules:
1. A message only gets forwarded to other cluster nodes if a cluster node is interested in it. This reduces the network traffic tremendously, because it prevents nodes from forwarding unnecessary messages.
2. As soon as a client on a node subscribes to a topic it becomes known within the cluster. If one of the clients somewhere in the cluster is publishing to this topic, the message will be delivered to its subscriber no matter to which cluster node it is connected.
.. _design_auth_acl:
----------------------
Authentication and ACL
----------------------
The *EMQ* broker supports an extensible authentication/ACL mechanism, which is implemented by emqttd_access_control, emqttd_auth_mod and emqttd_acl_mod modules.
emqttd_access_control module provides two APIs that help register/unregister auth or ACL module:
.. code-block:: erlang
register_mod(auth | acl, atom(), list()) -> ok | {error, any()}.
register_mod(auth | acl, atom(), list(), non_neg_integer()) -> ok | {error, any()}.
Authentication Bahaviour
-------------------------
The emqttd_auth_mod defines an Erlang behaviour for authentication module:
.. code-block:: erlang
-module(emqttd_auth_mod).
-ifdef(use_specs).
-callback init(AuthOpts :: list()) -> {ok, State :: any()}.
-callback check(Client, Password, State) -> ok | ignore | {error, string()} when
Client :: mqtt_client(),
Password :: binary(),
State :: any().
-callback description() -> string().
-else.
-export([behaviour_info/1]).
behaviour_info(callbacks) ->
[{init, 1}, {check, 3}, {description, 0}];
behaviour_info(_Other) ->
undefined.
-endif.
The authentication modules implemented by plugins:
+-----------------------+--------------------------------+
| Plugin | Authentication |
+-----------------------+--------------------------------+
| emq_auth_username | Username and Password |
+-----------------------+--------------------------------+
| emq_auth_clientid | ClientID and Password |
+-----------------------+--------------------------------+
| emq_auth_ldap | LDAP |
+-----------------------+--------------------------------+
| emq_auth_http | HTTP API |
+-----------------------+--------------------------------+
| emq_auth_mysql | MySQL |
+-----------------------+--------------------------------+
| emq_auth_pgsql | PostgreSQL |
+-----------------------+--------------------------------+
| emq_auth_redis | Redis |
+-----------------------+--------------------------------+
| emq_auth_mongo | MongoDB |
+-----------------------+--------------------------------+
Authorization(ACL)
------------------
The emqttd_acl_mod defines an Erlang behavihour for ACL module:
.. code-block:: erlang
-module(emqttd_acl_mod).
-include("emqttd.hrl").
-ifdef(use_specs).
-callback init(AclOpts :: list()) -> {ok, State :: any()}.
-callback check_acl({Client, PubSub, Topic}, State :: any()) -> allow | deny | ignore when
Client :: mqtt_client(),
PubSub :: pubsub(),
Topic :: binary().
-callback reload_acl(State :: any()) -> ok | {error, any()}.
-callback description() -> string().
-else.
-export([behaviour_info/1]).
behaviour_info(callbacks) ->
[{init, 1}, {check_acl, 2}, {reload_acl, 1}, {description, 0}];
behaviour_info(_Other) ->
undefined.
-endif.
emqttd_acl_internal implements the default ACL based on etc/acl.conf file:
.. code-block:: erlang
%%%-----------------------------------------------------------------------------
%%%
%%% -type who() :: all | binary() |
%%% {ipaddr, esockd_access:cidr()} |
%%% {client, binary()} |
%%% {user, binary()}.
%%%
%%% -type access() :: subscribe | publish | pubsub.
%%%
%%% -type topic() :: binary().
%%%
%%% -type rule() :: {allow, all} |
%%% {allow, who(), access(), list(topic())} |
%%% {deny, all} |
%%% {deny, who(), access(), list(topic())}.
%%%
%%%-----------------------------------------------------------------------------
{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.
{allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.
{allow, all}.
.. _design_hook:
------------
Hooks Design
------------
The *EMQ* broker implements a simple but powerful hooks mechanism to help users develop plugin. The broker would run the hooks when a client is connected/disconnected, a topic is subscribed/unsubscribed or a MQTT message is published/delivered/acked.
Hooks defined by the *EMQ* 2.0 broker:
+------------------------+------------------------------------------------------+
| Hook | Description |
+========================+======================================================+
| client.connected | Run when client connected to the broker successfully |
+------------------------+------------------------------------------------------+
| client.subscribe | Run before client subscribes topics |
+------------------------+------------------------------------------------------+
| client.unsubscribe | Run when client unsubscribes topics |
+------------------------+------------------------------------------------------+
| session.subscribed | Run After client(session) subscribed a topic |
+------------------------+------------------------------------------------------+
| session.unsubscribed | Run After client(session) unsubscribed a topic |
+------------------------+------------------------------------------------------+
| message.publish | Run when a MQTT message is published |
+------------------------+------------------------------------------------------+
| message.delivered | Run when a MQTT message is delivered |
+------------------------+------------------------------------------------------+
| message.acked | Run when a MQTT message is acked |
+------------------------+------------------------------------------------------+
| client.disconnected | Run when client disconnected from broker |
+------------------------+------------------------------------------------------+
The *EMQ* broker uses the `Chain-of-responsibility_pattern`_ to implement hook mechanism. The callback functions registered to hook will be executed one by one::
-------- ok | {ok, NewAcc} -------- ok | {ok, NewAcc} --------
(Args, Acc) --> | Fun1 | -------------------> | Fun2 | -------------------> | Fun3 | --> {ok, Acc} | {stop, Acc}
-------- -------- --------
| | |
stop | {stop, NewAcc} stop | {stop, NewAcc} stop | {stop, NewAcc}
The callback function for a hook should return:
+-----------------+------------------------+
| Return | Description |
+=================+========================+
| ok | Continue |
+-----------------+------------------------+
| {ok, NewAcc} | Return Acc and Continue|
+-----------------+------------------------+
| stop | Break |
+-----------------+------------------------+
| {stop, NewAcc} | Return Acc and Break |
+-----------------+------------------------+
The input arguments for a callback function are depending on the types of hook. Clone the `emq_plugin_template`_ project to check the argument in detail.
Hook Implementation
-------------------
The hook APIs defined in emqttd module:
.. code-block:: erlang
-module(emqttd).
%% Hooks API
-export([hook/4, hook/3, unhook/2, run_hooks/3]).
hook(Hook :: atom(), Callback :: function(), InitArgs :: list(any())) -> ok | {error, any()}.
hook(Hook :: atom(), Callback :: function(), InitArgs :: list(any()), Priority :: integer()) -> ok | {error, any()}.
unhook(Hook :: atom(), Callback :: function()) -> ok | {error, any()}.
run_hooks(Hook :: atom(), Args :: list(any()), Acc :: any()) -> {ok | stop, any()}.
And implemented in emqttd_hook module:
.. code-block:: erlang
-module(emqttd_hook).
%% Hooks API
-export([add/3, add/4, delete/2, run/3, lookup/1]).
add(HookPoint :: atom(), Callback :: function(), InitArgs :: list(any())) -> ok.
add(HookPoint :: atom(), Callback :: function(), InitArgs :: list(any()), Priority :: integer()) -> ok.
delete(HookPoint :: atom(), Callback :: function()) -> ok.
run(HookPoint :: atom(), Args :: list(any()), Acc :: any()) -> any().
lookup(HookPoint :: atom()) -> [#callback{}].
Hook Usage
----------
The `emq_plugin_template`_ project provides the examples for hook usage:
.. code-block:: erlang
-module(emq_plugin_template).
-export([load/1, unload/0]).
-export([on_message_publish/2, on_message_delivered/3, on_message_acked/3]).
load(Env) ->
emqttd:hook('message.publish', fun ?MODULE:on_message_publish/2, [Env]),
emqttd:hook('message.delivered', fun ?MODULE:on_message_delivered/3, [Env]),
emqttd:hook('message.acked', fun ?MODULE:on_message_acked/3, [Env]).
on_message_publish(Message, _Env) ->
io:format("publish ~s~n", [emqttd_message:format(Message)]),
{ok, Message}.
on_message_delivered(ClientId, Message, _Env) ->
io:format("delivered to client ~s: ~s~n", [ClientId, emqttd_message:format(Message)]),
{ok, Message}.
on_message_acked(ClientId, Message, _Env) ->
io:format("client ~s acked: ~s~n", [ClientId, emqttd_message:format(Message)]),
{ok, Message}.
unload() ->
emqttd:unhook('message.publish', fun ?MODULE:on_message_publish/2),
emqttd:unhook('message.acked', fun ?MODULE:on_message_acked/3),
emqttd:unhook('message.delivered', fun ?MODULE:on_message_delivered/3).
.. _design_plugin:
-------------
Plugin Design
-------------
Plugin is a normal erlang application that can be started/stopped dynamically by a running *EMQ* broker.
emqttd_plugins Module
---------------------
The plugin mechanism is implemented by emqttd_plugins module:
.. code-block:: erlang
-module(emqttd_plugins).
-export([load/1, unload/1]).
%% @doc Load a Plugin
load(PluginName :: atom()) -> ok | {error, any()}.
%% @doc UnLoad a Plugin
unload(PluginName :: atom()) -> ok | {error, any()}.
Load a Plugin
-------------
Use './bin/emqttd_ctl' CLI to load/unload a plugin::
./bin/emqttd_ctl plugins load emqttd_plugin_redis
./bin/emqttd_ctl plugins unload emqttd_plugin_redis
Plugin Template
---------------
http://github.com/emqtt/emqttd_plugin_template
.. _eSockd: https://github.com/emqtt/esockd
.. _Chain-of-responsibility_pattern: https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern
.. _emq_plugin_template: https://github.com/emqtt/emq_plugin_template/blob/master/src/emq_plugin_template.erl
-----------------
Mnesia/ETS Tables
-----------------
+--------------------+--------+----------------------------------------+
| Table | Type | Description |
+====================+========+========================================+
| mqtt_trie | mnesia | Trie Table |
+--------------------+--------+----------------------------------------+
| mqtt_trie_node | mnesia | Trie Node Table |
+--------------------+--------+----------------------------------------+
| mqtt_route | mnesia | Global Route Table |
+--------------------+--------+----------------------------------------+
| mqtt_local_route | mnesia | Local Route Table |
+--------------------+--------+----------------------------------------+
| mqtt_pubsub | ets | PubSub Tab |
+--------------------+--------+----------------------------------------+
| mqtt_subscriber | ets | Subscriber Tab |
+--------------------+--------+----------------------------------------+
| mqtt_subscription | ets | Subscription Tab |
+--------------------+--------+----------------------------------------+
| mqtt_session | mnesia | Global Session Table |
+--------------------+--------+----------------------------------------+
| mqtt_local_session | ets | Local Session Table |
+--------------------+--------+----------------------------------------+
| mqtt_client | ets | Client Table |
+--------------------+--------+----------------------------------------+
| mqtt_retained | mnesia | Retained Message Table |
+--------------------+--------+----------------------------------------+

View File

@ -1,77 +0,0 @@
===
FAQ
===
##### Q1. Is port 4369 and another random port secure?
```
HI, when start emqttd , I found the port 4369 and another random port(63703) is open, are this security ?
Example:
tcp 0 0 0.0.0.0:4369 0.0.0.0:* LISTEN 13736/epmd
tcp 0 0 0.0.0.0:8083 0.0.0.0:* LISTEN 16745/beam.smp
tcp 0 0 0.0.0.0:8883 0.0.0.0:* LISTEN 16745/beam.smp
tcp 0 0 0.0.0.0:63703 0.0.0.0:* LISTEN 16745/beam.smp
tcp 0 0 0.0.0.0:1883 0.0.0.0:* LISTEN 16745/beam.smp
1883: mqtt no ssl
8883: mqtt with ssl
8083: websocket
```
4369 and some random ports are opened by erlang node for internal communication. Configure your firewall to allow 1883, 8883, 8083 ports to be accessed from outside for security.
Access control of emqttd broker has two layers:
eSockd TCP Acceptor, Ipaddress based Access Control, Example:
```
{access, [{deny, "192.168.1.1"},
{allow, "192.168.1.0/24"},
{deny, all}]}
```
MQTT Subscribe/Publish Access Control by etc/acl.config, Example:
```
{allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.
{allow, all}.
```
##### Q2. cannot compile emqttd under Chinese folder?
It seems that rebar cannot support Chinese folder name.
##### Q3. emqttd is ready for production ?
The core features are solid and scalable. A small full-time team with many contributors are developing this project. You could submit issues if any feature requests or bug reports.
##### Q4. Benchmark and performance issue
Wiki: https://github.com/emqtt/emqttd/wiki/One-Million-Connections
##### Q5. 'session' identified by clientIDwhen session expired what will happenAll queued messages will be deleted and subscribed topics will be deleted toowhen reconnected need redo subscription(#150)
When a client connected to broker with 'clean session' flag 0, a session identified by clientId will be created. The session will expire after 48 hours(configured in etc/emqttd.config) if no client connections bind with it, and all queued messages and subscriptions will be dropped.
##### Q6. "{max_queued_messages, 100}" in 0.8 release or "{queue, {max_length, 1000},..." means queue for one session or one topicIf it stands for sessionwhile one topic has lots of offline messages(100), the user's other topic offline messages will be flushed? (#150)
For session. Topic just dispatch messages to clients or sessions that matched the subscriptions. Will Flood.
##### Q7. About the retained message, how to config one topic only keep the latest retained message, the older retained messages will be auto deleted?(#150)
By default, the broker only keep the latest retained message of one topic.
##### Q8. When the persistent client with 'clean session' flag 0 is offline but not expired, will the broker put session's subscribed topic new messages to session's queue?(#150)
Yes
##### Q9. If max_length of queue is 100, when the session subscribed topic1 and topic2, what will happen when topic1 fill 70 messages, then topic2 fill 80 messages? After the reconnection, will the session lose first 50 message?(#150)
Lose the oldest 50 messages.

View File

@ -1,279 +0,0 @@
.. _getstarted:
===========
Get Started
===========
--------
Overview
--------
*EMQ* (Erlang MQTT Broker) is an open source MQTT broker written in Erlang/OTP. Erlang/OTP is a concurrent, fault-tolerant, soft-realtime and distributed programming platform. MQTT is an extremely lightweight publish/subscribe messaging protocol powering IoT, M2M and Mobile applications.
The *EMQ* project is aimed to implement a scalable, distributed, extensible open-source MQTT broker for IoT, M2M and Mobile applications that hope to handle millions of concurrent MQTT clients.
Highlights of the *EMQ* broker:
* Full MQTT V3.1/3.1.1 Protocol Specifications Support
* Easy to Install - Quick Install on Linux, FreeBSD, Mac and Windows
* Massively scalable - Scaling to 1 million connections on a single server
* Cluster and Bridge Support
* Easy to extend - Hooks and plugins to customize or extend the broker
* Pluggable Authentication - LDAP, MySQL, PostgreSQL, Redis Authentication Plugins
--------
Features
--------
* Full MQTT V3.1/V3.1.1 protocol specification support
* QoS0, QoS1, QoS2 Publish and Subscribe
* Session Management and Offline Messages
* Retained Message
* Last Will Message
* TCP/SSL Connection
* MQTT Over WebSocket(SSL)
* HTTP Publish API
* STOMP protocol
* MQTT-SN Protocol
* CoAP Protocol
* STOMP over SockJS
* $SYS/# Topics
* ClientID Authentication
* IpAddress Authentication
* Username and Password Authentication
* Access control based on IpAddress, ClientID, Username
* Authentication with LDAP, Redis, MySQL, PostgreSQL and HTTP API
* Cluster brokers on several servers
* Bridge brokers locally or remotely
* mosquitto, RSMB bridge
* Extensible architecture with Hooks, Modules and Plugins
* Passed eclipse paho interoperability tests
* Local subscription
* Shared subscription
-----------
Quick Start
-----------
Download and Install
--------------------
The *EMQ* broker is cross-platform, which could be deployed on Linux, FreeBSD, Mac, Windows and even Raspberry Pi.
Download binary package from: http://emqtt.io/downloads.
Installing on Mac, for example:
.. code-block:: bash
unzip emqttd-macosx-v2.0-rc.2-20161019.zip && cd emqttd
# Start emqttd
./bin/emqttd start
# Check Status
./bin/emqttd_ctl status
# Stop emqttd
./bin/emqttd stop
Installing from Source
----------------------
.. NOTE:: The *EMQ* broker requires Erlang R18+ to build since 1.1 release.
.. code-block:: bash
git clone https://github.com/emqtt/emqttd.git
cd emqttd && make && make dist
cd rel/emqttd && ./bin/emqttd console
-------------
Web Dashboard
-------------
A Web Dashboard will be loaded when the *EMQ* broker is started successfully.
The Dashboard helps check running status of the broker, monitor statistics and metrics of MQTT packets, query clients, sessions, topics and subscriptions.
+------------------+---------------------------+
| Default Address | http://localhost:18083 |
+------------------+---------------------------+
| Default User | admin |
+------------------+---------------------------+
| Default Password | public |
+------------------+---------------------------+
.. image:: ./_static/images/dashboard.png
-------
Plugins
-------
The *EMQ* broker could be extended by Plugins. A plugin is an Erlang application to extend the *EMQ* broker:
+-------------------------+--------------------------------------------+
| `emq_auth_clientid`_ | Authentication with ClientId |
+-------------------------+--------------------------------------------+
| `emq_auth_username`_ | Authentication with Username and Password |
+-------------------------+--------------------------------------------+
| `emq_plugin_template`_ | Plugin template and demo |
+-------------------------+--------------------------------------------+
| `emq_dashboard`_ | Web Dashboard |
+-------------------------+--------------------------------------------+
| `emq_auth_ldap`_ | LDAP Auth Plugin |
+-------------------------+--------------------------------------------+
| `emq_auth_http`_ | Authentication/ACL with HTTP API |
+-------------------------+--------------------------------------------+
| `emq_auth_mysql`_ | Authentication with MySQL |
+-------------------------+--------------------------------------------+
| `emq_auth_pgsql`_ | Authentication with PostgreSQL |
+-------------------------+--------------------------------------------+
| `emq_auth_redis`_ | Authentication with Redis |
+-------------------------+--------------------------------------------+
| `emq_mod_rewrite`_ | Topics rewrite like HTTP rewrite module |
+-------------------------+--------------------------------------------+
| `emq_mod_retainer`_ | Retainer Module |
+-------------------------+--------------------------------------------+
| `emq_mod_presence`_ | Presence Module |
+-------------------------+--------------------------------------------+
| `emq_mod_subscription`_ | Subscription Module |
+-------------------------+--------------------------------------------+
| `emq_mod_mongo`_ | Authentication with MongoDB |
+-------------------------+--------------------------------------------+
| `emq_sn`_ | MQTT-SN Protocol Plugin |
+-------------------------+--------------------------------------------+
| `emq_coap`_ | CoAP Protocol Plugin |
+-------------------------+--------------------------------------------+
| `emq_stomp`_ | STOMP Protocol Plugin |
+-------------------------+--------------------------------------------+
| `emq_sockjs`_ | SockJS(Stomp) Plugin |
+-------------------------+--------------------------------------------+
| `emq_recon`_ | Recon Plugin |
+-------------------------+--------------------------------------------+
| `emq_reloader`_ | Reloader Plugin |
+-------------------------+--------------------------------------------+
A plugin could be enabled by 'bin/emqttd_ctl plugins load' command.
For example, enable 'emq_auth_pgsql' plugin::
./bin/emqttd_ctl plugins load emq_auth_pgsql
-----------------------
One Million Connections
-----------------------
Latest release of the *EMQ* broker is scaling to 1.3 million MQTT connections on a 12 Core, 32G CentOS server.
.. NOTE::
The emqttd broker only allows 512 concurrent connections by default, for 'ulimit -n' limit is 1024 on most platform.
We need tune the OS Kernel, TCP Stack, Erlang VM and emqttd broker for one million connections benchmark.
Linux Kernel Parameters
-----------------------
.. code-block:: bash
# 2M:
sysctl -w fs.file-max=2097152
sysctl -w fs.nr_open=2097152
echo 2097152 > /proc/sys/fs/nr_open
# 1M:
ulimit -n 1048576
TCP Stack Parameters
--------------------
.. code-block:: bash
# backlog
sysctl -w net.core.somaxconn=65536
Erlang VM
---------
emqttd/etc/emq.conf:
.. code-block:: properties
## Erlang Process Limit
node.process_limit = 2097152
## Sets the maximum number of simultaneously existing ports for this system
node.max_ports = 1048576
Max Allowed Connections
-----------------------
emqttd/etc/emq.conf 'listeners':
.. code-block:: properties
## Size of acceptor pool
mqtt.listener.tcp.acceptors = 64
## Maximum number of concurrent clients
mqtt.listener.tcp.max_clients = 1000000
Test Client
-----------
.. code-block:: bash
sysctl -w net.ipv4.ip_local_port_range="500 65535"
echo 1000000 > /proc/sys/fs/nr_open
ulimit -n 100000
---------------------
MQTT Client Libraries
---------------------
GitHub: https://github.com/emqtt
+--------------------+----------------------+
| `emqttc`_ | Erlang MQTT Client |
+--------------------+----------------------+
| `emqtt_benchmark`_ | MQTT benchmark Tool |
+--------------------+----------------------+
| `CocoaMQTT`_ | Swift MQTT Client |
+--------------------+----------------------+
| `QMQTT`_ | QT MQTT Client |
+--------------------+----------------------+
Eclipse Paho: https://www.eclipse.org/paho/
MQTT.org: https://github.com/mqtt/mqtt.github.io/wiki/libraries
.. _emqttc: https://github.com/emqtt/emqttc
.. _emqtt_benchmark: https://github.com/emqtt/emqtt_benchmark
.. _CocoaMQTT: https://github.com/emqtt/CocoaMQTT
.. _QMQTT: https://github.com/emqtt/qmqtt
.. _emq_plugin_template: https://github.com/emqtt/emq_plugin_template
.. _emq_dashboard: https://github.com/emqtt/emq_dashboard
.. _emq_mod_rewrite: https://github.com/emqtt/emq_mod_rewrite
.. _emq_auth_clientid: https://github.com/emqtt/emq_auth_clientid
.. _emq_auth_username: https://github.com/emqtt/emq_auth_username
.. _emq_auth_ldap: https://github.com/emqtt/emq_auth_ldap
.. _emq_auth_http: https://github.com/emqtt/emq_auth_http
.. _emq_auth_mysql: https://github.com/emqtt/emq_plugin_mysql
.. _emq_auth_pgsql: https://github.com/emqtt/emq_plugin_pgsql
.. _emq_auth_redis: https://github.com/emqtt/emq_plugin_redis
.. _emq_auth_mongo: https://github.com/emqtt/emq_plugin_mongo
.. _emq_reloader: https://github.com/emqtt/emq_reloader
.. _emq_stomp: https://github.com/emqtt/emq_stomp
.. _emq_sockjs: https://github.com/emqtt/emq_sockjs
.. _emq_recon: https://github.com/emqtt/emq_recon
.. _emq_sn: https://github.com/emqtt/emq_sn
.. _emq_coap: https://github.com/emqtt/emq_coap
.. _emq_mod_retainer: https://github.com/emqtt/emq_mod_retainer
.. _emq_mod_presence: https://github.com/emqtt/emq_mod_presence
.. _emq_mod_subscription: https://github.com/emqtt/emq_mod_subscription

View File

@ -1,881 +0,0 @@
.. _guide:
==========
User Guide
==========
--------------
Authentication
--------------
The *EMQ* broker supports to authenticate MQTT clients with ClientID, Username/Password, IpAddress and even HTTP Cookies.
The authentication is provided by a list of plugins such as MySQL, PostgreSQL and Redis...
If we enable several authentication plugins at the same time, the authentication process::
---------------- ---------------- -------------
Client --> | Username | -ignore-> | ClientID | -ignore-> | Anonymous |
---------------- ---------------- -------------
| | |
\|/ \|/ \|/
allow | deny allow | deny allow | deny
The authentication plugins implemented by default:
+---------------------------+---------------------------+
| Plugin | Description |
+===========================+===========================+
| `emq_auth_clientid`_ | ClientId Auth Plugin |
+---------------------------+---------------------------+
| `emq_auth_username`_ | Username Auth Plugin |
+---------------------------+---------------------------+
| `emq_auth_ldap`_ | LDAP Auth Plugin |
+---------------------------+---------------------------+
| `emq_auth_http`_ | HTTP Auth/ACL Plugin |
+---------------------------+---------------------------+
| `emq_auth_mysql`_ | MySQL Auth/ACL Plugin |
+---------------------------+---------------------------+
| `emq_auth_pgsql`_ | Postgre Auth/ACL Plugin |
+---------------------------+---------------------------+
| `emq_auth_redis`_ | Redis Auth/ACL Plugin |
+---------------------------+---------------------------+
| `emq_auth_mongo`_ | MongoDB Auth/ACL Plugin |
+---------------------------+---------------------------+
---------------
Allow Anonymous
---------------
Configure etc/emq.conf to allow anonymous authentication:
.. code-block:: properties
## Allow Anonymous authentication
mqtt.allow_anonymous = true
Username/Password
-----------------
Authenticate MQTT client with Username/Password::
Configure default users in etc/plugins/emq_auth_username.conf:
.. code-block:: properties
auth.username.$name=$password
Enable `emq_auth_username`_ plugin:
.. code-block:: bash
./bin/emqttd_ctl plugins load emq_auth_username
Add user by './bin/emqttd_ctl users' command::
$ ./bin/emqttd_ctl users add <Username> <Password>
ClientId
--------
Authentication with MQTT ClientId.
Configure Client Ids in etc/plugins/emq_auth_clientid.conf:
.. code-block:: properties
auth.clientid.$id=$password
Enable `emq_auth_clientid`_ plugin:
.. code-block:: bash
./bin/emqttd_ctl plugins load emq_auth_clientid
LDAP
----
etc/plugins/emq_auth_ldap.conf:
.. code-block:: properties
auth.ldap.servers = 127.0.0.1
auth.ldap.port = 389
auth.ldap.timeout = 30
auth.ldap.user_dn = uid=%u,ou=People,dc=example,dc=com
auth.ldap.ssl = false
Enable LDAP plugin::
./bin/emqttd_ctl plugins load emq_auth_ldap
HTTP
----
etc/plugins/emq_auth_http.conf:
.. code-block:: properties
## Variables: %u = username, %c = clientid, %a = ipaddress, %P = password, %t = topic
auth.http.auth_req = http://127.0.0.1:8080/mqtt/auth
auth.http.auth_req.method = post
auth.http.auth_req.params = clientid=%c,username=%u,password=%P
auth.http.super_req = http://127.0.0.1:8080/mqtt/superuser
auth.http.super_req.method = post
auth.http.super_req.params = clientid=%c,username=%u
Enable HTTP Plugin::
./bin/emqttd_ctl plugins load emq_auth_http
MySQL
-----
Authenticate with MySQL database. Suppose that we create a mqtt_user table:
.. code-block:: sql
CREATE TABLE `mqtt_user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(100) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`salt` varchar(20) DEFAULT NULL,
`created` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `mqtt_username` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Configure the 'auth_query' and 'password_hash' in etc/plugins/emq_auth_mysql.conf:
.. code-block:: properties
## Mysql Server
auth.mysql.server = 127.0.0.1:3306
## Mysql Pool Size
auth.mysql.pool = 8
## Mysql Username
## auth.mysql.username =
## Mysql Password
## auth.mysql.password =
## Mysql Database
auth.mysql.database = mqtt
## Variables: %u = username, %c = clientid
## Authentication Query: select password only
auth.mysql.auth_query = select password from mqtt_user where username = '%u' limit 1
## Password hash: plain, md5, sha, sha256, pbkdf2
auth.mysql.password_hash = sha256
## %% Superuser Query
auth.mysql.super_query = select is_superuser from mqtt_user where username = '%u' limit 1
Enable MySQL plugin:
.. code-block:: bash
./bin/emqttd_ctl plugins load emq_plugin_mysql
PostgreSQL
----------
Authenticate with PostgreSQL database. Create a mqtt_user table:
.. code-block:: sql
CREATE TABLE mqtt_user (
id SERIAL primary key,
username character varying(100),
password character varying(100),
salt character varying(40)
);
Configure the 'auth_query' and 'password_hash' in etc/plugins/emq_auth_pgsql.conf:
.. code-block:: properties
## Postgre Server
auth.pgsql.server = 127.0.0.1:5432
auth.pgsql.pool = 8
auth.pgsql.username = root
#auth.pgsql.password =
auth.pgsql.database = mqtt
auth.pgsql.encoding = utf8
auth.pgsql.ssl = false
## Variables: %u = username, %c = clientid, %a = ipaddress
## Authentication Query: select password only
auth.pgsql.auth_query = select password from mqtt_user where username = '%u' limit 1
## Password hash: plain, md5, sha, sha256, pbkdf2
auth.pgsql.password_hash = sha256
## sha256 with salt prefix
## auth.pgsql.password_hash = salt sha256
## sha256 with salt suffix
## auth.pgsql.password_hash = sha256 salt
## Superuser Query
auth.pgsql.super_query = select is_superuser from mqtt_user where username = '%u' limit 1
Enable the plugin:
.. code-block:: bash
./bin/emqttd_ctl plugins load emq_plugin_pgsql
Redis
-----
Authenticate with Redis. MQTT users could be stored in redis HASH, the key is "mqtt_user:<Username>".
Configure 'auth_cmd' and 'password_hash' in etc/plugins/emq_auth_redis.conf:
.. code-block:: properties
## Redis Server
auth.redis.server = 127.0.0.1:6379
## Redis Pool Size
auth.redis.pool = 8
## Redis Database
auth.redis.database = 0
## Redis Password
## auth.redis.password =
## Variables: %u = username, %c = clientid
## Authentication Query Command
auth.redis.auth_cmd = HGET mqtt_user:%u password
## Password hash: plain, md5, sha, sha256, pbkdf2
auth.redis.password_hash = sha256
## Superuser Query Command
auth.redis.super_cmd = HGET mqtt_user:%u is_superuser
Enable the plugin:
.. code-block:: bash
./bin/emqttd_ctl plugins load emq_auth_redis
MongoDB
-------
Create a `mqtt_user` collection::
{
username: "user",
password: "password hash",
is_superuser: boolean (true, false),
created: "datetime"
}
Configure `super_query`, `auth_query` in etc/plugins/emq_auth_mongo.conf:
.. code-block:: properties
## Mongo Server
auth.mongo.server = 127.0.0.1:27017
## Mongo Pool Size
auth.mongo.pool = 8
## Mongo User
## auth.mongo.user =
## Mongo Password
## auth.mongo.password =
## Mongo Database
auth.mongo.database = mqtt
## auth_query
auth.mongo.auth_query.collection = mqtt_user
auth.mongo.auth_query.password_field = password
auth.mongo.auth_query.password_hash = sha256
auth.mongo.auth_query.selector = username=%u
## super_query
auth.mongo.super_query.collection = mqtt_user
auth.mongo.super_query.super_field = is_superuser
auth.mongo.super_query.selector = username=%u
Enable the plugin:
.. code-block:: bash
./bin/emqttd_ctl plugins load emq_auth_mongo
.. _acl:
---
ACL
---
The ACL of *EMQ* broker is responsbile for authorizing MQTT clients to publish/subscribe topics.
The ACL rules define::
Allow|Deny Who Publish|Subscribe Topics
Access Control Module of *EMQ* broker will match the rules one by one::
--------- --------- ---------
Client -> | Rule1 | --nomatch--> | Rule2 | --nomatch--> | Rule3 | --> Default
--------- --------- ---------
| | |
match match match
\|/ \|/ \|/
allow | deny allow | deny allow | deny
Internal
--------
The default ACL of *EMQ* broker is implemented by an 'internal' module.
Enable the 'internal' ACL module in etc/emq.conf:
.. code-block:: properties
## Default ACL File
mqtt.acl_file = etc/acl.conf
The ACL rules of 'internal' module are defined in 'etc/acl.conf' file:
.. code-block:: erlang
%% Allow 'dashboard' to subscribe '$SYS/#'
{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.
%% Allow clients from localhost to subscribe any topics
{allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
%% Deny clients to subscribe '$SYS#' and '#'
{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.
%% Allow all by default
{allow, all}.
HTTP API
--------
ACL by HTTP API: https://github.com/emqtt/emq_auth_http
Configure etc/plugins/emq_auth_http.conf and enable the plugin:
.. code-block:: properties
## 'access' parameter: sub = 1, pub = 2
auth.http.acl_req = http://127.0.0.1:8080/mqtt/acl
auth.http.acl_req.method = get
auth.http.acl_req.params = access=%A,username=%u,clientid=%c,ipaddr=%a,topic=%t
auth.http.acl_nomatch = deny
MySQL
-----
ACL with MySQL database. The `mqtt_acl` table and default data:
.. code-block:: sql
CREATE TABLE `mqtt_acl` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`allow` int(1) DEFAULT NULL COMMENT '0: deny, 1: allow',
`ipaddr` varchar(60) DEFAULT NULL COMMENT 'IpAddress',
`username` varchar(100) DEFAULT NULL COMMENT 'Username',
`clientid` varchar(100) DEFAULT NULL COMMENT 'ClientId',
`access` int(2) NOT NULL COMMENT '1: subscribe, 2: publish, 3: pubsub',
`topic` varchar(100) NOT NULL DEFAULT '' COMMENT 'Topic Filter',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO mqtt_acl (id, allow, ipaddr, username, clientid, access, topic)
VALUES
(1,1,NULL,'$all',NULL,2,'#'),
(2,0,NULL,'$all',NULL,1,'$SYS/#'),
(3,0,NULL,'$all',NULL,1,'eq #'),
(5,1,'127.0.0.1',NULL,NULL,2,'$SYS/#'),
(6,1,'127.0.0.1',NULL,NULL,2,'#'),
(7,1,NULL,'dashboard',NULL,1,'$SYS/#');
Configure 'acl-query' and 'acl_nomatch' in etc/plugins/emq_auth_mysql.conf:
.. code-block:: properties
## ACL Query Command
auth.mysql.acl_query = select allow, ipaddr, username, clientid, access, topic from mqtt_acl where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'
## ACL nomatch
auth.mysql.acl_nomatch = deny
PostgreSQL
----------
ACL with PostgreSQL database. The mqtt_acl table and default data:
.. code-block:: sql
CREATE TABLE mqtt_acl (
id SERIAL primary key,
allow integer,
ipaddr character varying(60),
username character varying(100),
clientid character varying(100),
access integer,
topic character varying(100)
);
INSERT INTO mqtt_acl (id, allow, ipaddr, username, clientid, access, topic)
VALUES
(1,1,NULL,'$all',NULL,2,'#'),
(2,0,NULL,'$all',NULL,1,'$SYS/#'),
(3,0,NULL,'$all',NULL,1,'eq #'),
(5,1,'127.0.0.1',NULL,NULL,2,'$SYS/#'),
(6,1,'127.0.0.1',NULL,NULL,2,'#'),
(7,1,NULL,'dashboard',NULL,1,'$SYS/#');
Configure 'acl_query' and 'acl_nomatch' in etc/plugins/emq_auth_pgsql.conf:
.. code-block:: properties
## ACL Query. Comment this query, the acl will be disabled.
auth.pgsql.acl_query = select allow, ipaddr, username, clientid, access, topic from mqtt_acl where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'
## If no rules matched, return...
auth.pgsql.acl_nomatch = deny
Redis
-----
ACL with Redis. The ACL rules are stored in a Redis HashSet::
HSET mqtt_acl:<username> topic1 1
HSET mqtt_acl:<username> topic2 2
HSET mqtt_acl:<username> topic3 3
Configure `acl_cmd` and `acl_nomatch` in etc/plugins/emq_auth_redis.conf:
.. code-block:: properties
## ACL Query Command
auth.redis.acl_cmd = HGETALL mqtt_acl:%u
## ACL nomatch
auth.redis.acl_nomatch = deny
MongoDB
-------
Store ACL Rules in a `mqtt_acl` collection:
.. code-block:: json
{
username: "username",
clientid: "clientid",
publish: ["topic1", "topic2", ...],
subscribe: ["subtop1", "subtop2", ...],
pubsub: ["topic/#", "topic1", ...]
}
For example, insert rules into `mqtt_acl` collection::
db.mqtt_acl.insert({username: "test", publish: ["t/1", "t/2"], subscribe: ["user/%u", "client/%c"]})
db.mqtt_acl.insert({username: "admin", pubsub: ["#"]})
Configure `acl_query` and `acl_nomatch` in etc/plugins/emq_auth_mongo.conf:
.. code-block:: properties
## acl_query
auth.mongo.acl_query.collection = mqtt_user
auth.mongo.acl_query.selector = username=%u
## acl_nomatch
auth.mongo.acl_nomatch = deny
----------------------
MQTT Publish/Subscribe
----------------------
MQTT is a an extremely lightweight publish/subscribe messaging protocol desgined for IoT, M2M and Mobile applications.
.. image:: _static/images/pubsub_concept.png
Install and start the *EMQ* broker, and then any MQTT client could connect to the broker, subscribe topics and publish messages.
MQTT Client Libraries: https://github.com/mqtt/mqtt.github.io/wiki/libraries
For example, we use mosquitto_sub/pub commands::
mosquitto_sub -t topic -q 2
mosquitto_pub -t topic -q 1 -m "Hello, MQTT!"
MQTT V3.1.1 Protocol Specification: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html
MQTT Listener of emqttd broker is configured in etc/emq.conf:
.. code-block:: erlang
.. code-block:: properties
## TCP Listener: 1883, 127.0.0.1:1883, ::1:1883
mqtt.listener.tcp = 1883
## Size of acceptor pool
mqtt.listener.tcp.acceptors = 8
## Maximum number of concurrent clients
mqtt.listener.tcp.max_clients = 1024
MQTT(SSL) Listener, Default Port is 8883:
.. code-block:: properties
## SSL Listener: 8883, 127.0.0.1:8883, ::1:8883
mqtt.listener.ssl = 8883
## Size of acceptor pool
mqtt.listener.ssl.acceptors = 4
## Maximum number of concurrent clients
mqtt.listener.ssl.max_clients = 512
----------------
HTTP Publish API
----------------
The *EMQ* broker provides a HTTP API to help application servers publish messages to MQTT clients.
HTTP API: POST http://host:8083/mqtt/publish
Web servers such as PHP, Java, Python, NodeJS and Ruby on Rails could use HTTP POST to publish MQTT messages to the broker::
curl -v --basic -u user:passwd -d "qos=1&retain=0&topic=/a/b/c&message=hello from http..." -k http://localhost:8083/mqtt/publish
Parameters of the HTTP API:
+---------+----------------+
| Name | Description |
+=========+================+
| client | clientid |
+---------+----------------+
| qos | QoS(0, 1, 2) |
+---------+----------------+
| retain | Retain(0, 1) |
+---------+----------------+
| topic | Topic |
+---------+----------------+
| message | Payload |
+---------+----------------+
.. NOTE:: The API uses HTTP Basic Authentication.
-------------------
MQTT Over WebSocket
-------------------
Web browsers could connect to the emqttd broker directly by MQTT Over WebSocket.
+-------------------------+----------------------------+
| WebSocket URI: | ws(s)://host:8083/mqtt |
+-------------------------+----------------------------+
| Sec-WebSocket-Protocol: | 'mqttv3.1' or 'mqttv3.1.1' |
+-------------------------+----------------------------+
The Dashboard plugin provides a test page for WebSocket::
http://127.0.0.1:18083/websocket.html
Listener of WebSocket and HTTP Publish API is configured in etc/emqttd.config:
.. code-block:: properties
## HTTP and WebSocket Listener
mqtt.listener.http = 8083
mqtt.listener.http.acceptors = 4
mqtt.listener.http.max_clients = 64
-----------
$SYS Topics
-----------
The *EMQ* broker periodically publishes internal status, MQTT statistics, metrics and client online/offline status to $SYS/# topics.
For the *EMQ* broker could be clustered, the $SYS topic path is started with::
$SYS/brokers/${node}/
'${node}' is the erlang node name of emqttd broker. For example::
$SYS/brokers/emqttd@127.0.0.1/version
$SYS/brokers/emqttd@host2/uptime
.. NOTE:: The broker only allows clients from localhost to subscribe $SYS topics by default.
Sys Interval of publishing $SYS messages, could be configured in etc/emqttd.config::
{broker, [
%% System interval of publishing broker $SYS messages
{sys_interval, 60},
Broker Version, Uptime and Description
---------------------------------------
+--------------------------------+-----------------------+
| Topic | Description |
+================================+=======================+
| $SYS/brokers | Broker nodes |
+--------------------------------+-----------------------+
| $SYS/brokers/${node}/version | Broker Version |
+--------------------------------+-----------------------+
| $SYS/brokers/${node}/uptime | Broker Uptime |
+--------------------------------+-----------------------+
| $SYS/brokers/${node}/datetime | Broker DateTime |
+--------------------------------+-----------------------+
| $SYS/brokers/${node}/sysdescr | Broker Description |
+--------------------------------+-----------------------+
Online/Offline Status of MQTT Client
------------------------------------
The topic path started with: $SYS/brokers/${node}/clients/
+--------------------------+--------------------------------------------+------------------------------------+
| Topic | Payload(JSON) | Description |
+==========================+============================================+====================================+
| ${clientid}/connected | {ipaddress: "127.0.0.1", username: "test", | Publish when a client connected |
| | session: false, version: 3, connack: 0, | |
| | ts: 1432648482} | |
+--------------------------+--------------------------------------------+------------------------------------+
| ${clientid}/disconnected | {reason: "keepalive_timeout", | Publish when a client disconnected |
| | ts: 1432749431} | |
+--------------------------+--------------------------------------------+------------------------------------+
Properties of 'connected' Payload::
ipaddress: "127.0.0.1",
username: "test",
session: false,
protocol: 3,
connack: 0,
ts: 1432648482
Properties of 'disconnected' Payload::
reason: normal,
ts: 1432648486
Broker Statistics
-----------------
Topic path started with: $SYS/brokers/${node}/stats/
Clients
.......
+---------------------+---------------------------------------------+
| Topic | Description |
+---------------------+---------------------------------------------+
| clients/count | Count of current connected clients |
+---------------------+---------------------------------------------+
| clients/max | Max number of cocurrent connected clients |
+---------------------+---------------------------------------------+
Sessions
........
+---------------------+---------------------------------------------+
| Topic | Description |
+---------------------+---------------------------------------------+
| sessions/count | Count of current sessions |
+---------------------+---------------------------------------------+
| sessions/max | Max number of sessions |
+---------------------+---------------------------------------------+
Subscriptions
.............
+---------------------+---------------------------------------------+
| Topic | Description |
+---------------------+---------------------------------------------+
| subscriptions/count | Count of current subscriptions |
+---------------------+---------------------------------------------+
| subscriptions/max | Max number of subscriptions |
+---------------------+---------------------------------------------+
Topics
......
+---------------------+---------------------------------------------+
| Topic | Description |
+---------------------+---------------------------------------------+
| topics/count | Count of current topics |
+---------------------+---------------------------------------------+
| topics/max | Max number of topics |
+---------------------+---------------------------------------------+
Broker Metrics
--------------
Topic path started with: $SYS/brokers/${node}/metrics/
Bytes Sent/Received
...................
+---------------------+---------------------------------------------+
| Topic | Description |
+---------------------+---------------------------------------------+
| bytes/received | MQTT Bytes Received since broker started |
+---------------------+---------------------------------------------+
| bytes/sent | MQTT Bytes Sent since the broker started |
+---------------------+---------------------------------------------+
Packets Sent/Received
.....................
+--------------------------+---------------------------------------------+
| Topic | Description |
+--------------------------+---------------------------------------------+
| packets/received | MQTT Packets received |
+--------------------------+---------------------------------------------+
| packets/sent | MQTT Packets sent |
+--------------------------+---------------------------------------------+
| packets/connect | MQTT CONNECT Packet received |
+--------------------------+---------------------------------------------+
| packets/connack | MQTT CONNACK Packet sent |
+--------------------------+---------------------------------------------+
| packets/publish/received | MQTT PUBLISH packets received |
+--------------------------+---------------------------------------------+
| packets/publish/sent | MQTT PUBLISH packets sent |
+--------------------------+---------------------------------------------+
| packets/subscribe | MQTT SUBSCRIBE Packets received |
+--------------------------+---------------------------------------------+
| packets/suback | MQTT SUBACK packets sent |
+--------------------------+---------------------------------------------+
| packets/unsubscribe | MQTT UNSUBSCRIBE Packets received |
+--------------------------+---------------------------------------------+
| packets/unsuback | MQTT UNSUBACK Packets sent |
+--------------------------+---------------------------------------------+
| packets/pingreq | MQTT PINGREQ packets received |
+--------------------------+---------------------------------------------+
| packets/pingresp | MQTT PINGRESP Packets sent |
+--------------------------+---------------------------------------------+
| packets/disconnect | MQTT DISCONNECT Packets received |
+--------------------------+---------------------------------------------+
Messages Sent/Received
......................
+--------------------------+---------------------------------------------+
| Topic | Description |
+--------------------------+---------------------------------------------+
| messages/received | Messages Received |
+--------------------------+---------------------------------------------+
| messages/sent | Messages Sent |
+--------------------------+---------------------------------------------+
| messages/retained | Messages Retained |
+--------------------------+---------------------------------------------+
| messages/stored | TODO: Messages Stored |
+--------------------------+---------------------------------------------+
| messages/dropped | Messages Dropped |
+--------------------------+---------------------------------------------+
Broker Alarms
-------------
Topic path started with: $SYS/brokers/${node}/alarms/
+------------------+------------------+
| Topic | Description |
+------------------+------------------+
| ${alarmId}/alert | New Alarm |
+------------------+------------------+
| ${alarmId}/clear | Clear Alarm |
+------------------+------------------+
Broker Sysmon
-------------
Topic path started with: '$SYS/brokers/${node}/sysmon/'
+------------------+--------------------+
| Topic | Description |
+------------------+--------------------+
| long_gc | Long GC Warning |
+------------------+--------------------+
| long_schedule | Long Schedule |
+------------------+--------------------+
| large_heap | Large Heap Warning |
+------------------+--------------------+
| busy_port | Busy Port Warning |
+------------------+--------------------+
| busy_dist_port | Busy Dist Port |
+------------------+--------------------+
-----
Trace
-----
The emqttd broker supports to trace MQTT packets received/sent from/to a client, or trace MQTT messages published to a topic.
Trace a client::
./bin/emqttd_ctl trace client "clientid" "trace_clientid.log"
Trace a topic::
./bin/emqttd_ctl trace topic "topic" "trace_topic.log"
Lookup Traces::
./bin/emqttd_ctl trace list
Stop a Trace::
./bin/emqttd_ctl trace client "clientid" off
./bin/emqttd_ctl trace topic "topic" off
.. _emq_auth_clientid: https://github.com/emqtt/emq_auth_clientid
.. _emq_auth_username: https://github.com/emqtt/emq_auth_username
.. _emq_auth_ldap: https://github.com/emqtt/emq_auth_ldap
.. _emq_auth_http: https://github.com/emqtt/emq_auth_http
.. _emq_auth_mysql: https://github.com/emqtt/emq_plugin_mysql
.. _emq_auth_pgsql: https://github.com/emqtt/emq_plugin_pgsql
.. _emq_auth_redis: https://github.com/emqtt/emq_plugin_redis
.. _emq_auth_mongo: https://github.com/emqtt/emq_plugin_mongo

View File

@ -1,64 +0,0 @@
.. Erlang MQTT Broker documentation master file, created by
sphinx-quickstart on Mon Feb 22 00:46:47 2016.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
==========================
*EMQ* - Erlang MQTT Broker
==========================
*EMQ* (Erlang MQTT Broker) is a massively scalable and clusterable MQTT V3.1/V3.1.1 broker written in Erlang/OTP.
.. NOTE:: Adopt a shortened project name since 2.0 release: EMQ
*EMQ* is fully open source and licensed under the Apache Version 2.0. emqttd implements both MQTT V3.1 and V3.1.1 protocol specifications, and supports WebSocket, STOMP, SockJS, CoAP and MQTT-SN at the same time.
Latest release of the *EMQ* broker is scaling to 1.3 million MQTT connections on a 12 Core, 32G CentOS server.
.. image:: ./_static/images/emqtt.png
The *EMQ* project provides a scalable, enterprise grade, extensible open-source MQTT broker for IoT, M2M, Smart Hardware, Mobile Messaging and HTML5 Web Messaging Applications.
Sensors, Mobiles, Web Browsers and Application Servers could be connected by *EMQ* brokers with asynchronous PUB/SUB MQTT messages.
+---------------+-----------------------------------------+
| Homepage: | http://emqtt.io |
+---------------+-----------------------------------------+
| Downloads: | http://emqtt.io/downloads |
+---------------+-----------------------------------------+
| GitHub: | https://github.com/emqtt |
+---------------+-----------------------------------------+
| Twitter: | @emqtt |
+---------------+-----------------------------------------+
| Forum: | https://groups.google.com/d/forum/emqtt |
+---------------+-----------------------------------------+
| Mailing List: | emqtt@googlegroups.com |
+---------------+-----------------------------------------+
| Author: | Feng Lee <feng@emqtt.io> |
+---------------+-----------------------------------------+
Contents:
.. toctree::
:maxdepth: 2
getstarted
install
config
cluster
bridge
guide
advanced
design
commands
plugins
tune
changes
upgrade
-------
License
-------
Apache License Version 2.0

View File

@ -1,386 +0,0 @@
.. _install:
============
Installation
============
The *EMQ* broker is cross-platform, which could be deployed on Linux, FreeBSD, Mac, Windows and even Raspberry Pi.
.. NOTE::
Linux, FreeBSD Recommended.
.. _install_download:
-----------------
Download Packages
-----------------
Download binary packages from: http://emqtt.io/downloads
+-----------+------------------------------------------+
| Debian | http://emqtt.io/downloads/latest/debian |
+-----------+------------------------------------------+
| Ubuntu | http://emqtt.io/downloads/latest/ubuntu |
+-----------+------------------------------------------+
| CentOS | http://emqtt.io/downloads/latest/centos |
+-----------+------------------------------------------+
| FreeBSD | http://emqtt.io/downloads/latest/freebsd |
+-----------+------------------------------------------+
| Mac OS X | http://emqtt.io/downloads/latest/macosx |
+-----------+------------------------------------------+
| Windows | http://emqtt.io/downloads/latest/windows |
+-----------+------------------------------------------+
| Docker | http://emqtt.com/downloads/latest/docker |
+-----------+------------------------------------------+
The package name consists of platform, version and release time.
For example: emqttd-centos64-v2.0-rc.2-20161019.zip
.. _install_on_linux:
-------------------
Installing on Linux
-------------------
Download CentOS Package from: http://emqtt.io/downloads/latest/centos, and then unzip:
.. code-block:: bash
unzip emqttd-centos64-v2.0-rc.2-20161019.zip
Start the broker in console mode:
.. code-block:: bash
cd emqttd && ./bin/emqttd console
If the broker is started successfully, console will print:
.. code-block:: bash
starting emqttd on node 'emqttd@127.0.0.1'
emqttd ctl is starting...[done]
emqttd trace is starting...[done]
emqttd pubsub is starting...[done]
emqttd stats is starting...[done]
emqttd metrics is starting...[done]
emqttd retainer is starting...[done]
emqttd pooler is starting...[done]
emqttd client manager is starting...[done]
emqttd session manager is starting...[done]
emqttd session supervisor is starting...[done]
emqttd broker is starting...[done]
emqttd alarm is starting...[done]
emqttd mod supervisor is starting...[done]
emqttd bridge supervisor is starting...[done]
emqttd access control is starting...[done]
emqttd system monitor is starting...[done]
http listen on 0.0.0.0:18083 with 4 acceptors.
mqtt listen on 0.0.0.0:1883 with 16 acceptors.
mqtts listen on 0.0.0.0:8883 with 4 acceptors.
http listen on 0.0.0.0:8083 with 4 acceptors.
Erlang MQTT Broker 2.0 is running now
Eshell V6.4 (abort with ^G)
(emqttd@127.0.0.1)1>
CTRL+C to close the console and stop the broker.
Start the broker in daemon mode:
.. code-block:: bash
./bin/emqttd start
Check the running status of the broker:
.. code-block:: bash
$ ./bin/emqttd_ctl status
Node 'emqttd@127.0.0.1' is started
emqttd 2.0 is running
Or check the status by URL::
http://localhost:8083/status
Stop the broker::
./bin/emqttd stop
.. _install_on_freebsd:
---------------------
Installing on FreeBSD
---------------------
Download FreeBSD Package from: http://emqtt.io/downloads/latest/freebsd
The installing process is same to Linux.
.. _install_on_mac:
----------------------
Installing on Mac OS X
----------------------
We could install the broker on Mac OS X to develop and debug MQTT applications.
Download Mac Package from: http://emqtt.io/downloads/latest/macosx
Configure log level in `etc/emq.conf`, all MQTT messages recevied/sent will be printed on console:
.. code-block::
## Console log. Enum: off, file, console, both
log.console = both
## Console log level. Enum: debug, info, notice, warning, error, critical, alert, emergency
log.console.level = debug
## Console log file
log.console.file = log/console.log
The install and boot process on Mac are same to Linux.
.. _install_on_windows:
---------------------
Installing on Windows
---------------------
Download Package from: http://emqtt.io/downloads/latest/windows.
Unzip the package to install folder. Open the command line window and 'cd' to the folder.
Start the broker in console mode::
.\bin\emqttd console
If the broker started successfully, a Erlang console window will popup.
Close the console window and stop the emqttd broker. Prepare to register emqttd as window service.
Install emqttd serivce::
.\bin\emqttd install
Start emqttd serivce::
.\bin\emqttd start
Stop emqttd serivce::
.\bin\emqttd stop
Uninstall emqttd service::
.\bin\emqttd uninstall
.. WARNING:: './bin/emqttd_ctl' command line cannot work on Windows.
.. _install_via_docker_image:
------------------------
Install via Docker Image
------------------------
Download *EMQ* 2.0 Docker Image:
http://emqtt.com/downloads/latest/docker
unzip emqttd-docker image::
unzip emqttd-docker-v2.0.zip
Load Docker Image::
docker load < emqttd-docker-v2.0
Run the Container::
docker run -itd --net='host' --name emq20 emqttd-docker-v2.0
Stop the broker::
docker stop emq20
Start the broker::
docker start emq20
Enter the running container::
docker exec -it emq20 /bin/bash
.. _build_from_source:
----------------------
Installing From Source
----------------------
The *EMQ* broker requires Erlang/OTP R18+ and git client to build:
Install Erlang: http://www.erlang.org/
Install Git Client: http://www.git-scm.com/
Could use apt-get on Ubuntu, yum on CentOS/RedHat and brew on Mac to install Erlang and Git.
When all dependencies are ready, clone the emqttd project from github.com and build:
.. code-block:: bash
git clone https://github.com/emqtt/emqttd-relx.git
cd emqttd-relx && make
cd _rel/emqttd && ./bin/emqttd console
The binary package output in folder::
_rel/emqttd
.. _tcp_ports:
--------------
TCP Ports Used
--------------
+-----------+-----------------------------------+
| 1883 | MQTT Port |
+-----------+-----------------------------------+
| 8883 | MQTT/SSL Port |
+-----------+-----------------------------------+
| 8083 | MQTT(WebSocket), HTTP API Port |
+-----------+-----------------------------------+
| 8084 | MQTT(WebSocket/SSL), HTTP API Port|
+-----------+-----------------------------------+
| 18083 | Web Dashboard Port |
+-----------+-----------------------------------+
The TCP ports used can be configured in etc/emqttd.config:
.. code-block:: properties
## TCP Listener: 1883, 127.0.0.1:1883, ::1:1883
mqtt.listener.tcp = 1883
## SSL Listener: 8883, 127.0.0.1:8883, ::1:8883
mqtt.listener.ssl = 8883
## HTTP and WebSocket Listener
mqtt.listener.http = 8083
The 18083 port is used by Web Dashboard of the broker. Default login: admin, Password: public
.. _quick_setup:
-----------
Quick Setup
-----------
Two main configuration files of the *EMQ* broker:
+-----------------------+-----------------------------------+
| etc/emq.conf | EMQ Broker Config |
+-----------------------+-----------------------------------+
| etc/plugins/\*.conf | EMQ Plugins' Config |
+-----------------------+-----------------------------------+
Two important parameters in etc/emq.conf:
+--------------------+-------------------------------------------------------------------------+
| node.process_limit | Max number of Erlang proccesses. A MQTT client consumes two proccesses. |
| | The value should be larger than max_clients * 2 |
+--------------------+-------------------------------------------------------------------------+
| node.max_ports | Max number of Erlang Ports. A MQTT client consumes one port. |
| | The value should be larger than max_clients. |
+--------------------+-------------------------------------------------------------------------+
.. NOTE::
node.process_limit > maximum number of allowed concurrent clients * 2
node.max_ports > maximum number of allowed concurrent clients
The maximum number of allowed MQTT clients:
.. code-block:: properties
mqtt.listener.tcp = 1883
mqtt.listener.tcp.acceptors = 8
mqtt.listener.tcp.max_clients = 1024
.. _init_d_emqttd:
-------------------
/etc/init.d/emqttd
-------------------
.. code-block:: bash
#!/bin/sh
#
# emqttd Startup script for emqttd.
#
# chkconfig: 2345 90 10
# description: emqttd is mqtt broker.
# source function library
. /etc/rc.d/init.d/functions
# export HOME=/root
start() {
echo "starting emqttd..."
cd /opt/emqttd && ./bin/emqttd start
}
stop() {
echo "stopping emqttd..."
cd /opt/emqttd && ./bin/emqttd stop
}
restart() {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo $"Usage: $0 {start|stop}"
RETVAL=2
esac
chkconfig::
chmod +x /etc/init.d/emqttd
chkconfig --add emqttd
chkconfig --list
boot test::
service emqttd start
.. NOTE::
## erlexec: HOME must be set
uncomment '# export HOME=/root' if "HOME must be set" error.
.. _emq_dashboard: https://github.com/emqtt/emqttd_dashboard

View File

@ -1,10 +0,0 @@
.. _mqtt_sn:
TODO:...
================
MQTT-SN Protocol
================

View File

@ -1,101 +0,0 @@
.. _mqtt:
TODO:...
=============
MQTT Protocol
=============
----------------------
MQTT Protocol Tutorial
----------------------
MQTT.ORG docs: a publish/subscribe messaging protocol which is extremely lightweight, for IoT, M2M and mobile messaging
.. image:: _static/images/pubsub_concept.png
Publish/Subscribe Model
-----------------------
.. image:: _static/images/pubsub_concept.png
MQTT Control Packets
--------------------
MQTT Packet Structure
---------------------
Compact: 1 byte header
MQTT Packet Types
-----------------
MQTT Packet Flags
-----------------
MQTT Client Libraries
---------------------
MQTT Client Libraries
---------------------
mosquitto_pub mosquitto_sub co
mqtt.org:
TODO: LIST
Maintained by emqtt.com:
TODO: LIST
-------------------------
QoS0, QoS1, QoS2 Messages
-------------------------
C->S Sequence...
----------------
Retained Message
----------------
publish a retained message::
mosquitto_pub -t topic -m msg -q 1 -r
subscribe to get the message::
mosquitto_sub -t topic -m msg -q 1 -r
------------
Will Message
------------
------------
Keep Alive
------------
----------------------------------
Clean Session and Offline Messages
----------------------------------
MQTT Client Libraries
---------------------
mosquitto_pub mosquitto_sub co
mqtt.org:
TODO: LIST
Maintained by emqtt.com:
TODO: LIST

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +0,0 @@
.. _tables:
======
Tables
======
+--------------------+--------+----------------------------------------+
| Table | Type | Description |
+====================+========+========================================+
| mqtt_trie | mnesia | Trie Table |
+--------------------+--------+----------------------------------------+
| mqtt_trie_node | mnesia | Trie Node Table |
+--------------------+--------+----------------------------------------+
| mqtt_route | mnesia | Global Route Table |
+--------------------+--------+----------------------------------------+
| mqtt_local_route | mnesia | Local Route Table |
+--------------------+--------+----------------------------------------+
| mqtt_pubsub | ets | PubSub Tab |
+--------------------+--------+----------------------------------------+
| mqtt_subscriber | ets | Subscriber Tab |
+--------------------+--------+----------------------------------------+
| mqtt_subscription | ets | Subscription Tab |
+--------------------+--------+----------------------------------------+
| mqtt_session | mnesia | Global Session Table |
+--------------------+--------+----------------------------------------+
| mqtt_local_session | ets | Local Session Table |
+--------------------+--------+----------------------------------------+
| mqtt_client | ets | Client Table |
+--------------------+--------+----------------------------------------+

View File

@ -1,133 +0,0 @@
.. _tune:
============
Tuning Guide
============
Tuning the Linux Kernel, Networking, Erlang VM and the *EMQ* broker for one million concurrent MQTT connections.
-------------------
Linux Kernel Tuning
-------------------
The system-wide limit on max opened file handles::
# 2 million system-wide
sysctl -w fs.file-max=2097152
sysctl -w fs.nr_open=2097152
echo 2097152 > /proc/sys/fs/nr_open
The limit on opened file handles for current session::
ulimit -n 1048576
/etc/sysctl.conf
----------------
Add the 'fs.file-max' to /etc/sysctl.conf, make the changes permanent::
fs.file-max = 1048576
/etc/security/limits.conf
-------------------------
Persist the limits on opened file handles for users in /etc/security/limits.conf::
* soft nofile 1048576
* hard nofile 1048576
--------------
Network Tuning
--------------
Increase number of incoming connections backlog::
sysctl -w net.core.somaxconn=32768
sysctl -w net.ipv4.tcp_max_syn_backlog=16384
sysctl -w net.core.netdev_max_backlog=16384
Local Port Range::
sysctl -w net.ipv4.ip_local_port_range="1000 65535"
Read/Write Buffer for TCP connections::
sysctl -w net.core.rmem_default=262144
sysctl -w net.core.wmem_default=262144
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.core.optmem_max=16777216
#sysctl -w net.ipv4.tcp_mem='16777216 16777216 16777216'
sysctl -w net.ipv4.tcp_rmem='1024 4096 16777216'
sysctl -w net.ipv4.tcp_wmem='1024 4096 16777216'
Connection Tracking::
sysctl -w net.nf_conntrack_max=1000000
sysctl -w net.netfilter.nf_conntrack_max=1000000
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30
The TIME-WAIT Buckets Pool, Recycling and Reuse::
net.ipv4.tcp_max_tw_buckets=1048576
# Enable fast recycling of TIME_WAIT sockets. Enabling this
# option is not recommended for devices communicating with the
# general Internet or using NAT (Network Address Translation).
# Since some NAT gateways pass through IP timestamp values, one
# IP can appear to have non-increasing timestamps.
# net.ipv4.tcp_tw_recycle = 1
# net.ipv4.tcp_tw_reuse = 1
Timeout for FIN-WAIT-2 sockets::
net.ipv4.tcp_fin_timeout = 15
----------------
Erlang VM Tuning
----------------
Tuning and optimize the Erlang VM in etc/emq.conf file:
.. code-block:: properties
## Erlang Process Limit
node.process_limit = 2097152
## Sets the maximum number of simultaneously existing ports for this system
node.max_ports = 1048576
--------------
The EMQ Broker
--------------
Tune the acceptor pool, max_clients limit and sockopts for TCP listener in etc/emqttd.config:
.. code-block:: properties
## TCP Listener
mqtt.listener.tcp = 1883
mqtt.listener.tcp.acceptors = 64
mqtt.listener.tcp.max_clients = 1000000
--------------
Client Machine
--------------
Tune the client machine to benchmark emqttd broker:
.. code-block:: bash
sysctl -w net.ipv4.ip_local_port_range="500 65535"
sysctl -w fs.file-max=1000000
echo 1000000 > /proc/sys/fs/nr_open
ulimit -n 100000
---------------
emqtt_benchmark
---------------
Test tool for concurrent connections: http://github.com/emqtt/emqtt_benchmark

View File

@ -1,33 +0,0 @@
.. _upgrade:
=======
Upgrade
=======
.. _upgrade_1.1.2:
----------------
Upgrade to 1.1.2
----------------
.. NOTE:: 1.0+ releases can be upgraded to 1.1.2 smoothly
Steps:
1. Download and install emqttd-1.1.2 to the new directory, for example::
Old installation: /opt/emqttd_1_0_0/
New installation: /opt/emqttd_1_1_2/
2. Copy the 'etc/' and 'data/' from the old installation::
cp -R /opt/emqttd_1_0_0/etc/* /opt/emqttd_1_1_2/etc/
cp -R /opt/emqttd_1_0_0/data/* /opt/emqttd_1_1_2/data/
3. Copy the plugins/{plugin}/etc/* from the old installation if you loaded plugins.
4. Stop the old emqttd, and start the new one.