docker-compose部署emqx集群 配置带mysql授权认证

2023-05-16

EMQX 是一款大规模可弹性伸缩的云原生分布式物联网 MQTT 消息服务器。

作为全球最具扩展性的 MQTT 消息服务器,EMQX 提供了高效可靠海量物联网设备连接,能够高性能实时移动与处理消息和事件流数据,帮助您快速构建关键业务的物联网平台与应用。


产品详细介绍:产品概览 | EMQX 5.0 文档https://www.emqx.io/docs/zh/v5.0/


前言

EMQX 是目前全球市场广泛应用的百万级开源 MQTT 消息服务器,全球市场(西欧、北美、印度、中国)累积超 5000 家企业用户,产品环境下部署超 1 万节点,累计下载量超过 50 万,承载 MQTT 连接超 3000 万线

EMQ X 可以作为智能硬件、智能家居、物联网、车联网应用的百万级设备接入平台


基础配置就不介绍了,去官方看详细的配置,本文主要介绍下通过docker-compose的方式部署

  • docker已安装

  • docker-compose已安装

一、单机集群(伪集群)

创建 docker-compose.yaml

version: '3'

services:
  emqx1:
    image: emqx/emqx:4.3.10
    restart: always
    container_name: emqx1-borker1
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 1G
        reservations:
          memory: 1G
    environment:
    - "EMQX_NAME=emqx"
    - "EMQX_HOST=node1.emqx.io"
    - "EMQX_CLUSTER__DISCOVERY=static"
    - "EMQX_CLUSTER__STATIC__SEEDS=emqx@node1.emqx.io, emqx@node2.emqx.io"
    - "EMQX_ALLOW_ANONYMOUS=false"
    - "EMQX_ACL_NOMATCH=deny"
    - "EMQX_BROKER__SHARED_SUBSCRIPTION_STRATEGY=hash_clientid"
    - "EMQX_BROKER__SHARED_DISPATCH_ACK_ENABLED=true"
    - "EMQX_ZONE__EXTERNAL__IDLE_TIMEOUT=60s"
    - "EMQX_AUTH__MYSQL__SERVER=192.168.1.1:3306"
    - "EMQX_AUTH__MYSQL__POOL=8"
    - "EMQX_AUTH__MYSQL__USERNAME=root"
    - "EMQX_AUTH__MYSQL__PASSWORD=root"
    - "EMQX_AUTH__MYSQL__DATABASE=emqx"
    - "EMQX_AUTH__MYSQL__QUERY_TIMEOUT=5s"
    - "EMQX_AUTH__MYSQL__PASSWORD_HASH=sha256"
    - "EMQX_AUTH__MYSQL__AUTH_QUERY=select password as password from mqtt_user where username = '%u' limit 1"
    - "EMQX_AUTH__MYSQL__SUPER_QUERY=SELECT is_superuser from mqtt_user where username = '%u' limit 1"
    - "EMQX_AUTH__MYSQL__ACL_QUERY=select 0 as allow, null as ipaddr, '%u' as username, null as clientid, 3 as access, '/#' as topic union select 1 as allow, null as ipaddr, username, null as clientid, access, topic from mqtt_acl WHERE username = '%u'"
    volumes:
    - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime
    - ./loaded_plugins:/opt/emqx/data/loaded_plugins:z
    ports:
      - 1883:1883
      - 8081:8081
      - 8083:8083
      - 8084:8084
      - 8883:8883
      - 18083:18083
    networks:
      emqx-bridge:
        aliases:
        - node1.emqx.io

  emqx2:
    image: emqx/emqx:4.3.10
    environment:
    - "EMQX_NAME=emqx"
    - "EMQX_HOST=node2.emqx.io"
    - "EMQX_CLUSTER__DISCOVERY=static"
    - "EMQX_CLUSTER__STATIC__SEEDS=emqx@node1.emqx.io, emqx@node2.emqx.io"
    - "EMQX_ALLOW_ANONYMOUS=false"
    - "EMQX_ACL_NOMATCH=deny"
    - "EMQX_BROKER__SHARED_SUBSCRIPTION_STRATEGY=hash_clientid"
    - "EMQX_BROKER__SHARED_DISPATCH_ACK_ENABLED=true"
    - "EMQX_ZONE__EXTERNAL__IDLE_TIMEOUT=60s"
    - "EMQX_AUTH__MYSQL__SERVER=192.168.1.1:3306"
    - "EMQX_AUTH__MYSQL__POOL=8"
    - "EMQX_AUTH__MYSQL__USERNAME=root"
    - "EMQX_AUTH__MYSQL__PASSWORD=root"
    - "EMQX_AUTH__MYSQL__DATABASE=emqx"
    - "EMQX_AUTH__MYSQL__QUERY_TIMEOUT=15s"
    - "EMQX_AUTH__MYSQL__PASSWORD_HASH=sha256"
    - "EMQX_AUTH__MYSQL__AUTH_QUERY=select password_hash as password from mqtt_user where username = '%u' limit 1"
    - "EMQX_AUTH__MYSQL__SUPER_QUERY=SELECT is_superuser from mqtt_user where username = '%u'"
    - "EMQX_AUTH__MYSQL__ACL_QUERY=select 0 as allow, null as ipaddr, '%u' as username, null as clientid, 3 as access, '/#' as topic union select 1 as allow, null as ipaddr, username, null as clientid, access, topic from mqtt_acl WHERE username = '%u'"
    volumes:
    - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime
    - ./loaded_plugins:/opt/emqx/data/loaded_plugins:z
    ports:
      - 1884:1883
    networks:
      emqx-bridge:
        aliases:
        - node2.emqx.io

