0 Documentation
Release 2.0.5
1 Get Started 3
1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Quick Start . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 Web Dashboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.5 Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.6 One Million Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.7 MQTT Client Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2 Installation 9
2.1 Download Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2 Installing on Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3 Installing on FreeBSD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4 Installing on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.5 Installing on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.6 Install via Docker Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.7 Installing From Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.8 TCP Ports Used . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.9 Quick Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.10 /etc/init.d/emqttd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3 Configuration 15
3.1 EMQ 2.0 Config Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.2 OS Environment Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.3 EMQ Node and Cookie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.4 Erlang VM Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.5 Log Level and File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.6 MQTT Protocol Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.7 Allow Anonymous and ACL File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.8 MQTT Session Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.9 MQTT Message Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.10 Sys Interval of Broker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.11 PubSub Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.12 MQTT Bridge Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.13 Plugins Etc Folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.14 MQTT Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.15 System Monitor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
i
3.16 Plugin Configuration Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4 Clustering 25
4.1 Distributed Erlang/OTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2 Cluster Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.3 Cluster Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.4 Session across Nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.5 The Firewall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.6 Network Partitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.7 Consistent Hash and DHT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5 Bridge 31
5.1 EMQ Node Bridge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.2 EMQ Bridge CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
5.3 mosquitto Bridge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
5.4 rsmb Bridge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
6 User Guide 35
6.1 Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
6.2 Allow Anonymous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
6.3 ACL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6.4 MQTT Publish/Subscribe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.5 HTTP Publish API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
6.6 MQTT Over WebSocket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
6.7 $SYS Topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
6.8 Trace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
7 Advanced 49
7.1 Local Subscription . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
7.2 Shared Subscription . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
8 Design 51
8.1 Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
8.2 Connection Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.3 Session Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
8.4 PubSub Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
8.5 Routing Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
8.6 Authentication and ACL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
8.7 Hooks Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
8.8 Plugin Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
8.9 Mnesia/ETS Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
9 Commands 61
9.1 status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
9.2 broker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
9.3 cluster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
9.4 clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
9.5 sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
9.6 routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
9.7 topics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
9.8 subscriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
9.9 plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
9.10 bridges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
9.11 vm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
9.12 trace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
ii
9.13 listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
9.14 mnesia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
9.15 admins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
10 Plugins 75
10.1 emq_plugin_template - Template Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
10.2 emq_retainer - Retainer Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
10.3 emq_auth_clientid - ClientID Auth Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
10.4 emq_auth_username - Username Auth Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
10.5 emq_dashboard - Dashboard Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
10.6 emq_auth_ldap: LDAP Auth Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
10.7 emq_auth_http - HTTP Auth/ACL Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
10.8 emq_auth_mysql - MySQL Auth/ACL Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
10.9 emq_auth_pgsql - PostgreSQL Auth/ACL Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
10.10 emq_auth_redis - Redis Auth/ACL Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
10.11 emq_auth_mongo - MongoDB Auth/ACL Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
10.12 emq_modules - Modules Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
10.13 emq_mod_presence - Presence Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
10.14 emq_mod_retainer - Retainer Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
10.15 emq_mod_subscription - Subscription Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
10.16 emq_mod_rewrite - Topic Rewrite Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
10.17 emq_coap: CoAP Protocol Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
10.18 emq_sn: MQTT-SN Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
10.19 emq_stomp - STOMP Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
10.20 emq_sockjs - STOMP/SockJS Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
10.21 emq_recon - Recon Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
10.22 emq_reloader - Reloader Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
10.23 Plugin Development Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
11 Tuning Guide 97
11.1 Linux Kernel Tuning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
11.2 Network Tuning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
11.3 Erlang VM Tuning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
11.4 The EMQ Broker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
11.5 Client Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
11.6 emqtt_benchmark . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
12 Changes 101
12.1 Version 2.1.0-rc.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
12.2 Version 2.1.0-rc.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
12.3 Version 2.1.0-beta.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
12.4 Version 2.1.0-beta.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
12.5 Version 2.1-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
12.6 Version 2.1-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
12.7 Version 2.0.7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
12.8 Version 2.0.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
12.9 Version 2.0.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
12.10 Version 2.0.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
12.11 Version 2.0.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
12.12 Version 2.0.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
12.13 Version 2.0.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
12.14 Version 2.0 West of West Lake . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
12.15 Version 2.0-rc.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
12.16 Version 2.0-rc.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
iii
12.17 Version 2.0-rc.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
12.18 Version 2.0-beta.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
12.19 Version 2.0-beta.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
12.20 Version 2.0-beta.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
12.21 Version 1.1.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
12.22 Version 1.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
12.23 Version 1.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
12.24 Version 1.1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
12.25 Version 1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
12.26 Version 1.0.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
12.27 Version 1.0.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
12.28 Version 1.0.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
12.29 Version 1.0 (The Seven Mile Journey) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
12.30 Version 0.17.1-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
12.31 Version 0.17.0-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
12.32 Version 0.16.0-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
12.33 Version 0.15.0-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
12.34 Version 0.14.1-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
12.35 Version 0.14.0-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
12.36 Version 0.13.1-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
12.37 Version 0.13.0-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
12.38 Version 0.12.3-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
12.39 Version 0.12.2-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
12.40 Version 0.12.1-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
12.41 Version 0.12.0-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
12.42 Version 0.11.0-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
12.43 Version 0.10.4-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
12.44 Version 0.10.3-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
12.45 Version 0.10.2-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
12.46 Version 0.10.1-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
12.47 Version 0.10.0-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
12.48 Version 0.9.3-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
12.49 Version 0.9.2-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
12.50 Version 0.9.1-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
12.51 Version 0.9.0-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
12.52 Version 0.8.6-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
12.53 Version 0.8.5-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
12.54 Version 0.8.4-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
12.55 Version 0.8.3-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
12.56 Version 0.8.2-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
12.57 Version 0.8.1-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
12.58 Version 0.8.0-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
12.59 Version 0.7.1-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
12.60 Version 0.7.0-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
12.61 Version 0.6.2-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
12.62 Version 0.6.1-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
12.63 Version 0.6.0-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
12.64 Version 0.5.5-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
12.65 Version 0.5.4-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
12.66 Version 0.5.3-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
12.67 Version 0.5.2-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
12.68 Version 0.5.1-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
12.69 Version 0.5.0-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
12.70 Version 0.4.0-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
iv
12.71 Version 0.3.4-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
12.72 Version 0.3.3-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
12.73 Version 0.3.2-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
12.74 Version 0.3.1-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
12.75 Version 0.3.0-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
12.76 Version 0.3.0-alpha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
12.77 Version 0.2.1-beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
12.78 Version 0.2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
12.79 Version 0.1.5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
12.80 Version 0.1.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
12.81 Version 0.1.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
12.82 Version 0.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
12.83 Version 0.1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
12.84 Version 0.1.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
13 Upgrade 137
13.1 Upgrade to 2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
13.2 Upgrade to 1.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
14 License 139
v
vi
EMQ 2.0 Documentation, Release 2.0.5
EMQ(Erlang MQTT Broker) is a distributed, massively scalable, highly extensible MQTT message broker written in
Erlang/OTP.
EMQ is fully open source and licensed under the Apache Version 2.0. EMQ implements both MQTT V3.1 and V3.1.1
protocol specifications, and supports MQTT-SN, CoAP, WebSocket, STOMP and SockJS at the same time.
EMQ provides a scalable, reliable, enterprise-grade MQTT message Hub for IoT, M2M, Smart Hardware and Mobile
Messaging Applications. Sensors, Mobiles, Web Browsers and Application Servers could be connected by EMQ
brokers with asynchronous PUB/SUB MQTT messages.
The 1.0 release of the EMQ broker has scaled to 1.3 million concurrent MQTT connections on a 12 Core, 32G CentOS
server.
Please visit [emqtt.io](http://emqtt.io) for more service. Follow us on Twitter: [@emqtt](https://twitter.com/emqtt)
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:
Contents 1
EMQ 2.0 Documentation, Release 2.0.5
2 Contents
CHAPTER 1
Get Started
Overview
EMQ (Erlang MQTT Broker) is an open source MQTT broker written in Erlang/OTP. Erlang/OTP is a concur-
rent, fault-tolerant, soft-realtime and distributed programming platform. MQTT is an extremely lightweight pub-
lish/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
3
EMQ 2.0 Documentation, Release 2.0.5
Quick Start
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:
# Start emqttd
./bin/emqttd start
# Check Status
./bin/emqttd_ctl status
# Stop emqttd
./bin/emqttd stop
Note: The EMQ broker requires Erlang R18+ to build since 1.1 release.
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
Plugins
The EMQ broker could be extended by Plugins. A plugin is an Erlang application that adds extra feature to the EMQ
broker:
emq_retainer Store Retained Messages
emq_dashboard Web Dashboard
emq_modules Presence, Subscription, Rewrite Modules
emq_auth_clientid Authentication with ClientId
emq_auth_username Authentication with Username and Password
emq_plugin_template Plugin template and demo
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
Authentication with MongoDB
emq_mod_mongo_
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:
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.
# 2M:
sysctl -w fs.file-max=2097152
sysctl -w fs.nr_open=2097152
echo 2097152 > /proc/sys/fs/nr_open
# 1M:
ulimit -n 1048576
# backlog
sysctl -w net.core.somaxconn=65536
Erlang VM
emqttd/etc/emq.conf:
## Sets the maximum number of simultaneously existing ports for this system
node.max_ports = 1048576
emqttd/etc/emq.conf listeners:
Test Client
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
Installation
The EMQ broker is cross-platform, which could be deployed on Linux, FreeBSD, Mac, Windows and even Raspberry
Pi.
Download Packages
Installing on Linux
9
EMQ 2.0 Documentation, Release 2.0.5
unzip emqttd-centos64-v2.0.zip
Installing on FreeBSD
10 Chapter 2. Installation
EMQ 2.0 Documentation, Release 2.0.5
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:
The install and boot process on Mac are same to Linux.
Installing on Windows
bin\emqttd console
bin\emqttd install
bin\emqttd start
bin\emqttd stop
bin\emqttd uninstall
unzip emqttd-docker-v2.0.zip
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:
git clone https://github.com/emqtt/emq-relx.git
12 Chapter 2. Installation
EMQ 2.0 Documentation, Release 2.0.5
The 18083 port is used by Web Dashboard of the broker. Default login: admin, Password: public
Quick Setup
Note: node.process_limit > maximum number of allowed concurrent clients * 2 node.max_ports > maximum number
of allowed concurrent clients
mqtt.listener.tcp.acceptors = 8
mqtt.listener.tcp.max_clients = 1024
/etc/init.d/emqttd
#!/bin/sh
#
# emqttd Startup script for emqttd.
#
# chkconfig: 2345 90 10
# description: emqttd is mqtt broker.
# 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:
Note: ## erlexec: HOME must be set uncomment # export HOME=/root if HOME must be set error.
14 Chapter 2. Installation
CHAPTER 3
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
The EMQ 2.0-rc.2 release integrated with cuttlefish library, and adopted a more user-friendly k = v syntax for config-
uration file:
## 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 |
----------------------
-------------------
15
EMQ 2.0 Documentation, Release 2.0.5
OS Environment Variables
The node name and cookie of EMQ should be configured when clustering:
## Node name
node.name = emqttd@127.0.0.1
Erlang VM Arguments
## Sets the maximum number of simultaneously existing ports for this system
node.max_ports = 65536
## Crash dump
node.crash_dump = log/crash.dump
16 Chapter 3. Configuration
EMQ 2.0 Documentation, Release 2.0.5
Console Log
## Console log level. Enum: debug, info, notice, warning, error, critical, alert,
emergency
log.console.level = error
Error Log
Crash Log
log.crash.file = log/crash.log
Syslog
## syslog level. Enum: debug, info, notice, warning, error, critical, alert,
emergency
log.syslog.level = error
Force GC Count
Allow Anonymous
18 Chapter 3. Configuration
EMQ 2.0 Documentation, Release 2.0.5
An ACL rule is an Erlang tuple. The Access control module of EMQ broker matches the rule one by one from top to
bottom:
## Upgrade QoS?
mqtt.session.upgrade_qos = off
## Max number of QoS 1 and 2 messages that can be inflight at one time.
## 0 means no limit
mqtt.session.max_inflight = 32
20 Chapter 3. Configuration
EMQ 2.0 Documentation, Release 2.0.5
PubSub Parameters
mqtt.pubsub.by_clientid = true
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
## HTTP(SSL) Listener
mqtt.listener.https = 8084
mqtt.listener.https.acceptors = 4
mqtt.listener.https.max_clients = 64
mqtt.listener.https.handshake_timeout = 15
22 Chapter 3. Configuration
EMQ 2.0 Documentation, Release 2.0.5
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
## Long Schedule(ms)
sysmon.long_schedule = 240
## Busy Port
sysmon.busy_port = false
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
24 Chapter 3. Configuration
CHAPTER 4
Clustering
Distributed Erlang/OTP
Erlang/OTP is a concurrent, fault-tolerant, distributed programming platform. A distributed Erlang/OTP system con-
sists of a number of Erlang runtime systems called node. Nodes connect to each other with TCP/IP sockets and
communicate by Message Passing.
--------- ---------
| 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:
25
EMQ 2.0 Documentation, Release 2.0.5
(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.
(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
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:
26 Chapter 4. Clustering
EMQ 2.0 Documentation, Release 2.0.5
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 |
--------------------------
The brokers in the cluster route messages by topic trie and route table, deliver messages to MQTT clients by subscrip-
tions. 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:
client1->node1: Publish[t/a]
node1-->node2: Route[t/#]
node1-->node3: Route[t/a]
node2-->client2: Deliver[t/#]
node3-->client3: Deliver[t/a]
Cluster Setup
Warning: The node name is Name@Host, where Host is IP address or the fully qualified host name.
emqttd@s1.emqtt.io config
etc/emq.conf:
node.name = emqttd@s1.emqtt.io
or
node.name = emqttd@192.168.0.10
Warning: The name cannot be changed after node joined the cluster.
emqttd@s2.emqtt.io config
etc/emq.conf:
28 Chapter 4. Clustering
EMQ 2.0 Documentation, Release 2.0.5
node.name = emqttd@s2.emqtt.io
or
node.name = emqttd@192.168.0.20
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:
[{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:
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 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.
30 Chapter 4. Clustering
CHAPTER 5
Bridge
Two or more EMQ brokers could be bridged together. Bridges forward MQTT messages from one broker node to
another:
Configure Bridge
1. Start Brokers
31
EMQ 2.0 Documentation, Release 2.0.5
bridge is started.
bridge: emqttd1@127.0.0.1--sensor/#-->emqttd2@127.0.0.1
#emqttd2
mosquitto_sub -t sensor/# -p 2883 -d
#emqttd1
mosquitto_pub -t sensor/1/temperature -m "37.5" -d
#query bridges
./bin/emqttd_ctl bridges list
#start bridge
./bin/emqttd_ctl bridges start <Node> <Topic>
#stop bridge
./bin/emqttd_ctl bridges stop <Node> <Topic>
mosquitto Bridge
mosquitto.conf
32 Chapter 5. Bridge
EMQ 2.0 Documentation, Release 2.0.5
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
connection emqttd
addresses 127.0.0.1:2883
topic sensor/#
34 Chapter 5. Bridge
CHAPTER 6
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:
Allow Anonymous
35
EMQ 2.0 Documentation, Release 2.0.5
Username/Password
auth.user.$N.username = admin
auth.user.$N.password = public
ClientId
auth.client.$N.clientid = clientid
auth.client.$N.password = passwd
LDAP
etc/plugins/emq_auth_ldap.conf:
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
HTTP
etc/plugins/emq_auth_http.conf:
## 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
MySQL
## Mysql Username
## auth.mysql.username =
## Mysql Password
## auth.mysql.password =
## Mysql Database
auth.mysql.database = mqtt
## %% Superuser Query
auth.mysql.super_query = select is_superuser from mqtt_user where username = '%u'
limit 1
PostgreSQL
## 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
## Superuser Query
auth.pgsql.super_query = select is_superuser from mqtt_user where username = '%u'
limit 1
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:
## Redis Server
auth.redis.server = 127.0.0.1:6379
## Redis Database
auth.redis.database = 0
## Redis Password
## auth.redis.password =
MongoDB
## 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
ACL
The ACL of EMQ broker is responsible for authorizing MQTT clients to publish/subscribe topics.
The ACL rules define:
Access Control Module of EMQ broker will match the rules one by one:
Internal
HTTP API
auth.http.acl_nomatch = deny
MySQL
ACL with MySQL database. The mqtt_acl table and default data:
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/#');
%c'
6.3. ACL 41
EMQ 2.0 Documentation, Release 2.0.5
## ACL nomatch
auth.mysql.acl_nomatch = deny
PostgreSQL
ACL with PostgreSQL database. The mqtt_acl table and default data:
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/#');
%c'
Redis
ACL with Redis. The ACL rules are stored in a Redis HashSet:
## ACL nomatch
auth.redis.acl_nomatch = deny
MongoDB
{
username: "username",
clientid: "clientid",
publish: ["topic1", "topic2", ...],
subscribe: ["subtop1", "subtop2", ...],
pubsub: ["topic/#", "topic1", ...]
}
## 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 appli-
cations.
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!"
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:
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
$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}/
$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.
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
Broker Statistics
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
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
Broker Sysmon
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:
Trace a topic:
Lookup Traces:
Stop a Trace:
Advanced
Local Subscription
The EMQ broker will not create global routes for Local Subscription, and only dispatch MQTT messages on local
node.
mosquitto_sub -t '$local/topic'
mosquitto_pub -t 'topic'
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
---------
49
EMQ 2.0 Documentation, Release 2.0.5
50 Chapter 7. Advanced
CHAPTER 8
Design
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.
The EMQ 2.0 seperated the Message Flow Plane and Monitor/Control Plane, the Architecture is something like:
51
EMQ 2.0 Documentation, Release 2.0.5
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
52 Chapter 8. Design
EMQ 2.0 Documentation, Release 2.0.5
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.
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.
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 ->|
--------------------------------------------------------
PubSub Layer
The PubSub layer maintains a subscription table and is responsible to dispatch MQTT messages to subscribers.
MQTT messages will be dispatched to the subscribers 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 |
54 Chapter 8. Design
EMQ 2.0 Documentation, Release 2.0.5
The routing layer would route MQTT messages among clustered nodes by topic trie match and routing table lookup:
Authentication Bahaviour
-module(emqttd_auth_mod).
-ifdef(use_specs).
-else.
-export([behaviour_info/1]).
behaviour_info(callbacks) ->
[{init, 1}, {check, 3}, {description, 0}];
behaviour_info(_Other) ->
undefined.
-endif.
Authorization(ACL)
-module(emqttd_acl_mod).
-include("emqttd.hrl").
-ifdef(use_specs).
-callback check_acl({Client, PubSub, Topic}, State :: any()) -> allow | deny | ignore
when
Client :: mqtt_client(),
PubSub :: pubsub(),
Topic :: binary().
-else.
-export([behaviour_info/1]).
behaviour_info(callbacks) ->
[{init, 1}, {check_acl, 2}, {reload_acl, 1}, {description, 0}];
behaviour_info(_Other) ->
undefined.
-endif.
56 Chapter 8. Design
EMQ 2.0 Documentation, Release 2.0.5
%%%-----------------------------------------------------------------------------
%%%
%%% -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, all}.
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:
Hook Implementation
-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()}.
run_hooks(Hook :: atom(), Args :: list(any()), Acc :: any()) -> {ok | stop, any()}.
-module(emqttd_hook).
%% Hooks API
-export([add/3, add/4, delete/2, run/3, lookup/1]).
Hook Usage
-module(emq_plugin_template).
-export([load/1, unload/0]).
58 Chapter 8. Design
EMQ 2.0 Documentation, Release 2.0.5
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]).
{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).
Plugin Design
Plugin is a normal erlang application that can be started/stopped dynamically by a running EMQ broker.
emqttd_plugins Module
-module(emqttd_plugins).
-export([load/1, unload/1]).
Load a Plugin
Plugin Template
http://github.com/emqtt/emq_plugin_template
Mnesia/ETS Tables
60 Chapter 8. Design
CHAPTER 9
Commands
The ./bin/emqttd_ctl command line could be used to query and administrate the EMQ broker.
status
$ ./bin/emqttd_ctl status
broker
$ ./bin/emqttd_ctl broker
61
EMQ 2.0 Documentation, Release 2.0.5
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
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
62 Chapter 9. Commands
EMQ 2.0 Documentation, Release 2.0.5
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
cluster
9.3. cluster 63
EMQ 2.0 Documentation, Release 2.0.5
clients
clients lists
...
64 Chapter 9. Commands
EMQ 2.0 Documentation, Release 2.0.5
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
created_at=1452935508)
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
created_at=1452935508)
9.5. sessions 65
EMQ 2.0 Documentation, Release 2.0.5
created_at=1452935401)
Show a session:
created_at=1452935508)
routes
routes list
Show a route:
topics
topics list
66 Chapter 9. Commands
EMQ 2.0 Documentation, Release 2.0.5
$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
...
Show a topic:
$SYS/brokers: static
subscriptions
subscriptions list
clientid: [{<<"x">>,1},{<<"topic2">>,1},{<<"topic3">>,1}]
9.8. subscriptions 67
EMQ 2.0 Documentation, Release 2.0.5
plugins
plugins list
Properties of a plugin:
version Plugin Version
description Plugin Description
active If the plugin is Loaded
Load <Plugin>
Load a Plugin:
68 Chapter 9. Commands
EMQ 2.0 Documentation, Release 2.0.5
Unload <Plugin>
Unload a Plugin:
bridges
--------- ---------
Publisher --> | node1 | --Bridge Forward--> | node2 | --> Subscriber
--------- ---------
bridge is started.
bridge: emqttd1@127.0.0.1--sensor/#-->emqttd2@127.0.0.1
#emqttd2 node
#emqttd1 node
bridges options
9.10. bridges 69
EMQ 2.0 Documentation, Release 2.0.5
Options:
qos = 0 | 1 | 2
prefix = string
suffix = string
queue = integer
Example:
qos=2,prefix=abc/,suffix=/yxz,queue=1000
bridge is stopped.
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
70 Chapter 9. Commands
EMQ 2.0 Documentation, Release 2.0.5
memory/binary : 51432
memory/code : 13401565
memory/ets : 1082848
vm process
$ ./bin/emqttd_ctl vm process
process/limit : 8192
process/count : 221
vm io
$ ./bin/emqttd_ctl vm io
io/max_fds : 2560
io/active_fds : 1
trace
9.12. trace 71
EMQ 2.0 Documentation, Release 2.0.5
trace list
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 : []
72 Chapter 9. Commands
EMQ 2.0 Documentation, Release 2.0.5
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
mnesia
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
admins passwd
Reset password:
admins del
9.14. mnesia 73
EMQ 2.0 Documentation, Release 2.0.5
74 Chapter 9. Commands
CHAPTER 10
Plugins
The EMQ broker could be extended by plugins. Users could develop plugins to customize authentication, ACL and
functions of the broker, or integrate the broker with other systems.
The plugins that EMQ 2.0-rc.2 released:
Plugin Description
emq_dashboard Web Dashboard
emq_retainer Store Retained Messages
emq_modules Extend Modules Plugin
emq_auth_clientid ClientId Auth Plugin
emq_auth_username Username/Password Auth Plugin
emq_auth_ldap LDAP Auth
emq_auth_http HTTP Auth/ACL Plugin
emq_auth_mysql MySQL Auth/ACL Plugin
emq_auth_pgsql PostgreSQL Auth/ACL Plugin
emq_auth_redis Redis Auth/ACL Plugin
emq_auth_mongo MongoDB Auth/ACL Plugin
emq_coap CoAP Protocol Plugin
emq_sn MQTT-SN Protocol Plugin
emq_stomp STOMP Protocol Plugin
emq_sockjs STOMP over SockJS Plugin
emq_recon Recon Plugin
emq_reloader Reloader Plugin
emq_plugin_template Template Plugin
A plugin is just a normal Erlang application which has its own configuration file: etc/<PluginName>.conf|config.
emq_plugin_template is a plugin template.
75
EMQ 2.0 Documentation, Release 2.0.5
etc/plugins/emq_retainer.conf:
etc/plugins/emq_auth_clientid.conf:
##auth.client.$N.clientid = clientid
##auth.client.$N.password = passwd
## Examples
##auth.client.1.clientid = id
##auth.client.1.password = passwd
##auth.client.2.clientid = dev:devid
##auth.client.2.password = passwd2
##auth.client.3.clientid = app:appid
##auth.client.3.password = passwd3
etc/plugins/emq_auth_username.conf:
##auth.user.$N.username = admin
##auth.user.$N.password = public
## Examples:
##auth.user.1.username = admin
##auth.user.1.password = public
##auth.user.2.username = feng@emqtt.io
##auth.user.2.password = public
The Web Dashboard for EMQ broker. The plugin will be loaded automatically when the broker started successfully.
Address http://localhost:18083
Default User admin
Default Password public
etc/plugins/emq_dashboard.conf:
## HTTP Listener
dashboard.listener.http = 18083
dashboard.listener.http.acceptors = 2
dashboard.listener.http.max_clients = 512
## HTTPS Listener
## dashboard.listener.https = 18084
## dashboard.listener.https.acceptors = 2
## dashboard.listener.https.max_clients = 512
## dashboard.listener.https.handshake_timeout = 15
## dashboard.listener.https.certfile = etc/certs/cert.pem
## dashboard.listener.https.keyfile = etc/certs/key.pem
## dashboard.listener.https.cacertfile = etc/certs/cacert.pem
## dashboard.listener.https.verify = verify_peer
## dashboard.listener.https.fail_if_no_peer_cert = true
etc/plugins/emq_auth_ldap.conf:
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
etc/plugins/emq_auth_http.conf:
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
auth.http.acl_nomatch = deny
Return 200 if ok
Return 4xx if unauthorized
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/#');
etc/plugins/emq_auth_mysql.conf:
## Mysql Server
auth.mysql.server = 127.0.0.1:3306
## Mysql Username
## auth.mysql.username =
## Mysql Password
## auth.mysql.password =
## Mysql Database
auth.mysql.database = mqtt
## %% Superuser Query
auth.mysql.super_query = select is_superuser from mqtt_user where username = '%u'
limit 1
%c'
## ACL nomatch
auth.mysql.acl_nomatch = deny
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/#');
auth.pgsql.pool = 8
auth.pgsql.username = root
#auth.pgsql.password =
auth.pgsql.database = mqtt
auth.pgsql.encoding = utf8
auth.pgsql.ssl = false
## Superuser Query
%c'
etc/plugins/emq_auth_redis.conf:
## Redis Server
auth.redis.server = 127.0.0.1:6379
## Redis Database
auth.redis.database = 0
## Redis Password
## auth.redis.password =
## ACL nomatch
auth.redis.acl_nomatch = deny
etc/plugins/emq_auth_mongo.conf:
## Mongo Server
auth.mongo.server = 127.0.0.1:27017
## 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
## acl_query
auth.mongo.acl_query.collection = mqtt_user
auth.mongo.acl_query.selector = username=%u
## acl_nomatch
auth.mongo.acl_nomatch = deny
MongoDB Database
{
username: "user",
password: "password hash",
is_superuser: boolean (true, false),
created: "datetime"
}
For example:
{
username: "username",
clientid: "clientid",
publish: ["topic1", "topic2", ...],
subscribe: ["subtop1", "subtop2", ...],
For example:
##--------------------------------------------------------------------
## Presence Module
##--------------------------------------------------------------------
module.presence.qos = 1
##--------------------------------------------------------------------
## Subscription Module
##--------------------------------------------------------------------
## module.subscription.2.topic = $user/%u
## module.subscription.2.qos = 1
##--------------------------------------------------------------------
## Rewrite Module
##--------------------------------------------------------------------
Presence module will publish presence message to $SYS topic when a client connected or disconnected:
etc/plugins/emq_mod_presence.conf:
## Enable presence module
## Values: on | off
module.presence = on
module.presence.qos = 0
etc/plugins/emq_mod_retainer.conf:
## disc: disc_copies, ram: ram_copies
module.retainer.storage_type = ram
Subscription module forces the client to subscribe some topics when connected to the broker:
etc/plugins/emq_mod_subscription.conf:
##module.subscription.2.topic = $user/%u
##module.subscription.2.qos = 1
etc/plugins/emq_mod_rewrite.config:
[
{emq_mod_rewrite, [
{rules, [
%% {rewrite, Topic, Re, Dest}
coap.server = 5683
coap.prefix.mqtt = mqtt
coap.handler.mqtt = emq_coap_gateway
libcoap Client
etc/plugins/emq_sn.conf:
mqtt.sn.port = 1884
Support STOMP 1.0/1.1/1.2 clients to connect to emqttd broker and communicate with MQTT Clients.
etc/plugins/emq_stomp.conf:
stomp.default_user.login = guest
stomp.default_user.passcode = guest
stomp.allow_anonymous = true
stomp.frame.max_headers = 10
stomp.frame.max_header_length = 1024
stomp.frame.max_body_length = 8192
stomp.listener = 61613
stomp.listener.acceptors = 4
stomp.listener.max_clients = 512
emq_sockjs plugin enables web browser to connect to emqttd broker and communicate with MQTT clients.
[
{emq_sockjs, [
{sockjs, []},
%% TODO: unused...
{stomp, [
{frame, [
{max_headers, 10},
{max_header_length, 1024},
{max_body_length, 8192}
]}
]}
]}
].
http://localhost:61616/index.html
The plugin loads recon library on a running EMQ broker. Recon libray helps debug and optimize an Erlang application.
Recon CLI
./bin/emqttd_ctl recon
reload CLI
./bin/emqttd_ctl reload
Create a plugin project with erlang.mk and depends on emqttd application, the Makefile:
PROJECT = emq_plugin_abc
PROJECT_DESCRIPTION = emqttd abc plugin
PROJECT_VERSION = 1.0
BUILD_DEPS = emqttd
COVER = true
include erlang.mk
-module(emq_auth_demo).
-behaviour(emqttd_auth_mod).
-include_lib("emqttd/include/emqttd.hrl").
-module(emq_acl_demo).
-include_lib("emqttd/include/emqttd.hrl").
%% ACL callbacks
-export([init/1, check_acl/2, reload_acl/1, description/0]).
init(Opts) ->
{ok, Opts}.
reload_acl(_Opts) ->
ok.
The plugin could register callbacks for hooks. The hooks will be run by the broker when a client con-
nected/disconnected, a topic subscribed/unsubscribed or a message published/delivered:
Name Description
client.connected Run when a client connected to the broker successfully
client.subscribe Run before a client subscribes topics
client.unsubscribe Run when a client unsubscribes topics
session.subscribed Run after a client subscribed a topic
session.unsubscribed Run after a client unsubscribed a topic
message.publish Run when a message is published
message.delivered Run when a message is delivered
message.acked Run when a message(qos1/2) is acked
client.disconnected Run when a client is disconnnected
emq_plugin_template.erl for example:
emq_cli_demo.erl:
-module(emqttd_cli_demo).
-include_lib("emqttd/include/emqttd_cli.hrl").
-export([cmd/1]).
cmd(_) ->
?USAGE([{"cmd arg1 arg2", "cmd demo"}]).
Create etc/${plugin_name}.conf|config file for the plugin. The EMQ broker supports two type of config syntax:
1. ${plugin_name}.config with erlang syntax:
[
{plugin_name, [
{key, value}
]}
].
plugin_name.key = value
DEPS += plugin_name
dep_plugin_name = git url_of_plugin
{plugin_name, load},
Tuning Guide
Tuning the Linux Kernel, Networking, Erlang VM and the EMQ broker for one million concurrent MQTT connections.
# 2 million system-wide
sysctl -w fs.file-max=2097152
sysctl -w fs.nr_open=2097152
echo 2097152 > /proc/sys/fs/nr_open
ulimit -n 1048576
/etc/sysctl.conf
fs.file-max = 1048576
/etc/security/limits.conf
97
EMQ 2.0 Documentation, Release 2.0.5
Network Tuning
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
Erlang VM Tuning
## Sets the maximum number of simultaneously existing ports for this system
node.max_ports = 1048576
Tune the acceptor pool, max_clients limit and sockopts for TCP listener in etc/emqttd.config:
## TCP Listener
mqtt.listener.tcp = 1883
mqtt.listener.tcp.acceptors = 64
mqtt.listener.tcp.max_clients = 1000000
Client Machine
emqtt_benchmark
Changes
Version 2.1.0-rc.2
Version 2.1.0-rc.1
Version 2.1.0-beta.2
101
EMQ 2.0 Documentation, Release 2.0.5
Version 2.1.0-beta.1
Since 2.1.0 release, we will tag EMQ versions accoding to the Semantic Versioning 2.0.0 principles. And we will
release EMQ versions monthly, odd number releases for bugfix and optimization, and even number releases for bugfix
and new features.
Tuning GC
1. All the WebSocket, Client, Session processes will hiberante and GC after a period of idle time.
2. Add mqtt.conn.force_gc_count configuration to force the Client, Session processes to GC when high message
throughput.
3. Tune the fullsweep_after option of WebSocket, Client, Session processes.
Hooks API
Hooks module now support to register the same function with different tags.
Bugfix
Version 2.1-beta
Version 2.1-beta
EMQ v2.1-beta is now available. We improved the design of Session/Inflight and use one timer to redeliver the inflight
QoS1/2 messages, and improved the GC mechanism of MQTT connection process to reduce CPU usage at the high
rate of messages.
mqtt.client.enable_stats = 60s
mqtt.session.enable_stats = 60s
The missed metrics will be increased when EMQ broker received PUBACK, PUBREC, PUBREL, PUBCOMP
packets from clients, but missing in inflight window:
packets/puback/missed
packets/pubrec/missed
packets/pubrel/missed
packets/pubcomp/missed
Integrate Syslog
## syslog level. Enum: debug, info, notice, warning, error, critical, alert,
emergency
log.syslog.level = error
Upgrade QoS
mqtt.session.upgrade_qos = on
etc/emq.conf Changes
Dashboard Plugin
Overview page: Add missed metrics Client page: Add SendMsg, RecvMsg Fields Session page: DeliverMsgEn-
queueMsg Fields
recon Plugin
reloader Plugin
Version 2.0.7
Version 2.0.6
Version 2.0.5
Version 2.0.4
Version 2.0.3
Version 2.0.2
Version 2.0.1
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
---------
Local Subscription
The Local Subscription will not create global routes on clustered nodes, and only dispatch MQTT messages on local
node.
Usage: subscribe a topic with $local/ prefix.
The EMQ 2.0 adopts erlang.mk and relx tools to build the whole projects on Linux, Unix and Windows.
CoAP Support
The EMQ 2.0 supports CoAP(RFC7252) protocol/gateway now, and supports communication between CoAP, MQTT-
SN and MQTT clients.
CoAP Protocol Plugin: https://github.com/emqtt/emqttd_coap
MQTT-SN Support
The release integrated with cuttlefish library, and adopted a more user-friendly k = v syntax for the new configuration
file:
## Node name
node.name = emqttd@127.0.0.1
...
## Max ClientId Length Allowed.
mqtt.max_clientid_len = 1024
...
The new configuration files will be preprocessed and translated to an 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
Docker Image
We released an official Docker Image for EMQ 2.0. The open source project for Dockerfile: https://github.com/emqtt/
emq_docker.
The EMQ 2.0 fully supports Windows platform. You can run emqttd_ctl command and cluster two nodes on Windows
now.
Plugins
Plugin Description
emq_dashboard Web Dashboard
emq_auth_clientid ClientId Auth Plugin
emq_auth_username Username/Password Auth Plugin
emq_auth_ldap LDAP Auth
emq_auth_http HTTP Auth/ACL Plugin
emq_auth_mysql MySQL Auth/ACL Plugin
emq_auth_pgsql PostgreSQL Auth/ACL Plugin
emq_auth_redis Redis Auth/ACL Plugin
emq_auth_mongo MongoDB Auth/ACL Plugin
emq_mod_presence Presence Module
emq_mod_retainer Retainer Module
emq_mod_rewrite Topic Rewrite Module
emq_mod_subscription Subscription Module
emq_coap CoAP Protocol Plugin
emq_sn MQTT-SN Protocol Plugin
emq_stomp STOMP Protocol Plugin
emq_sockjs STOMP over SockJS Plugin
emq_recon Recon Plugin
emq_reloader Reloader Plugin
emq_plugin_template Template Plugin
Version 2.0-rc.3
Version 2.0-rc.2
node.name = emqttd@127.0.0.1
...
mqtt.listener.tcp = 1883
...
2. Support OS Environments:
EMQ_NODE_NAME
EMQ_NODE_COOKIE
EMQ_MAX_PORTS
EMQ_TCP_PORT
EMQ_SSL_PORT
EMQ_HTTP_PORT
EMQ_HTTPS_PORT
3. Refactor all the modules and plugins, and adopt new configuration syntax.
TODO: issues closed.
Version 2.0-rc.1
BUILD_DEPS = emqttd
dep_emqttd = git https://github.com/emqtt/emqttd emq20
Version 2.0-beta.3
New Features
mosquitto_sub -t '$queue/topic'
mosquitto_sub -t '$share/group/topic'
mosquitto_sub -t '$local/topic'
Bugfix
Version 2.0-beta.2
CoAP Support
Bugfix
Version 2.0-beta.1
Adopt a shortened project name: EMQ(Erlang/Enterprise/Elastic MQTT Broker)E means Erlang/OTP, Enterprise and
Elastic.
In order to iterate the project fast, we will adopt a new release management strategy since 2.0. There will be two or
three Preview Release named beta1, beta2 or beta3, and then one or two Release Candidate named rc1, rc2 before
a Major version is production ready.
We split the emqttd 1.x project into two projects since 2.0-beta1 release to resolve the plugins dependency issue.
A new project named emqttd-relx_ is created and responsible for buiding the emqttd application and the plugins:
The rebar which is used in 1.x release is replaced by erlang.mk and relx tools since 2.0-beta1 release.
You can check the Makefile and relx.config in the release project of the borker: emqttd-relx_ .
Since 2.0-beta1 release the configuration file of the broker and plugins adopt a new syntax like rebar.config and
relx.config:
etc/emqttd.conf for example:
The MQTT-SN Protocol Plugin emqttd_sn has been ready in 2.0-beta1 release. The default UDP port of MQTT-SN is
1884.
Load the plugin:
The plugin of EMQ 2.0 broker is a normal erlang application which depends on and extends emqttd. You can create
a standalone plugin application project, and add it to emqttd-relx_ Makefile as a DEP.
All the plugins config files will be copied to emqttd/etc/plugins/ folder when making emqttd brinary packages in
emqttd-relx_ project:
emqttd/
etc/
modules/
plugins/
emqtt_coap.conf
emqttd.conf
emqttd_auth_http.conf
emqttd_auth_mongo.conf
emqttd_auth_mysql.conf
emqttd_auth_pgsql.conf
emqttd_auth_redis.conf
emqttd_coap.conf
emqttd_dashboard.conf
emqttd_plugin_template.conf
emqttd_recon.conf
emqttd_reloader.conf
emqttd_sn.conf
emqttd_stomp.conf
http://emqtt.io/docs/v2/index.html
Version 1.1.3
Cannot publish payloads with a size of the order 64K using WebSockets (#643)
Optimize the procedures that retrieve the Broker version and Borker description in the tick timer (PR#627)
Fix SSL certfile, keyfile config (#651)
Version 1.1.2
Version 1.1.2
Version 1.1.1
Version 1.1
Highlights
Enhancements
Bugfix
Bugfix: function_clause exception occurs when registering a duplicated authentication module (#542)
Bugfix: ./emqttd_top msg_q result: {init terminating in do_boot,{undef,[{etop,start,[],[]},{init,start_it,1,[]},{init,start_em,1,[]}]}}
(#557)
Tests
Dashboard Plugin
MongoDB Plugin
MySQL Plugin
Postgre Plugin
Redis Plugin
Reloader Plugin
Version 1.0.3
Version 1.0.2
Version 1.0.1
The emqttd 1.0 implements a fully-featured, scalable, distributed and extensible open-source MQTT broker for IoT,
M2M and Mobile applications:
1. Full MQTT V3.1/3.1.1 Protocol Specifications Support
2. Massively scalable - Scaling to 1 million connections on a single server
3. Distributed - Route MQTT Messages among clustered or bridged broker nodes
4. Extensible - LDAP, MySQL, PostgreSQL, Redis Authentication/ACL Plugins
Documentation
http://emqtt.io/docs
http://docs.emqtt.com/
Thanks
Version 0.17.1-beta
Enhancements
Dashboard
Version 0.17.0-beta
Highlights
Enhancements
Tests
Plugins
Version 0.16.0-beta
Highlights
$ ./bin/emqttd_ctl cluster
cluster join <Node> #Join the cluster
cluster leave #Leave the cluster
cluster remove <Node> #Remove the node from cluster
cluster status #Cluster status
Improve the design of Trie and Route, only the wildcard topics stored in Trie.
Common Test to replace EUnit.
Enhancements
Bugfix
Plugins
Version 0.15.0-beta
Highlights
Enhancements
Bugfix
Plugins
Version 0.14.1-beta
Version 0.14.0-beta
Highlights
Scaling to 1.3 Million Concurrent MQTT Connections on a 12 Core, 32G CentOS server.
New PubSub, Router Design (#402). Prepare for scaling to 10 millions on one cluster.
Enhancements
Bugfix
Benchmark
1.3 million concurrent MQTT connections on a 12 Core, 32G CentOS Server, consume about 15G Memory and 200%
CPU.
Version 0.13.1-beta
Version 0.13.0-beta
Highlights
Enhancements
Bugfix
Benchmark
Connections: 250K
Subscribers: 250K
Topics: 50K
Qos1 Messages/Sec In: 4K
Qos1 Messages/Sec Out: 20K
Traffic In(bps): 12M+
Traffic Out(bps): 56M+
Version 0.12.3-beta
Version 0.12.2-beta
Version 0.12.1-beta
Version 0.12.0-beta
Highlights
Enhance the emqttd_ctl module to allow plugins to register new commands (#256)
Add [emqttd_recon plugin](https://github.com/emqtt/emqttd_recon) to debug/optimize the broker (#235)
Add ./bin/emqttd_ctl broker pubsub command to check the status of core pubsub processes
Add ./bin/emqttd_top command(like etop) to show the top msg_q, reductions, memory or runtime processes
rel/files/emqttd.config.production for production deployment(default)
rel/files/emqttd.config.development for development deployment
Enhancements
Qos1/2 messages will not be dropped under unstable mobile network (#264)
emqttd_session:subscribe/2, emqttd_session:unsubscribe/2 APIs should be asynchronous (#292)
etc/emqttd.config: idle_timeout option to close the idle client(socket connected but no CONNECT frame received)
etc/emqttd.config: unack_retry_interval option for redelivering Qos1/2 messages
How to monitor large message_queue_len (#283)
Bugfix
Benchmark
Version 0.11.0-beta
Version 0.10.4-beta
Version 0.10.3-beta
Version 0.10.2-beta
Version 0.10.1-beta
Version 0.10.0-beta
Version 0.9.3-alpha
Version 0.9.2-alpha
Version 0.9.1-alpha
Version 0.9.0-alpha
Version 0.8.6-beta
Version 0.8.5-beta
Version 0.8.4-beta
Version 0.8.3-beta
Version 0.8.2-alpha
Version 0.8.1-alpha
Version 0.8.0-alpha
Version 0.7.1-alpha
Version 0.7.0-alpha
Version 0.6.2-alpha
Version 0.6.1-alpha
Version 0.6.0-alpha
Version 0.5.5-beta
Version 0.5.4-alpha
200K Connections,
30K Messages/Sec,
20Mbps In/Out Traffic,
200K Topics,
200K Subscribers,
Version 0.5.3-alpha
Version 0.5.2-alpha
Version 0.5.1-alpha
Version 0.5.0-alpha
Version 0.4.0-alpha
Version 0.3.4-beta
Version 0.3.3-beta
Version 0.3.2-beta
Version 0.3.1-beta
Version 0.3.0-beta
Version 0.3.0-alpha
Version 0.2.1-beta
Version 0.2.0
Version 0.1.5
Version 0.1.4
Version 0.1.3
Version 0.1.2
Version 0.1.1
Version 0.1.0
Upgrade
Upgrade to 2.0
Upgrade steps:
1. Download and install emqttd-2.0 to the new directory, for example:
Upgrade to 1.1.2
Steps:
1. Download and install emqttd-1.1.2 to the new directory, for example:
137
EMQ 2.0 Documentation, Release 2.0.5
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.
License
139