emq作为一个mqtt的消息broker,可以通过它的相关学习,一方面掌握emq本身的一些功能点,另一方面对于集群系统也有一个更好的了解,Mark起来

说明emqx的配置文件主要由主配置文件etc/emqx.conf以及各种插件配置文件etc/plugins/*.conf组成
附上原版md文件,感兴趣的可以在此基础上编辑

一、几个默认端口

1883: MQTT protocol

8883: MQTT/SSL Protocol

8083: MQTT/WebSocket Protocol

8080: HTTP API

18083: Dashboard Interface

修改etc/emqx.conf里面的这几项

listener.tcp.external = 0.0.0.0:1883
listener.ssl.external = 8883
listener.ws.external = 8083

以及etc/plugins/emqx_management.conf

management.listener.http = 8080

以及etc/plugins/emqx_dashboard.conf里面的这几项

dashboard.listener.http = 18083

注意:emqx中TCP端口4369被epmd(Erlang Port Mapper Daemon,守护进程服务,管理节点名到机器地址的映射)占用,所以单机部署两个emqx这种骚操作应该是不可行的,目前没发现哪里可以配置这个端口号。

二、Erlang VM配置

在emqx.conf中影响emq的最大连接数

node.process_limit:VM的进程数量,一个连接需要两个进程
node.max_ports:VM的最大端口数,一个连接需要一个端口
注:在 Erlang 虚拟机中的 Port 概念并不是 TCP 端口,可以近似的理解为文件句柄

三、cluster集群相关概念(可以作为理解其他集群系统的很好的范本)

集群的概念:一组软硬件协同完成一项任务,并且软硬件通过计算机网络进行通讯。从外部来看,集群被当做一个整体,并且提供某项服务。服务的享受着不需要关心集群内部是交互的细节。集群中能够提供服务的最小的软硬件单元组合称为节点(Node)
集群的几个主要优势:

  • 高可用:单节点的损坏并不会导致整个服务的不可用
  • 负载均衡:通过引入负载均衡服务,集群中的节点不会过载
  • 高性能:相比单机部署,多节点的 EMQ X 集群能够成倍的提升整个系统的连接和消息处理能力。
  • 可扩展性:通过添加节点无需停机的方式来完成扩容

emqx集群中相关概念

节点

emqx集群中的相关节点由唯一节点名做区分,形式为 name@node ,其中 name 由用户决定, node由ip地址或者FQDN(Full Qualified Domain Name)决定,例子

emqx1@192.168.1.165
emqx2@broker1.emqx.io

节点间的通讯方式

这里就直接摘用原文了

EMQ X cluster uses epmd to map the node name to TCP port. If there is firewall on the network please make sure the communication among nodes is allowed.

EMQ X uses magic cookie of Erlang/OTP to verify if the nodes belong to a same cluster. Nodes of a cluster should have same cookie.

The cluster internal connection can be TCPv4 or TCPv6, TLS is supported

集群中的消息处理方式

单个mqtt客户端只能连接到集群中的某个节点上,消息处理归纳为两点

  • 客户端在某个节点上订阅到某条消息的时候会被告知到集群的所有节点
  • 当某个主题下的消息被发布的时候,会被转发到所有有订阅该主题的客户端的节点上(根据主题树和路由表)

所有节点都有一份路由表和主题树的拷贝,路由表的每一项由主题和节点构成,类似于

--------------------------
|             t          |
|            / \         |
|           +   #        |
|         /  \           |
|       x      y         |
--------------------------
| t/+/x -> node1, node3  |
| t/+/y -> node1         |
| t/#   -> node2         |
| t/a   -> node3         |
--------------------------

另外具体某个节点上某个主题被哪个客户端订阅的信息则由节点本地保存

四、集群建立方式

  • 手工方式(以下参数均在emqx.conf中配置)
  • 1.设置节点名(配置项名称为node.name),emqx@s1.emqx.io(emq@192.168.0.10), emqx@s2.emqx.io(emq@192.168.0.20),
    2.设置集群cookie, emqx使用cookie来确认同一集群中的节点,同一集群中的节点必须使用相同的cookie,设置
    node.cookie = emqxsecretcookie
    3.设置集群发现方式为手动 cluster.discovery = manual
    4.利用命令行工具在s1上运行emqx_ctl cluster join emq@s2.emqx.io
    5.查询集群的相关状态,emqx_ctl cluster status
    6.节点移除以及退出则直接查看emqx_ctl命令行工具的提示即可
  • 自动集群方式(以下参数均在emqx.conf中配置)

1、 简介:emqx使用Ekka来实现集群节点自动发现,支持以下几种策略:

- static : 使用静态节点列表
- mcast : 使用UDP组播
- dns : 使用DNS记录
- etcd : 使用etcd服务
- k8s : 使用Kubernetes服务

同时结合Ekka,还提供了自动脑裂愈合以及自动移除宕机节点的功能(貌似是个集群都会有的这两个功能)

static方式:

不需要任何其他网络组件或服务,也不需要网络支持网络IP组播只需,node间只需要可以通过TCP访问即可
同时所有集群节点配置一个完全一样的节点列表
配置集群方式和节点列表即可
集群方式cluster.discovery = static
cluster.static.seeds 配置项为集群列表。列表中的节点名遵从name@host的格式,各个节点名以逗号(,)分隔。
配置完成后,启动各节点即可

其他几种方式,目前用不到,用到的话可以翻看手册,链接
https://docs.emqx.io/tutorial/v3/en/cluster

五、负载均衡配置

为集群配置负载均衡(LB, Load Balancer),主要作用就是平衡网络组件的负载,最小化系统响应时间,最大化服务能力,优化资源利用。对于集群,虽然LB不是必须的,但能给整个系统带来额外的性能,因此经常在集群前面提供一个LB。使用负载可以通过云服务商提供的,或者开源的Nginx或者HAproxy

六、Mqtt协议配置

主要用来配置协议的相关参数
在emqx.conf的## MQTT Protocol模块下

mqtt.max_clientid_len:客户端id长度限制
mqtt.max_packet_size:单个包大小
mqtt.keepalive_backoff:mqtt协议的keepalive参数的补偿,和mqtt协议的连接超时有关,如果'Keepalive * backoff * 2'这么长的时间里面客户端没有响应,则emqx断开此链接

七、zone配置

emq支持基于zone的listener组,根据不同的zone配置不同的选项,多个listener隶属于一个zone,当客户端属于某个zone的时候,客户端匹配该zone中的选项。格式为zone.$name.configItem,具体配置参见https://docs.emqx.io/tutorial/v3/cn/config/zone.html

八、listener配置

listener是emq打开和监听的用来支持相关协议(包括tcp|ssl|ws|wss)的端口,
listener.$protocol.$name = IP:Port 配置监听的端口
listener.tcp.external.zone = zoneName 配置此端口隶属于哪个zone

九、会话以及节点配置

默认就好

十、插件配置

emq基础协议层之外的大多数功能都是通过插件的形式实现的,所有插件都要有一个同名的,以.conf结尾的配置文件

plugins.etc_dir = etc/plugins/      #配置插件配置文件目录
plugins.loaded_file = data/loaded_plugins      #配置启动时加载的插件的名字

十一、流控

emq可以从连接以及发布层面进行速率限制,避免因为客户端的频繁上下线以及单个客户端无限制发布消息造成服务器波动

1.字节流限制
	每项配置的值为 rate,burst 组合,单位是 Bps,超限的连接将挂起,默认不启用该配置:
	    rate: 每秒连接速率;
	    burst: 每秒连接报文大小;
		listener.tcp.external.rate_limit = 1024,4096 :配置 external 域下 TCP 连接速率;

2.连接速率限制
	每秒最大连接数,超限将挂起连接
		listener.tcp.external.max_conn_rate = 1000 : 配置 external 域下 TCP 连接速率;

3.PUB 速率限制
	配置项为 rate,timerange 组合,时间范围支持s,m,h。
		zone.external.publish_limit = 10,1m :配置 external 域下每个客户端 PUB 速率限制。

这几项看了文档也不是很清楚,尤其是第三项本地设置之后完全没有限制啊???

十二、共享订阅

两种主题方式
Topic Prefix 			|		Examples
-----------------------------------------------------
$queue/:topic 			|		sub $queue/up/data
$share/:group/:topic 	|		sub $share/group/up/data

十三、代理订阅功能

给客户端代理订阅一些主题,有代理订阅模块,rest api方式等实现手段

十四、桥接

可以用来衔接其他消息队列服务,如Kafaka