networks:
  emqx-bridge:
    driver: bridge

loaded_plugins文件:用于替换插件启用配置(启用emqx_auth_mysql插件)

{emqx_management, true}.
{emqx_recon, true}.
{emqx_retainer, true}.
{emqx_dashboard, true}.
{emqx_telemetry, true}.
{emqx_rule_engine, true}.
{emqx_bridge_mqtt, false}.
{emqx_auth_mysql, true}.                  

mysql授权认证表:

CREATE TABLE `iot_mqtt_acl` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'mqtt用户名',
  `topic` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'Topic Filter',
  `access` int DEFAULT NULL COMMENT '访问权限 1: subscribe, 2: publish, 3: pubsub',
  `create_time` datetime DEFAULT NULL COMMENT '创建日期',
  `del_flag` int DEFAULT '0' COMMENT '是否删除 0未删除 1删除',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_username` (`username`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC COMMENT='mqtt的ACL规则表';

CREATE TABLE `iot_mqtt_user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'mqtt用户名',
  `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'mqtt加密的密码',
  `login_pwd` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'mqtt明文的密码',
  `is_superuser` tinyint(1) DEFAULT NULL COMMENT '是否超级用户(1-是,0-否)',
  `create_by` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '创建人',
  `create_time` datetime DEFAULT NULL COMMENT '创建日期',
  `update_by` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '更新人',
  `update_time` datetime DEFAULT NULL COMMENT '更新日期',
  `del_flag` int DEFAULT '0' COMMENT '是否删除 0未删除 1删除',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_username` (`username`) USING BTREE,
  KEY `idx_sn` (`sn`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC COMMENT='mqtt用户表';

 关于日志挂载

可以在yaml文件中配置 ./logs:/opt/emqx/log,说明我们把日志挂载出来了
但是这里有个问题:容器中使用的并不是root用户,如果我们用root用户启动容器,则docker在宿主机上创建的logs目录的属主是 root,那么容器中的服务会没有权限写,有如下两个解决方案:

  • 给logs目录777 权限(不推荐)
  • 修改logs目录属主(推荐)
    一般容器中的用户会映射到宿主机中 用户ID是 1001这个用户。为了保险我们可以自己实测:
    1)创建logs目录给777 权限
    2)启动服务,查看容器在logs目录下创建的文件属主(比如看到是用户A)
    3)停止容器,删除logs目录
    4)重新创建logs目录,将主、组都修改为用户A

启动: docker-compose up -d

注意:最开始没有在docker-compose文件中没有配置限制内容大小等,后面加的;如果使用docker-compose up会有问题(docker-compose 默认的有deploy配置),可以使用这个命令启动:

docker-compose不支持deploy节点配置启动命令:
docker-compose --compatibility up -d

查看启动的容器:

  • web访问
  • URL: http://IP:18083

emqx如果不需要授权的可以干掉授权部分的配置(参考:使用 MySQL 的密码认证 | EMQX 5.0 文档)

二、多态机子集群部署

1. 环境说明(IP是阿里云内网IP,这里只是展示,请自行切换)

节点IP
emqx01192.168.1.1
emqx02192.168.1.2

emqx集群部署

2.1 emqx01

网络需要使用host模式

  • docker-compose.yml 文件
version: '3'

services:
  emqx1:
    image: emqx/emqx:4.3.10
    restart: always
    container_name: emqx1-borker
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 1G
        reservations:
          memory: 1G
    environment:
    - "EMQX_NAME=emqx"
    - "EMQX_HOST=192.168.1.1"
    - "EMQX_NODE_NMAE=emqx@192.168.1.1"
    - "EMQX_CLUSTER__DISCOVERY=static"
    - "EMQX_CLUSTER__STATIC__SEEDS=emqx@192.168.1.1,emqx@192.168.1.2"
    - "EMQX_CLUSTER_AUTOHEAL=on"
    - "EMQX_ALLOW_ANONYMOUS=false" 
    - "EMQX_ACL_NOMATCH=deny"
    - "EMQX_BROKER__SHARED_SUBSCRIPTION_STRATEGY=hash_clientid"
    - "EMQX_BROKER__SHARED_DISPATCH_ACK_ENABLED=true"
    - "EMQX_ZONE__EXTERNAL__IDLE_TIMEOUT=60s"
    - "EMQX_AUTH__MYSQL__SERVER=域名/IP:3306"
    - "EMQX_AUTH__MYSQL__POOL=8"
    - "EMQX_AUTH__MYSQL__USERNAME=root"
    - "EMQX_AUTH__MYSQL__PASSWORD=xxxxx"
    - "EMQX_AUTH__MYSQL__DATABASE=emqx"
    - "EMQX_AUTH__MYSQL__QUERY_TIMEOUT=15s"
    - "EMQX_AUTH__MYSQL__PASSWORD_HASH=sha256"
    - "EMQX_AUTH__MYSQL__AUTH_QUERY=select password as password from mqtt_user where username = '%u' limit 1"
    - "EMQX_AUTH__MYSQL__SUPER_QUERY=SELECT is_superuser from mqtt_user where username = '%u' limit 1"
    - "EMQX_AUTH__MYSQL__ACL_QUERY=select 0 as allow, null as ipaddr, '%u' as username, null as clientid, 3 as access, '/#' as topic union select 1 as allow, null as ipaddr, username, null as clientid, access, topic from mqtt_acl WHERE username = '%u'"
    network_mode: host
    volumes:
    - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime
    - ./loaded_plugins:/opt/emqx/data/loaded_plugins:z
    healthcheck:
      test: ["CMD", "/opt/emqx/bin/emqx_ctl", "status"]
      interval: 5s
      timeout: 25s
      retries: 5
  • 启动
[root@XXXXXX emqx01]# docker-compose --compatibility up -d
  • 查看结果
[root@xxxx emqx01]# docker-compose ps
     Name                   Command                  State       Ports
----------------------------------------------------------------------
emqx1_broker   /usr/bin/docker-entrypoint ...   Up (healthy)

2.2 emqx02

网络需要使用host模式

  • docker-compose.yml 文件
version: '3'

services:
  emqx1:
    image: emqx/emqx:4.3.10
    restart: always
    container_name: emqx2-borker
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 1G
        reservations:
          memory: 1G
    environment:
    - "EMQX_NAME=emqx"
    - "EMQX_HOST=192.168.1.1"
    - "EMQX_NODE_NMAE=emqx@192.168.1.2"
    - "EMQX_CLUSTER__DISCOVERY=static"
    - "EMQX_CLUSTER__STATIC__SEEDS=emqx@192.168.1.1,emqx@192.168.1.2"
    - "EMQX_CLUSTER_AUTOHEAL=on"
    - "EMQX_ALLOW_ANONYMOUS=false" 
    - "EMQX_ACL_NOMATCH=deny"
    - "EMQX_BROKER__SHARED_SUBSCRIPTION_STRATEGY=hash_clientid"
    - "EMQX_BROKER__SHARED_DISPATCH_ACK_ENABLED=true"
    - "EMQX_ZONE__EXTERNAL__IDLE_TIMEOUT=60s"
    - "EMQX_AUTH__MYSQL__SERVER=域名/IP:3306"
    - "EMQX_AUTH__MYSQL__POOL=8"
    - "EMQX_AUTH__MYSQL__USERNAME=root"
    - "EMQX_AUTH__MYSQL__PASSWORD=xxxxx"
    - "EMQX_AUTH__MYSQL__DATABASE=emqx"
    - "EMQX_AUTH__MYSQL__QUERY_TIMEOUT=15s"
    - "EMQX_AUTH__MYSQL__PASSWORD_HASH=sha256"
    - "EMQX_AUTH__MYSQL__AUTH_QUERY=select password as password from mqtt_user where username = '%u' limit 1"
    - "EMQX_AUTH__MYSQL__SUPER_QUERY=SELECT is_superuser from mqtt_user where username = '%u' limit 1"
    - "EMQX_AUTH__MYSQL__ACL_QUERY=select 0 as allow, null as ipaddr, '%u' as username, null as clientid, 3 as access, '/#' as topic union select 1 as allow, null as ipaddr, username, null as clientid, access, topic from mqtt_acl WHERE username = '%u'"
    network_mode: host
    volumes:
    - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime
    - ./loaded_plugins:/opt/emqx/data/loaded_plugins:z
    healthcheck:
      test: ["CMD", "/opt/emqx/bin/emqx_ctl", "status"]
      interval: 5s
      timeout: 25s
      retries: 5
  • 启动
[root@XXXXXX emqx02]# docker-compose --compatibility up -d
  • 查看结果
[root@xxxx emqx02]#  docker-compose ps
     Name                   Command                  State       Ports
----------------------------------------------------------------------
emqx2_broker   /usr/bin/docker-entrypoint ...   Up (healthy)

WEB查看结果:

IP1:18083

IP2:18083


总结

提示:集群和集群后同一个订阅消息花了几天时间,最后才发现是阿里云的内网端口的问题,明明是同一个地区,同一个专有网络,结果发现内网端口不通;最后才知道因为两台服务器安全组不一样。

进入容器查看集群状态: docker exec -it emqx1-borker sh -c "emqx_ctl cluster status"

同一个集群下的客户端,订阅相同主题缺无法收到消息:

4.0+版本,检查5369端口开放

集群方式介绍:

设置集群方式(manual) 手动集群方式是 EMQ X 的默认集群方式。
请在配置文件emqx/etc/emqx.conf中找到以下行并做相应修改:
cluster.discovery = manual 
#-manual:手动加入命令 
#-static:静态节点列表 
#-mcast:IP组播 
#-dns:DNS自动集群 
#-etcd:etcd自动集群 
#-k8s:Kubernetes

最开始集群未成功:还是端口的问题,导致我进容器手动添加:不推荐使用

$ ./bin/emqx_ctl cluster join emqx@s1.emqx.io
Join the cluster successfully.
Cluster status: [{running_nodes,['emqx@s1.emqx.io','emqx@s2.emqx.io']}]

好了:以上就是今天要讲的内容,记录下自己踩过的坑

EMQX产品优势:

  • 开放源码:基于 Apache 2.0 许可证完全开源,自 2013 年起 200+ 开源版本迭代。
  • MQTT 5.0:100% 支持 MQTT 5.0 和 3.x 协议标准,更好的伸缩性、安全性和可靠性。
  • 海量连接:单节点支持 500 万 MQTT 设备连接,集群可扩展至 1 亿并发 MQTT 连接。
  • 高性能:单节点支持每秒实时接收、移动、处理与分发数百万条的 MQTT 消息。
  • 低时延:基于 Erlang/OTP 软实时的运行时系统设计,消息分发与投递时延低于 1 毫秒。
  • 高可用:采用 Masterless 的大规模分布式集群架构,实现系统高可用和水平扩展
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

docker-compose部署emqx集群 配置带mysql授权认证 的相关文章

随机推荐

  • archlinux中navicat无法使用fcitx5输入法

    现象 archlinux中navicat无法使用fcitx5输入法 而我在ubuntu中使用navicat调用fcitx输入法是可以正常使用的 在网上搜索了很久 xff0c 这方面的文章比较少 而我的其他程序输入法又是正常的 解决办法 参考
  • JetBrains Gateway IDEA远程开发

    为什么进行远程开发 xff1f 无论身处何处数秒内连接至远程环境 充分利用远程计算机的强大功能 在任何笔记本电脑上都可以轻松工作 xff0c 无论其性能如何 借助远程计算机的计算资源 xff0c 充分利用最大规模的数据集和代码库 在远程服务
  • ubuntu 22.04安装nvm

    执行安装脚本 span class token function sudo span span class token function apt span span class token function install span spa
  • 手推DNN,CNN池化层,卷积层反向传播

    反向传播算法是神经网络中用来学习的算法 xff0c 从网络的输出一直往输出方向计算梯度来更新网络参数 xff0c 达到学习的目的 xff0c 而因为其传播方向与网络的推理方向相反 xff0c 因此成为反向传播 神经网络有很多种 xff0c
  • 软件架构概念和面向服务的架构

    摘要 软件架构作为软件开发过程的一个重要组成部分 xff0c 有着各种各样的方法和路线图 xff0c 它们都有一些共同的原则 基于架构的方法作为控制系统构建和演化复杂性的一种手段得到了推广 引言 在计算机历史中 xff0c 软件变得越来越复
  • 初识强化学习,什么是强化学习?

    相信很多人都听过 机器学习 和 深度学习 但是听过 强化学习 的人可能没有那么多 那么 什么是强化学习呢 强化学习是机器学习的一个子领域 它可以随着时间的推移自动学习到最优的策略 在我们不断变化的纷繁复杂的世界里 从更广的角度来看 即使是单
  • 强化学习形式与关系

    在强化学习中有这么几个术语 智能体 Agent 环境 Environment 动作 Action 奖励 Reward 状态 State 有些地方称作观察 Observation 奖励 Reward 在强化学习中 奖励是一个标量 它是从环境中
  • 多层网络和反向传播笔记

    在我之前的博客中讲到了感知器 xff08 感知器 xff09 xff0c 它是用于线性可分模式分类的最简单的神经网络模型 xff0c 单个感知器只能表示线性的决策面 xff0c 而反向传播算法所学习的多层网络能够表示种类繁多的非线性曲面 对
  • 在Kaggle手写数字数据集上使用Spark MLlib的朴素贝叶斯模型进行手写数字识别

    昨天我在Kaggle上下载了一份用于手写数字识别的数据集 xff0c 想通过最近学习到的一些方法来训练一个模型进行手写数字识别 这些数据集是从28 28像素大小的手写数字灰度图像中得来 xff0c 其中训练数据第一个元素是具体的手写数字 x
  • Ros使用自定义数据通讯无法收到消息的分析和解决

    nbsp 在实际的开发中 和别的模块定义了自定义的 数据类型 比如 userMsg msg文件 Header header int32 nState string strImageName string strYamlName 报错和原因
  • 在Kaggle手写数字数据集上使用Spark MLlib的RandomForest进行手写数字识别

    昨天我使用Spark MLlib的朴素贝叶斯进行手写数字识别 xff0c 准确率在0 83左右 xff0c 今天使用了RandomForest来训练模型 xff0c 并进行了参数调优 首先来说说RandomForest 训练分类器时使用到的
  • 遇见AI,从Java到数据挖掘。

    在上小学的时候就听说过AI xff0c 人工智能 xff0c 那个时候我对人工智能的感受都来自于各类影视作品 xff0c 类人的外表 xff0c 能听说读写 xff0c 有情感 xff0c 会思考 所以那个时候的我将人工智能想象成和人类相似
  • PyTorch模型保存与加载

    torch save xff1a 保存序列化的对象到磁盘 xff0c 使用了Python的pickle进行序列化 xff0c 模型 张量 所有对象的字典 torch load xff1a 使用了pickle的unpacking将pickle
  • ROS和ROS2.0到底该用哪个呢?

    很多朋友经常问ROS1 0 下文简称ROS 和ROS2 0我到底该学习 使用哪个呢 欢迎拍砖讨论 但若是因此对您的项目或产品造成了损失 本人不负任何责任 我先给出个人的观点 再说明其中原因 对于大众学习者 普通开发者 机器人算法开发者 在2
  • C++ Primer第五版_第一章习题答案

    文章目录 题目概览1 1 编译器文档1 2 错误标识1 3 Hello World1 4 两数相乘1 5 独立语句1 6 程序合法性1 7 不正确的嵌套注释1 8 语句合法性1 9 50到100的整数相加1 10 递减顺序打印10到0之间的
  • C++ Primer第五版_第十五章习题答案(11~20)

    文章目录 练习15 11练习15 12练习15 13练习15 14练习15 15Disc quote hBulk quote h 练习15 16练习15 17练习15 18练习15 19练习15 20 练习15 11 为你的 Quote 类
  • ROS机器人操作系统(roscpp)

    1 Client Library与roscpp 1 1 Client Library简介 ROS为机器人开发者们提供了不同语言的编程接口 比如C 接口叫做roscpp Python接口叫做rospy Java接口叫做rosjava 尽管语言
  • OpenCVSharp之ArucoSample例程

    ArUco xff1a 是一个根据预设黑白Markers来估计相机位姿的开源库 该库由C 43 43 编写 xff0c 运行速度很快 已被应用在了机器人导航 增强现实和目标姿态估计中 DetectorParameters xff1a 检测标
  • PUTTY连接虚拟机linux,出现connection refused的解决方法!

    先确认是否已经给UBUNTU安装了SSHD 在终端输入SSHD 若未安装 xff0c 按提示安装 sudo apt get install openssh server 若出现以下问题 xff1a E Could not get lock
  • docker-compose部署emqx集群 配置带mysql授权认证

    EMQX 是一款大规模可弹性伸缩的云原生分布式物联网 MQTT 消息服务器 作为全球最具扩展性的 MQTT 消息服务器 xff0c EMQX 提供了高效可靠海量物联网设备连接 xff0c 能够高性能实时移动与处理消息和事件流数据 xff0c