commit 9adaacb84d41a3da4b3e250d373cff6af1e10fef Author: 张建平 Date: Sat Feb 22 18:03:33 2025 +0800 feat: 初始化项目结构 添加 README.MD、images目录、single_node目录及其配置文件,multi_node目录及各节点配置。 diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..35a6362 --- /dev/null +++ b/README.MD @@ -0,0 +1,110 @@ +# EMQX Cluster 配置说明 + +![集群概览](images/集群概览.png) + +本文档描述了如何根据单节点和多节点的配置部署 EMQX 集群。本文档适用于两种场景: + +- **单节点配置**:适用于测试或小规模部署,在目录 [single_node] 中包含所有必要的配置和证书。 +- **多节点配置**:适用于集群部署,在目录 [multi_node] 中提供多个节点的配置示例,每个节点拥有独立的配置文件和 Docker Compose 配置。 + +--- + +## 单节点配置 + +单节点部署的相关文件位于目录 **single_node**,主要文件包括: + +- **docker-compose.yaml**:Docker Compose 部署文件,用于启动 EMQX 及其依赖服务。 +- **nginx.conf**:Nginx 负载均衡配置,可选用于反向代理。 +- **api_key.conf**:API 密钥配置文件。 +- **certs/**:存放 SSL/TLS 证书文件,包含: + - cacert.pem + - cert.pem + - client-cert.pem + - client-key.pem + - key.pem + +### 部署步骤 + +1. 进入 `single_node` 目录: + ``` + cd single_node + ``` +2. 根据需要检查并修改配置文件(如 API 密钥、证书等)。 +3. 使用 Docker Compose 启动服务: + ``` + docker-compose up -d + ``` +4. 如使用 Nginx 提供反向代理,确保 `nginx.conf` 中的配置与实际环境匹配。 + +--- + +## 多节点配置 + +多节点部署适用于 EMQX 集群环境,相关配置位于目录 **multi_node**,包含以下内容: + +- **nginx.conf**:用于集群中负载均衡和反向代理的 Nginx 配置。 +- 子目录分别对应各个节点配置,目前包含: + - **node20.50/** + - docker-compose.yaml + - api_key.conf + - **node20.220/** + - docker-compose.yaml + - api_key.conf + - **node22.85/** + - docker-compose.yaml + - api_key.conf + +### 部署步骤 + +1. 检查各节点目录下的配置文件,确保 API 密钥、证书路径等配置正确。 +2. 对于每个节点,进入相应的目录并启动服务,例如: + ``` + cd multi_node/node20.50 + docker-compose up -d + ``` + 对其他节点重复上述步骤。 +3. 部署完各节点服务后,如使用 Nginx 执行负载均衡,请确保 `multi_node/nginx.conf` 配置准确,并启动 Nginx 服务: + ``` + # 修改 nginx.conf 配置后,启动或重启 Nginx 服务 + nginx -c $(pwd)/multi_node/nginx.conf + ``` + +--- + +## 注意事项 + +- 请根据实际环境修改各配置文件中的关键信息(如 API 密钥、证书路径、端口号等)。 +- 在集群部署环境中,确保各节点之间网络互通,并按实际需求配置负载均衡器。 +- 建议在修改配置后,先测试单节点部署,再逐步扩展到多节点集群。 + +--- + +## EMQX 测试工具 + +EMQX 测试工具采用 mqttx 进行压力测试,支持以下测试场景: + +- **压测海量链接**: + 使用以下命令测试大量连接: + ``` + mqttx bench conn -c 5000 + ``` + +- **批量发布消息**: + 使用以下命令进行批量消息发布: + ``` + mqttx bench pub -c 5000 -t bench/%i + ``` + +- **批量订阅消息**: + 使用以下命令进行批量消息订阅: + ``` + mqttx bench sub -c 5000 -t bench/%i + ``` + +详细使用说明请参考:[mqttx CLI 文档](https://mqttx.app/docs/cli/get-started) + +--- + +本文档旨在为用户提供一个清晰的部署及测试指导,可根据项目需求进行适当调整。更多使用说明和排查问题的细节,请参考各目录内附带的 README 文件或官方文档。 + +2025年2月22日 diff --git a/images/1节点发布2节点订阅.png b/images/1节点发布2节点订阅.png new file mode 100644 index 0000000..ee4e491 Binary files /dev/null and b/images/1节点发布2节点订阅.png differ diff --git a/images/单节点发布订阅.png b/images/单节点发布订阅.png new file mode 100644 index 0000000..a97d7ff Binary files /dev/null and b/images/单节点发布订阅.png differ diff --git a/images/多节点链接.png b/images/多节点链接.png new file mode 100644 index 0000000..852d593 Binary files /dev/null and b/images/多节点链接.png differ diff --git a/images/集群概览.png b/images/集群概览.png new file mode 100644 index 0000000..05b614e Binary files /dev/null and b/images/集群概览.png differ diff --git a/multi_node/README.MD b/multi_node/README.MD new file mode 100644 index 0000000..4dc46e8 --- /dev/null +++ b/multi_node/README.MD @@ -0,0 +1,104 @@ +# EMQX 集群配置指南 + +该目录用于模拟 EMQX 集群环境。每个子文件夹代表集群中的一个服务器节点,节点文件夹包括: +- **node20.220/** +- **node20.50/** +- **node22.85/** + +## 主要功能 + +各节点将使用独立的配置文件(例如各节点下的 `api_key.conf` 和 `docker-compose.yaml`),通过 Docker Compose 方式启动 EMQX 服务,并构建一个集群环境以实现消息同步与负载均衡。 + +## nginx 负载均衡配置 + +新增的 nginx.conf 文件用于配置负载均衡,支持 TCP、TLS 以及 WebSocket 协议转发。请根据实际部署环境调整证书路径与后端服务配置。 + +## DNS 负载均衡配置 + +除了nginx方案,另一种常见方案是采用DNS服务器进行负载均衡。DNS负载均衡通过在DNS解析记录中配置多个后端节点,实现流量的轮询分发。此方案配置简单,无需额外的反向代理软件,但在健康检查和故障切换方面存在不足,并且受DNS缓存影响,更新较慢。 + +## 端口要求 + +确保你的服务器或虚拟机开放以下端口,以便 EMQX 正常运行及集群节点间的通信: + +- **EMQX 客户端端口**(用于 MQTT/WS/HTTPS 协议接入): + - 1883 + - 8083 + - 8084 + - 8883 + - 18083 + +- **集群同步端口**(用于节点间状态同步与集群通信): + - 4370 + - 5369 + - 5370 + +## 发布订阅测试 + +使用 MQTTX 工具,可以分别从不同节点发起发布和订阅请求,验证不同节点之间的消息传递。测试结果显示,三个节点均能实现消息的成功发布与订阅,证明集群内的消息同步功能正常。 + +## 控制台访问 + +任意节点均可通过管理端口(例如,访问 `http://<节点IP>:18083`)进入 EMQX 控制台。通过控制台可以监控集群状态、管理配置及进行其他操作,不必限定于单一节点。 + +![集群概览](../images/集群概览.png) + +## 启动集群 + +1. 分别进入各节点目录,例如 `node20.220/`、`node20.50/` 或 `node22.85/`。 +2. 检查并配置各节点下的 `api_key.conf` 文件,确保各节点使用正确的认证信息。 +3. 启动 Docker Compose 服务: + ```bash + docker-compose up -d + ``` +4. 各节点将自动相互发现并建立集群,完成后即可通过任意节点的管理端口(如 18083)访问 EMQX 管理界面。 + +## 注意事项 + +- 请确保所有要求的端口在宿主机或虚拟机中均已开放,避免防火墙阻止集群内部通信。 +- 集群节点配置应保持一致,某些配置如集群名称和共享认证方式应统一设置。 +- 若在启动过程中遇到问题,请检查各节点日志信息以定位问题。 + +## 负载均衡方案对比及推荐 + +### nginx 负载均衡方案 +优势: +- 支持TCP、TLS及WebSocket协议; +- 支持健康检测和故障转移; +- 可灵活配置转发规则; +- 高性能且成熟稳定。 + +劣势: +- 需要额外配置nginx服务及证书管理; +- 配置较复杂,需针对不同协议单独调优; + +### DNS 负载均衡方案 +优势: +- 配置简单,无需额外软件安装; +- 实现多节点轮询较为容易; + +劣势: +- 缺乏实时健康检查能力; +- 更新较慢,受DNS缓存影响,故障切换不够及时; + +### 推荐方案 +综合对比,推荐采用nginx负载均衡方案以实现更高效、稳定的负载分发和故障切换,适合对性能和可靠性要求较高的生产环境。 + +按照以上说明配置后,即可启动并运行一个基于 Docker 的 EMQX 集群。 + + +--- + +## EMQX测试 + +### 多节点链接 + +![多节点链接](../images/多节点链接.png) + +### 单节点发布订阅 + +![单节点发布订阅](../images/单节点发布订阅.png) + +### 多节点发布订阅 + +![1节点发布2节点订阅](../images/1节点发布2节点订阅.png) diff --git a/multi_node/certs/cacert.pem b/multi_node/certs/cacert.pem new file mode 100644 index 0000000..604fd23 --- /dev/null +++ b/multi_node/certs/cacert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDUTCCAjmgAwIBAgIJAPPYCjTmxdt/MA0GCSqGSIb3DQEBCwUAMD8xCzAJBgNV +BAYTAkNOMREwDwYDVQQIDAhoYW5nemhvdTEMMAoGA1UECgwDRU1RMQ8wDQYDVQQD +DAZSb290Q0EwHhcNMjAwNTA4MDgwNjUyWhcNMzAwNTA2MDgwNjUyWjA/MQswCQYD +VQQGEwJDTjERMA8GA1UECAwIaGFuZ3pob3UxDDAKBgNVBAoMA0VNUTEPMA0GA1UE +AwwGUm9vdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzcgVLex1 +EZ9ON64EX8v+wcSjzOZpiEOsAOuSXOEN3wb8FKUxCdsGrsJYB7a5VM/Jot25Mod2 +juS3OBMg6r85k2TWjdxUoUs+HiUB/pP/ARaaW6VntpAEokpij/przWMPgJnBF3Ur +MjtbLayH9hGmpQrI5c2vmHQ2reRZnSFbY+2b8SXZ+3lZZgz9+BaQYWdQWfaUWEHZ +uDaNiViVO0OT8DRjCuiDp3yYDj3iLWbTA/gDL6Tf5XuHuEwcOQUrd+h0hyIphO8D +tsrsHZ14j4AWYLk1CPA6pq1HIUvEl2rANx2lVUNv+nt64K/Mr3RnVQd9s8bK+TXQ +KGHd2Lv/PALYuwIDAQABo1AwTjAdBgNVHQ4EFgQUGBmW+iDzxctWAWxmhgdlE8Pj +EbQwHwYDVR0jBBgwFoAUGBmW+iDzxctWAWxmhgdlE8PjEbQwDAYDVR0TBAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAQEAGbhRUjpIred4cFAFJ7bbYD9hKu/yzWPWkMRa +ErlCKHmuYsYk+5d16JQhJaFy6MGXfLgo3KV2itl0d+OWNH0U9ULXcglTxy6+njo5 +CFqdUBPwN1jxhzo9yteDMKF4+AHIxbvCAJa17qcwUKR5MKNvv09C6pvQDJLzid7y +E2dkgSuggik3oa0427KvctFf8uhOV94RvEDyqvT5+pgNYZ2Yfga9pD/jjpoHEUlo +88IGU8/wJCx3Ds2yc8+oBg/ynxG8f/HmCC1ET6EHHoe2jlo8FpU/SgGtghS1YL30 +IWxNsPrUP+XsZpBJy/mvOhE5QXo6Y35zDqqj8tI7AGmAWu22jg== +-----END CERTIFICATE----- diff --git a/multi_node/certs/cert.pem b/multi_node/certs/cert.pem new file mode 100644 index 0000000..092390b --- /dev/null +++ b/multi_node/certs/cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEzCCAfugAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJDTjER +MA8GA1UECAwIaGFuZ3pob3UxDDAKBgNVBAoMA0VNUTEPMA0GA1UEAwwGUm9vdENB +MB4XDTIwMDUwODA4MDcwNVoXDTMwMDUwNjA4MDcwNVowPzELMAkGA1UEBhMCQ04x +ETAPBgNVBAgMCGhhbmd6aG91MQwwCgYDVQQKDANFTVExDzANBgNVBAMMBlNlcnZl +cjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALNeWT3pE+QFfiRJzKmn +AMUrWo3K2j/Tm3+Xnl6WLz67/0rcYrJbbKvS3uyRP/stXyXEKw9CepyQ1ViBVFkW +Aoy8qQEOWFDsZc/5UzhXUnb6LXr3qTkFEjNmhj+7uzv/lbBxlUG1NlYzSeOB6/RT +8zH/lhOeKhLnWYPXdXKsa1FL6ij4X8DeDO1kY7fvAGmBn/THh1uTpDizM4YmeI+7 +4dmayA5xXvARte5h4Vu5SIze7iC057N+vymToMk2Jgk+ZZFpyXrnq+yo6RaD3ANc +lrc4FbeUQZ5a5s5Sxgs9a0Y3WMG+7c5VnVXcbjBRz/aq2NtOnQQjikKKQA8GF080 +BQkCAwEAAaMaMBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwDQYJKoZIhvcNAQEL +BQADggEBAJefnMZpaRDHQSNUIEL3iwGXE9c6PmIsQVE2ustr+CakBp3TZ4l0enLt +iGMfEVFju69cO4oyokWv+hl5eCMkHBf14Kv51vj448jowYnF1zmzn7SEzm5Uzlsa +sqjtAprnLyof69WtLU1j5rYWBuFX86yOTwRAFNjm9fvhAcrEONBsQtqipBWkMROp +iUYMkRqbKcQMdwxov+lHBYKq9zbWRoqLROAn54SRqgQk6c15JdEfgOOjShbsOkIH +UhqcwRkQic7n1zwHVGVDgNIZVgmJ2IdIWBlPEC7oLrRrBD/X1iEEXtKab6p5o22n +KB5mN+iQaE+Oe2cpGKZJiJRdM+IqDDQ= +-----END CERTIFICATE----- diff --git a/multi_node/certs/client-cert.pem b/multi_node/certs/client-cert.pem new file mode 100644 index 0000000..09d8552 --- /dev/null +++ b/multi_node/certs/client-cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEzCCAfugAwIBAgIBATANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJDTjER +MA8GA1UECAwIaGFuZ3pob3UxDDAKBgNVBAoMA0VNUTEPMA0GA1UEAwwGUm9vdENB +MB4XDTIwMDUwODA4MDY1N1oXDTMwMDUwNjA4MDY1N1owPzELMAkGA1UEBhMCQ04x +ETAPBgNVBAgMCGhhbmd6aG91MQwwCgYDVQQKDANFTVExDzANBgNVBAMMBkNsaWVu +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMy4hoksKcZBDbY680u6 +TS25U51nuB1FBcGMlF9B/t057wPOlxF/OcmbxY5MwepS41JDGPgulE1V7fpsXkiW +1LUimYV/tsqBfymIe0mlY7oORahKji7zKQ2UBIVFhdlvQxunlIDnw6F9popUgyHt +dMhtlgZK8oqRwHxO5dbfoukYd6J/r+etS5q26sgVkf3C6dt0Td7B25H9qW+f7oLV +PbcHYCa+i73u9670nrpXsC+Qc7Mygwa2Kq/jwU+ftyLQnOeW07DuzOwsziC/fQZa +nbxR+8U9FNftgRcC3uP/JMKYUqsiRAuaDokARZxVTV5hUElfpO6z6/NItSDvvh3i +eikCAwEAAaMaMBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwDQYJKoZIhvcNAQEL +BQADggEBABchYxKo0YMma7g1qDswJXsR5s56Czx/I+B41YcpMBMTrRqpUC0nHtLk +M7/tZp592u/tT8gzEnQjZLKBAhFeZaR3aaKyknLqwiPqJIgg0pgsBGITrAK3Pv4z +5/YvAJJKgTe5UdeTz6U4lvNEux/4juZ4pmqH4qSFJTOzQS7LmgSmNIdd072rwXBd +UzcSHzsJgEMb88u/LDLjj1pQ7AtZ4Tta8JZTvcgBFmjB0QUi6fgkHY6oGat/W4kR +jSRUBlMUbM/drr2PVzRc2dwbFIl3X+ZE6n5Sl3ZwRAC/s92JU6CPMRW02muVu6xl +goraNgPISnrbpR6KjxLZkVembXzjNNc= +-----END CERTIFICATE----- diff --git a/multi_node/certs/client-key.pem b/multi_node/certs/client-key.pem new file mode 100644 index 0000000..2b3f30c --- /dev/null +++ b/multi_node/certs/client-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAzLiGiSwpxkENtjrzS7pNLblTnWe4HUUFwYyUX0H+3TnvA86X +EX85yZvFjkzB6lLjUkMY+C6UTVXt+mxeSJbUtSKZhX+2yoF/KYh7SaVjug5FqEqO +LvMpDZQEhUWF2W9DG6eUgOfDoX2milSDIe10yG2WBkryipHAfE7l1t+i6Rh3on+v +561LmrbqyBWR/cLp23RN3sHbkf2pb5/ugtU9twdgJr6Lve73rvSeulewL5BzszKD +BrYqr+PBT5+3ItCc55bTsO7M7CzOIL99BlqdvFH7xT0U1+2BFwLe4/8kwphSqyJE +C5oOiQBFnFVNXmFQSV+k7rPr80i1IO++HeJ6KQIDAQABAoIBAGWgvPjfuaU3qizq +uti/FY07USz0zkuJdkANH6LiSjlchzDmn8wJ0pApCjuIE0PV/g9aS8z4opp5q/gD +UBLM/a8mC/xf2EhTXOMrY7i9p/I3H5FZ4ZehEqIw9sWKK9YzC6dw26HabB2BGOnW +5nozPSQ6cp2RGzJ7BIkxSZwPzPnVTgy3OAuPOiJytvK+hGLhsNaT+Y9bNDvplVT2 +ZwYTV8GlHZC+4b2wNROILm0O86v96O+Qd8nn3fXjGHbMsAnONBq10bZS16L4fvkH +5G+W/1PeSXmtZFppdRRDxIW+DWcXK0D48WRliuxcV4eOOxI+a9N2ZJZZiNLQZGwg +w3A8+mECgYEA8HuJFrlRvdoBe2U/EwUtG74dcyy30L4yEBnN5QscXmEEikhaQCfX +Wm6EieMcIB/5I5TQmSw0cmBMeZjSXYoFdoI16/X6yMMuATdxpvhOZGdUGXxhAH+x +xoTUavWZnEqW3fkUU71kT5E2f2i+0zoatFESXHeslJyz85aAYpP92H0CgYEA2e5A +Yozt5eaA1Gyhd8SeptkEU4xPirNUnVQHStpMWUb1kzTNXrPmNWccQ7JpfpG6DcYl +zUF6p6mlzY+zkMiyPQjwEJlhiHM2NlL1QS7td0R8ewgsFoyn8WsBI4RejWrEG9td +EDniuIw+pBFkcWthnTLHwECHdzgquToyTMjrBB0CgYEA28tdGbrZXhcyAZEhHAZA +Gzog+pKlkpEzeonLKIuGKzCrEKRecIK5jrqyQsCjhS0T7ZRnL4g6i0s+umiV5M5w +fcc292pEA1h45L3DD6OlKplSQVTv55/OYS4oY3YEJtf5mfm8vWi9lQeY8sxOlQpn +O+VZTdBHmTC8PGeTAgZXHZUCgYA6Tyv88lYowB7SN2qQgBQu8jvdGtqhcs/99GCr +H3N0I69LPsKAR0QeH8OJPXBKhDUywESXAaEOwS5yrLNP1tMRz5Vj65YUCzeDG3kx +gpvY4IMp7ArX0bSRvJ6mYSFnVxy3k174G3TVCfksrtagHioVBGQ7xUg5ltafjrms +n8l55QKBgQDVzU8tQvBVqY8/1lnw11Vj4fkE/drZHJ5UkdC1eenOfSWhlSLfUJ8j +ds7vEWpRPPoVuPZYeR1y78cyxKe1GBx6Wa2lF5c7xjmiu0xbRnrxYeLolce9/ntp +asClqpnHT8/VJYTD7Kqj0fouTTZf0zkig/y+2XERppd8k+pSKjUCPQ== +-----END RSA PRIVATE KEY----- diff --git a/multi_node/certs/key.pem b/multi_node/certs/key.pem new file mode 100644 index 0000000..6c33821 --- /dev/null +++ b/multi_node/certs/key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAs15ZPekT5AV+JEnMqacAxStajcraP9Obf5eeXpYvPrv/Stxi +sltsq9Le7JE/+y1fJcQrD0J6nJDVWIFUWRYCjLypAQ5YUOxlz/lTOFdSdvotevep +OQUSM2aGP7u7O/+VsHGVQbU2VjNJ44Hr9FPzMf+WE54qEudZg9d1cqxrUUvqKPhf +wN4M7WRjt+8AaYGf9MeHW5OkOLMzhiZ4j7vh2ZrIDnFe8BG17mHhW7lIjN7uILTn +s36/KZOgyTYmCT5lkWnJeuer7KjpFoPcA1yWtzgVt5RBnlrmzlLGCz1rRjdYwb7t +zlWdVdxuMFHP9qrY206dBCOKQopADwYXTzQFCQIDAQABAoIBAQCuvCbr7Pd3lvI/ +n7VFQG+7pHRe1VKwAxDkx2t8cYos7y/QWcm8Ptwqtw58HzPZGWYrgGMCRpzzkRSF +V9g3wP1S5Scu5C6dBu5YIGc157tqNGXB+SpdZddJQ4Nc6yGHXYERllT04ffBGc3N +WG/oYS/1cSteiSIrsDy/91FvGRCi7FPxH3wIgHssY/tw69s1Cfvaq5lr2NTFzxIG +xCvpJKEdSfVfS9I7LYiymVjst3IOR/w76/ZFY9cRa8ZtmQSWWsm0TUpRC1jdcbkm +ZoJptYWlP+gSwx/fpMYftrkJFGOJhHJHQhwxT5X/ajAISeqjjwkWSEJLwnHQd11C +Zy2+29lBAoGBANlEAIK4VxCqyPXNKfoOOi5dS64NfvyH4A1v2+KaHWc7lqaqPN49 +ezfN2n3X+KWx4cviDD914Yc2JQ1vVJjSaHci7yivocDo2OfZDmjBqzaMp/y+rX1R +/f3MmiTqMa468rjaxI9RRZu7vDgpTR+za1+OBCgMzjvAng8dJuN/5gjlAoGBANNY +uYPKtearBmkqdrSV7eTUe49Nhr0XotLaVBH37TCW0Xv9wjO2xmbm5Ga/DCtPIsBb +yPeYwX9FjoasuadUD7hRvbFu6dBa0HGLmkXRJZTcD7MEX2Lhu4BuC72yDLLFd0r+ +Ep9WP7F5iJyagYqIZtz+4uf7gBvUDdmvXz3sGr1VAoGAdXTD6eeKeiI6PlhKBztF +zOb3EQOO0SsLv3fnodu7ZaHbUgLaoTMPuB17r2jgrYM7FKQCBxTNdfGZmmfDjlLB +0xZ5wL8ibU30ZXL8zTlWPElST9sto4B+FYVVF/vcG9sWeUUb2ncPcJ/Po3UAktDG +jYQTTyuNGtSJHpad/YOZctkCgYBtWRaC7bq3of0rJGFOhdQT9SwItN/lrfj8hyHA +OjpqTV4NfPmhsAtu6j96OZaeQc+FHvgXwt06cE6Rt4RG4uNPRluTFgO7XYFDfitP +vCppnoIw6S5BBvHwPP+uIhUX2bsi/dm8vu8tb+gSvo4PkwtFhEr6I9HglBKmcmog +q6waEQKBgHyecFBeM6Ls11Cd64vborwJPAuxIW7HBAFj/BS99oeG4TjBx4Sz2dFd +rzUibJt4ndnHIvCN8JQkjNG14i9hJln+H3mRss8fbZ9vQdqG+2vOWADYSzzsNI55 +RFY7JjluKcVkp/zCDeUxTU3O6sS+v6/3VE11Cob6OYQx3lN5wrZ3 +-----END RSA PRIVATE KEY----- diff --git a/multi_node/nginx.conf b/multi_node/nginx.conf new file mode 100644 index 0000000..982cf50 --- /dev/null +++ b/multi_node/nginx.conf @@ -0,0 +1,127 @@ +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + +events { + worker_connections 10240; +} + +stream { + + upstream emqxtcp { + server node20.220:1883; + server node20.50:1883; + server node22.85:1883; + } + + upstream emqxtls { + server node20.220:1883 weight=1 max_fails=2; + server node20.50:1883 weight=1 max_fails=2; + server node22.85:1883 weight=2 max_fails=2; + } + + # 多网卡 + # split_clients "$remote_addr$remote_port" $multi_ip { + # 20% 10.211.55.5; + # 20% 10.211.55.20; + # 20% 10.211.55.21; + # 20% 10.211.55.22; + # * 10.211.55.23; + # } + + # TCP + server { + listen 1883; + # Multiple Network Interfaces + #proxy_bind $multi_ip; + + proxy_pass emqxtcp; + # EMQX corresponding listeners need to enable the proxy protocol. + # proxy_protocol on; + } + + # TLS + server { + listen 8883 ssl; + + + # If the certificate doesn't match the hostname, validation needs to be disabled. + ssl_verify_client off; + ssl_verify_depth 0; + + ssl_certificate /etc/nginx/certs/cert.pem; + ssl_certificate_key /etc/nginx/certs/key.pem; + ssl_handshake_timeout 15s; + + proxy_pass emqxtls; + proxy_buffer_size 4k; + + # EMQX corresponding listeners need to enable the proxy protocol. + # proxy_protocol on; + } + +} + +http { + # Nginx status + server { + listen 8888; + + location /status { + stub_status on; + access_log off; + } + } + + upstream emqxws { + server node20.220:8083; + server node20.50:8083; + server node22.85:8083; + } + + # ws + server { + listen 8083; + + location /mqtt { + proxy_pass http://emqxws; + + # websocket连接的Upgrade必须设置为WebSocket,表示在取得服务器响应之后,使用HTTP升级将HTTP协议转换(升级)为WebSocket协议 + proxy_set_header Upgrade $http_upgrade; + # websocket 的Connection必须设置为Upgrade,表示客户端希望连接升级 + proxy_set_header Connection "Upgrade"; + #反向代理真实IP + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header REMOTE-HOST $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + #禁用缓存 + proxy_buffering off; + } + } + + # wss + server { + listen 8084 ssl; + ssl_certificate /etc/nginx/certs/cert.pem; + ssl_certificate_key /etc/nginx/certs/key.pem; + + location /mqtt { + proxy_pass http://emqxws; + + # WebSocket Connection Upgrade must be set to "WebSocket," indicating that after receiving a server response, the HTTP protocol is transformed (upgraded) to the WebSocket protocol. + proxy_set_header Upgrade $http_upgrade; + # WebSocket Connection header must be set to "Upgrade," indicating that the client wishes to upgrade the connection. + proxy_set_header Connection "Upgrade"; + # Proxy Real IP + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header REMOTE-HOST $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # Disable Caching + proxy_buffering off; + } + } +} diff --git a/multi_node/node20.220/api_key.conf b/multi_node/node20.220/api_key.conf new file mode 100644 index 0000000..166bd8f --- /dev/null +++ b/multi_node/node20.220/api_key.conf @@ -0,0 +1 @@ +admin:admin123456 \ No newline at end of file diff --git a/multi_node/node20.220/docker-compose.yaml b/multi_node/node20.220/docker-compose.yaml new file mode 100644 index 0000000..685b8be --- /dev/null +++ b/multi_node/node20.220/docker-compose.yaml @@ -0,0 +1,35 @@ +#version: '3' +services: + emqx: + image: emqx/emqx:5.8.4 + container_name: emqx + hostname: 192.168.20.200 +# networks: +# emqx-net: +# network_mode: host + environment: + - EMQX_NODE__NAME=emqx@192.168.20.200 # 节点名称 + - EMQX_NODE__COOKIE=emqx_dist_cookie # 集群通信cookie + - EMQX_DASHBOARD__DEFAULT_PASSWORD=admin123456 # dashboard密码 + - EMQX_CLUSTER__DISCOVERY_STRATEGY=static # 集群发现策略 可选 manual | static | dns | etcd | k8s | singleton + - EMQX_CLUSTER__STATIC__SEEDS=emqx@192.168.20.200,emqx@192.168.20.50,emqx@192.168.22.85 + - EMQX_API_KEY__BOOTSTRAP_FILE=/opt/emqx/etc/api_key.conf + ports: # 非host模式需要映射所有端口 + - "1883:1883" + - "8083:8083" + - "8084:8084" + - "8883:8883" + - "18083:18083" + - "4370:4370" + - "5370:5370" + - "5369:5369" + volumes: + - ./api_key.conf:/opt/emqx/etc/api_key.conf + +#networks: +# emqx-net: +# driver: bridge +# ipam: +# driver: default +# config: +# - subnet: 192.168.0.0/24 diff --git a/multi_node/node20.50/api_key.conf b/multi_node/node20.50/api_key.conf new file mode 100644 index 0000000..166bd8f --- /dev/null +++ b/multi_node/node20.50/api_key.conf @@ -0,0 +1 @@ +admin:admin123456 \ No newline at end of file diff --git a/multi_node/node20.50/docker-compose.yaml b/multi_node/node20.50/docker-compose.yaml new file mode 100644 index 0000000..4238990 --- /dev/null +++ b/multi_node/node20.50/docker-compose.yaml @@ -0,0 +1,23 @@ +version: '3' +services: + emqx: + image: emqx/emqx:5.8.4 + container_name: emqx + hostname: 192.168.20.50 + network_mode: host # host模式配置 + environment: + - EMQX_NODE__NAME=emqx@192.168.20.50 # 节点名称 + - EMQX_NODE__COOKIE=emqx_dist_cookie + - EMQX_DASHBOARD__DEFAULT_PASSWORD=admin123456 # dashboard密码 + - EMQX_CLUSTER__DISCOVERY_STRATEGY=static # 集群发现策略 可选 manual | static | dns | etcd | k8s | singleton + - EMQX_CLUSTER__STATIC__SEEDS=emqx@192.168.20.220,emqx@192.168.20.50,emqx@192.168.22.85 # 所有的节点都需要配置 + - EMQX_API_KEY__BOOTSTRAP_FILE=/opt/emqx/etc/api_key.conf + ports: # host模式映射参数不生效 + - "1883:1883" + - "8083:8083" + - "8084:8084" + - "8883:8883" + - "18083:18083" + volumes: + - ./api_key.conf:/opt/emqx/etc/api_key.conf + diff --git a/multi_node/node22.85/api_key.conf b/multi_node/node22.85/api_key.conf new file mode 100644 index 0000000..166bd8f --- /dev/null +++ b/multi_node/node22.85/api_key.conf @@ -0,0 +1 @@ +admin:admin123456 \ No newline at end of file diff --git a/multi_node/node22.85/docker-compose.yaml b/multi_node/node22.85/docker-compose.yaml new file mode 100644 index 0000000..2c486ea --- /dev/null +++ b/multi_node/node22.85/docker-compose.yaml @@ -0,0 +1,35 @@ +#version: '3' +services: + emqx: + image: emqx/emqx:5.8.4 + container_name: emqx + hostname: 192.168.22.85 +# networks: +# emqx-net: +# network_mode: host + environment: + - EMQX_NODE__NAME=emqx@192.168.22.85 # 节点名称 + - EMQX_NODE__COOKIE=emqx_dist_cookie # 集群通信cookie + - EMQX_DASHBOARD__DEFAULT_PASSWORD=admin123456 # dashboard密码 + - EMQX_CLUSTER__DISCOVERY_STRATEGY=static # 集群发现策略 可选 manual | static | dns | etcd | k8s | singleton + - EMQX_CLUSTER__STATIC__SEEDS=emqx@192.168.20.200,emqx@192.168.20.50,emqx@192.168.22.85 + - EMQX_API_KEY__BOOTSTRAP_FILE=/opt/emqx/etc/api_key.conf + ports: + - "1883:1883" + - "8083:8083" + - "8084:8084" + - "8883:8883" + - "18083:18083" + - "4370:4370" + - "5370:5370" + - "5369:5369" + volumes: + - ./api_key.conf:/opt/emqx/etc/api_key.conf + +#networks: +# emqx-net: +# driver: bridge +# ipam: +# driver: default +# config: +# - subnet: 192.168.0.0/24 \ No newline at end of file diff --git a/single_node/README.md b/single_node/README.md new file mode 100644 index 0000000..b175b28 --- /dev/null +++ b/single_node/README.md @@ -0,0 +1,70 @@ +# 单节点部署 + +该项目用于模拟 EMQX 集群环境下的单节点部署。通过 Docker Compose 启动三个 EMQX 实例,并利用 Nginx 实现负载均衡和协议代理,帮助你快速体验 EMQX 集群的基本功能。 + +## 目录结构 + +- **api_key.conf**: 存放 EMQX API 密钥配置信息,格式为 `用户名:密码`。 +- **certs/**: 存放 Nginx 使用的 SSL 证书文件,用于支持 TLS/SSL 加密连接。 +- **docker-compose.yaml**: Docker Compose 配置文件,定义了三个 EMQX 实例(emqx1、emqx2、emqx3)及一个 Nginx 服务。 +- **nginx.conf**: Nginx 配置文件,配置了 TCP、TLS、WebSocket、WSS 的代理规则。 +- **README.md**: 本说明文档。 + +## 前置要求 + +- 安装 Docker 和 Docker Compose。 +- 确保主机端口未被其他服务占用(如 18083、1883、8883、8083、8084、8888)。 + +## 部署步骤 + +1. 将本项目克隆或下载到本地。 +2. 在命令行中进入 `single_node` 目录: + ``` + cd single_node + ``` +3. 使用 Docker Compose 启动所有服务: + ``` + docker-compose up -d + ``` +4. 检查容器状态和日志,确保各服务正常启动: + ``` + docker-compose logs -f + ``` +5. 访问 EMQX Dashboard: + - 打开浏览器,访问 [http://localhost:18083](http://localhost:18083) + - 默认用户名为 `admin`,默认密码为 `admin123456` +6. 测试 MQTT 连接: + - 使用 TCP 连接测试端口 1883 或 TLS 连接测试端口 8883。 + - 使用 WebSocket 连接测试端口 8083 或 WSS 连接测试端口 8084(需支持 SSL)。 + +## 文件说明 + +- **docker-compose.yaml** + 定义了三个 EMQX 实例,各实例通过环境变量设置节点名称、集群静态种子以及 Dashboard 默认密码。API 密钥文件通过 volume 挂载到容器内指定位置。 + +- **nginx.conf** + 配置了 Nginx 的 TCP/TLS 和 WebSocket/WSS 代理。 + - **TCP/TLS**:利用 upstream 分发到各 EMQX 实例,支持普通 TCP 连接和 TLS 加密连接。 + - **WebSocket/WSS**:配置了 WebSocket 升级、请求头转发等,确保 MQTT over WebSocket 连接正常工作。 + +- **api_key.conf** + 包含 EMQX 服务所需的 API 密钥信息,格式为 `admin:admin123456`。根据实际需要,可修改为自定义值。 + +## 更新和扩展 + +- 若需扩展成多节点部署,可参照其他目录(如 multi_node)的配置进行修改和扩展。 +- 若需要更新 SSL 证书,请将新的证书文件替换 **certs** 目录中的对应文件,并检查 **nginx.conf** 中的证书路径是否正确。 + +## 常见问题 + +- **容器启动失败或服务异常** + 检查 docker-compose 文件中的环境变量、网络配置及端口映射是否正确;同时确认主机上的相关端口无冲突。 + +- **Nginx 代理错误** + 验证 nginx.conf 文件中的代理和证书配置;确保挂载的证书文件有效且路径正确。 + +## 参考资料 + +- [EMQX 官方网站](https://www.emqx.io) +- [Docker Compose 文档](https://docs.docker.com/compose/) +- [Nginx 官方文档](https://nginx.org) diff --git a/single_node/api_key.conf b/single_node/api_key.conf new file mode 100644 index 0000000..166bd8f --- /dev/null +++ b/single_node/api_key.conf @@ -0,0 +1 @@ +admin:admin123456 \ No newline at end of file diff --git a/single_node/certs/cacert.pem b/single_node/certs/cacert.pem new file mode 100644 index 0000000..604fd23 --- /dev/null +++ b/single_node/certs/cacert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDUTCCAjmgAwIBAgIJAPPYCjTmxdt/MA0GCSqGSIb3DQEBCwUAMD8xCzAJBgNV +BAYTAkNOMREwDwYDVQQIDAhoYW5nemhvdTEMMAoGA1UECgwDRU1RMQ8wDQYDVQQD +DAZSb290Q0EwHhcNMjAwNTA4MDgwNjUyWhcNMzAwNTA2MDgwNjUyWjA/MQswCQYD +VQQGEwJDTjERMA8GA1UECAwIaGFuZ3pob3UxDDAKBgNVBAoMA0VNUTEPMA0GA1UE +AwwGUm9vdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzcgVLex1 +EZ9ON64EX8v+wcSjzOZpiEOsAOuSXOEN3wb8FKUxCdsGrsJYB7a5VM/Jot25Mod2 +juS3OBMg6r85k2TWjdxUoUs+HiUB/pP/ARaaW6VntpAEokpij/przWMPgJnBF3Ur +MjtbLayH9hGmpQrI5c2vmHQ2reRZnSFbY+2b8SXZ+3lZZgz9+BaQYWdQWfaUWEHZ +uDaNiViVO0OT8DRjCuiDp3yYDj3iLWbTA/gDL6Tf5XuHuEwcOQUrd+h0hyIphO8D +tsrsHZ14j4AWYLk1CPA6pq1HIUvEl2rANx2lVUNv+nt64K/Mr3RnVQd9s8bK+TXQ +KGHd2Lv/PALYuwIDAQABo1AwTjAdBgNVHQ4EFgQUGBmW+iDzxctWAWxmhgdlE8Pj +EbQwHwYDVR0jBBgwFoAUGBmW+iDzxctWAWxmhgdlE8PjEbQwDAYDVR0TBAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAQEAGbhRUjpIred4cFAFJ7bbYD9hKu/yzWPWkMRa +ErlCKHmuYsYk+5d16JQhJaFy6MGXfLgo3KV2itl0d+OWNH0U9ULXcglTxy6+njo5 +CFqdUBPwN1jxhzo9yteDMKF4+AHIxbvCAJa17qcwUKR5MKNvv09C6pvQDJLzid7y +E2dkgSuggik3oa0427KvctFf8uhOV94RvEDyqvT5+pgNYZ2Yfga9pD/jjpoHEUlo +88IGU8/wJCx3Ds2yc8+oBg/ynxG8f/HmCC1ET6EHHoe2jlo8FpU/SgGtghS1YL30 +IWxNsPrUP+XsZpBJy/mvOhE5QXo6Y35zDqqj8tI7AGmAWu22jg== +-----END CERTIFICATE----- diff --git a/single_node/certs/cert.pem b/single_node/certs/cert.pem new file mode 100644 index 0000000..092390b --- /dev/null +++ b/single_node/certs/cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEzCCAfugAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJDTjER +MA8GA1UECAwIaGFuZ3pob3UxDDAKBgNVBAoMA0VNUTEPMA0GA1UEAwwGUm9vdENB +MB4XDTIwMDUwODA4MDcwNVoXDTMwMDUwNjA4MDcwNVowPzELMAkGA1UEBhMCQ04x +ETAPBgNVBAgMCGhhbmd6aG91MQwwCgYDVQQKDANFTVExDzANBgNVBAMMBlNlcnZl +cjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALNeWT3pE+QFfiRJzKmn +AMUrWo3K2j/Tm3+Xnl6WLz67/0rcYrJbbKvS3uyRP/stXyXEKw9CepyQ1ViBVFkW +Aoy8qQEOWFDsZc/5UzhXUnb6LXr3qTkFEjNmhj+7uzv/lbBxlUG1NlYzSeOB6/RT +8zH/lhOeKhLnWYPXdXKsa1FL6ij4X8DeDO1kY7fvAGmBn/THh1uTpDizM4YmeI+7 +4dmayA5xXvARte5h4Vu5SIze7iC057N+vymToMk2Jgk+ZZFpyXrnq+yo6RaD3ANc +lrc4FbeUQZ5a5s5Sxgs9a0Y3WMG+7c5VnVXcbjBRz/aq2NtOnQQjikKKQA8GF080 +BQkCAwEAAaMaMBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwDQYJKoZIhvcNAQEL +BQADggEBAJefnMZpaRDHQSNUIEL3iwGXE9c6PmIsQVE2ustr+CakBp3TZ4l0enLt +iGMfEVFju69cO4oyokWv+hl5eCMkHBf14Kv51vj448jowYnF1zmzn7SEzm5Uzlsa +sqjtAprnLyof69WtLU1j5rYWBuFX86yOTwRAFNjm9fvhAcrEONBsQtqipBWkMROp +iUYMkRqbKcQMdwxov+lHBYKq9zbWRoqLROAn54SRqgQk6c15JdEfgOOjShbsOkIH +UhqcwRkQic7n1zwHVGVDgNIZVgmJ2IdIWBlPEC7oLrRrBD/X1iEEXtKab6p5o22n +KB5mN+iQaE+Oe2cpGKZJiJRdM+IqDDQ= +-----END CERTIFICATE----- diff --git a/single_node/certs/client-cert.pem b/single_node/certs/client-cert.pem new file mode 100644 index 0000000..09d8552 --- /dev/null +++ b/single_node/certs/client-cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEzCCAfugAwIBAgIBATANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJDTjER +MA8GA1UECAwIaGFuZ3pob3UxDDAKBgNVBAoMA0VNUTEPMA0GA1UEAwwGUm9vdENB +MB4XDTIwMDUwODA4MDY1N1oXDTMwMDUwNjA4MDY1N1owPzELMAkGA1UEBhMCQ04x +ETAPBgNVBAgMCGhhbmd6aG91MQwwCgYDVQQKDANFTVExDzANBgNVBAMMBkNsaWVu +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMy4hoksKcZBDbY680u6 +TS25U51nuB1FBcGMlF9B/t057wPOlxF/OcmbxY5MwepS41JDGPgulE1V7fpsXkiW +1LUimYV/tsqBfymIe0mlY7oORahKji7zKQ2UBIVFhdlvQxunlIDnw6F9popUgyHt +dMhtlgZK8oqRwHxO5dbfoukYd6J/r+etS5q26sgVkf3C6dt0Td7B25H9qW+f7oLV +PbcHYCa+i73u9670nrpXsC+Qc7Mygwa2Kq/jwU+ftyLQnOeW07DuzOwsziC/fQZa +nbxR+8U9FNftgRcC3uP/JMKYUqsiRAuaDokARZxVTV5hUElfpO6z6/NItSDvvh3i +eikCAwEAAaMaMBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwDQYJKoZIhvcNAQEL +BQADggEBABchYxKo0YMma7g1qDswJXsR5s56Czx/I+B41YcpMBMTrRqpUC0nHtLk +M7/tZp592u/tT8gzEnQjZLKBAhFeZaR3aaKyknLqwiPqJIgg0pgsBGITrAK3Pv4z +5/YvAJJKgTe5UdeTz6U4lvNEux/4juZ4pmqH4qSFJTOzQS7LmgSmNIdd072rwXBd +UzcSHzsJgEMb88u/LDLjj1pQ7AtZ4Tta8JZTvcgBFmjB0QUi6fgkHY6oGat/W4kR +jSRUBlMUbM/drr2PVzRc2dwbFIl3X+ZE6n5Sl3ZwRAC/s92JU6CPMRW02muVu6xl +goraNgPISnrbpR6KjxLZkVembXzjNNc= +-----END CERTIFICATE----- diff --git a/single_node/certs/client-key.pem b/single_node/certs/client-key.pem new file mode 100644 index 0000000..2b3f30c --- /dev/null +++ b/single_node/certs/client-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAzLiGiSwpxkENtjrzS7pNLblTnWe4HUUFwYyUX0H+3TnvA86X +EX85yZvFjkzB6lLjUkMY+C6UTVXt+mxeSJbUtSKZhX+2yoF/KYh7SaVjug5FqEqO +LvMpDZQEhUWF2W9DG6eUgOfDoX2milSDIe10yG2WBkryipHAfE7l1t+i6Rh3on+v +561LmrbqyBWR/cLp23RN3sHbkf2pb5/ugtU9twdgJr6Lve73rvSeulewL5BzszKD +BrYqr+PBT5+3ItCc55bTsO7M7CzOIL99BlqdvFH7xT0U1+2BFwLe4/8kwphSqyJE +C5oOiQBFnFVNXmFQSV+k7rPr80i1IO++HeJ6KQIDAQABAoIBAGWgvPjfuaU3qizq +uti/FY07USz0zkuJdkANH6LiSjlchzDmn8wJ0pApCjuIE0PV/g9aS8z4opp5q/gD +UBLM/a8mC/xf2EhTXOMrY7i9p/I3H5FZ4ZehEqIw9sWKK9YzC6dw26HabB2BGOnW +5nozPSQ6cp2RGzJ7BIkxSZwPzPnVTgy3OAuPOiJytvK+hGLhsNaT+Y9bNDvplVT2 +ZwYTV8GlHZC+4b2wNROILm0O86v96O+Qd8nn3fXjGHbMsAnONBq10bZS16L4fvkH +5G+W/1PeSXmtZFppdRRDxIW+DWcXK0D48WRliuxcV4eOOxI+a9N2ZJZZiNLQZGwg +w3A8+mECgYEA8HuJFrlRvdoBe2U/EwUtG74dcyy30L4yEBnN5QscXmEEikhaQCfX +Wm6EieMcIB/5I5TQmSw0cmBMeZjSXYoFdoI16/X6yMMuATdxpvhOZGdUGXxhAH+x +xoTUavWZnEqW3fkUU71kT5E2f2i+0zoatFESXHeslJyz85aAYpP92H0CgYEA2e5A +Yozt5eaA1Gyhd8SeptkEU4xPirNUnVQHStpMWUb1kzTNXrPmNWccQ7JpfpG6DcYl +zUF6p6mlzY+zkMiyPQjwEJlhiHM2NlL1QS7td0R8ewgsFoyn8WsBI4RejWrEG9td +EDniuIw+pBFkcWthnTLHwECHdzgquToyTMjrBB0CgYEA28tdGbrZXhcyAZEhHAZA +Gzog+pKlkpEzeonLKIuGKzCrEKRecIK5jrqyQsCjhS0T7ZRnL4g6i0s+umiV5M5w +fcc292pEA1h45L3DD6OlKplSQVTv55/OYS4oY3YEJtf5mfm8vWi9lQeY8sxOlQpn +O+VZTdBHmTC8PGeTAgZXHZUCgYA6Tyv88lYowB7SN2qQgBQu8jvdGtqhcs/99GCr +H3N0I69LPsKAR0QeH8OJPXBKhDUywESXAaEOwS5yrLNP1tMRz5Vj65YUCzeDG3kx +gpvY4IMp7ArX0bSRvJ6mYSFnVxy3k174G3TVCfksrtagHioVBGQ7xUg5ltafjrms +n8l55QKBgQDVzU8tQvBVqY8/1lnw11Vj4fkE/drZHJ5UkdC1eenOfSWhlSLfUJ8j +ds7vEWpRPPoVuPZYeR1y78cyxKe1GBx6Wa2lF5c7xjmiu0xbRnrxYeLolce9/ntp +asClqpnHT8/VJYTD7Kqj0fouTTZf0zkig/y+2XERppd8k+pSKjUCPQ== +-----END RSA PRIVATE KEY----- diff --git a/single_node/certs/key.pem b/single_node/certs/key.pem new file mode 100644 index 0000000..6c33821 --- /dev/null +++ b/single_node/certs/key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAs15ZPekT5AV+JEnMqacAxStajcraP9Obf5eeXpYvPrv/Stxi +sltsq9Le7JE/+y1fJcQrD0J6nJDVWIFUWRYCjLypAQ5YUOxlz/lTOFdSdvotevep +OQUSM2aGP7u7O/+VsHGVQbU2VjNJ44Hr9FPzMf+WE54qEudZg9d1cqxrUUvqKPhf +wN4M7WRjt+8AaYGf9MeHW5OkOLMzhiZ4j7vh2ZrIDnFe8BG17mHhW7lIjN7uILTn +s36/KZOgyTYmCT5lkWnJeuer7KjpFoPcA1yWtzgVt5RBnlrmzlLGCz1rRjdYwb7t +zlWdVdxuMFHP9qrY206dBCOKQopADwYXTzQFCQIDAQABAoIBAQCuvCbr7Pd3lvI/ +n7VFQG+7pHRe1VKwAxDkx2t8cYos7y/QWcm8Ptwqtw58HzPZGWYrgGMCRpzzkRSF +V9g3wP1S5Scu5C6dBu5YIGc157tqNGXB+SpdZddJQ4Nc6yGHXYERllT04ffBGc3N +WG/oYS/1cSteiSIrsDy/91FvGRCi7FPxH3wIgHssY/tw69s1Cfvaq5lr2NTFzxIG +xCvpJKEdSfVfS9I7LYiymVjst3IOR/w76/ZFY9cRa8ZtmQSWWsm0TUpRC1jdcbkm +ZoJptYWlP+gSwx/fpMYftrkJFGOJhHJHQhwxT5X/ajAISeqjjwkWSEJLwnHQd11C +Zy2+29lBAoGBANlEAIK4VxCqyPXNKfoOOi5dS64NfvyH4A1v2+KaHWc7lqaqPN49 +ezfN2n3X+KWx4cviDD914Yc2JQ1vVJjSaHci7yivocDo2OfZDmjBqzaMp/y+rX1R +/f3MmiTqMa468rjaxI9RRZu7vDgpTR+za1+OBCgMzjvAng8dJuN/5gjlAoGBANNY +uYPKtearBmkqdrSV7eTUe49Nhr0XotLaVBH37TCW0Xv9wjO2xmbm5Ga/DCtPIsBb +yPeYwX9FjoasuadUD7hRvbFu6dBa0HGLmkXRJZTcD7MEX2Lhu4BuC72yDLLFd0r+ +Ep9WP7F5iJyagYqIZtz+4uf7gBvUDdmvXz3sGr1VAoGAdXTD6eeKeiI6PlhKBztF +zOb3EQOO0SsLv3fnodu7ZaHbUgLaoTMPuB17r2jgrYM7FKQCBxTNdfGZmmfDjlLB +0xZ5wL8ibU30ZXL8zTlWPElST9sto4B+FYVVF/vcG9sWeUUb2ncPcJ/Po3UAktDG +jYQTTyuNGtSJHpad/YOZctkCgYBtWRaC7bq3of0rJGFOhdQT9SwItN/lrfj8hyHA +OjpqTV4NfPmhsAtu6j96OZaeQc+FHvgXwt06cE6Rt4RG4uNPRluTFgO7XYFDfitP +vCppnoIw6S5BBvHwPP+uIhUX2bsi/dm8vu8tb+gSvo4PkwtFhEr6I9HglBKmcmog +q6waEQKBgHyecFBeM6Ls11Cd64vborwJPAuxIW7HBAFj/BS99oeG4TjBx4Sz2dFd +rzUibJt4ndnHIvCN8JQkjNG14i9hJln+H3mRss8fbZ9vQdqG+2vOWADYSzzsNI55 +RFY7JjluKcVkp/zCDeUxTU3O6sS+v6/3VE11Cob6OYQx3lN5wrZ3 +-----END RSA PRIVATE KEY----- diff --git a/single_node/docker-compose.yaml b/single_node/docker-compose.yaml new file mode 100644 index 0000000..8617ce0 --- /dev/null +++ b/single_node/docker-compose.yaml @@ -0,0 +1,58 @@ +services: + emqx1: + image: emqx/emqx:5.8.4 + container_name: emqx1 + hostname: emqx1-cluster.emqx.io + environment: + - EMQX_NODE__NAME=emqx1@emqx1-cluster.emqx.io + - EMQX_CLUSTER__DISCOVERY_STRATEGY=static + - EMQX_DASHBOARD__DEFAULT_PASSWORD=admin123456 # dashboard密码 + - EMQX_CLUSTER__STATIC__SEEDS=emqx1@emqx1-cluster.emqx.io,emqx2@emqx2-cluster.emqx.io,emqx3@emqx3-cluster.emqx.io + - EMQX_API_KEY__BOOTSTRAP_FILE=/opt/emqx/etc/api_key.conf + ports: + - 18083:18083 + volumes: + - ./api_key.conf:/opt/emqx/etc/api_key.conf + + emqx2: + image: emqx/emqx:5.8.4 + container_name: emqx2 + hostname: emqx2-cluster.emqx.io + environment: + - EMQX_NODE__NAME=emqx2@emqx2-cluster.emqx.io + - EMQX_CLUSTER__DISCOVERY_STRATEGY=static + - EMQX_DASHBOARD__DEFAULT_PASSWORD=admin123456 + - EMQX_CLUSTER__STATIC__SEEDS=emqx1@emqx1-cluster.emqx.io,emqx2@emqx2-cluster.emqx.io,emqx3@emqx3-cluster.emqx.io + - EMQX_API_KEY__BOOTSTRAP_FILE=/opt/emqx/etc/api_key.conf + volumes: + - ./api_key.conf:/opt/emqx/etc/api_key.conf + + emqx3: + image: emqx/emqx:5.8.4 + container_name: emqx3 + hostname: emqx3-cluster.emqx.io + environment: + - EMQX_NODE__NAME=emqx3@emqx3-cluster.emqx.io + - EMQX_CLUSTER__DISCOVERY_STRATEGY=static + - EMQX_DASHBOARD__DEFAULT_PASSWORD=admin123456 + - EMQX_CLUSTER__STATIC__SEEDS=emqx1@emqx1-cluster.emqx.io,emqx2@emqx2-cluster.emqx.io,emqx3@emqx3-cluster.emqx.io + - EMQX_API_KEY__BOOTSTRAP_FILE=/opt/emqx/etc/api_key.conf + volumes: + - ./api_key.conf:/opt/emqx/etc/api_key.conf + + nginx: + image: nginx + container_name: nginx + ports: + - 1883:1883 + - 8883:8883 + - 8083:8083 + - 8084:8084 + - 8888:8888 # nginx status + volumes: + - $PWD/nginx.conf:/etc/nginx/nginx.conf + - $PWD/certs:/etc/nginx/certs + +networks: + emqx-net: + driver: emqx-net diff --git a/single_node/nginx.conf b/single_node/nginx.conf new file mode 100644 index 0000000..76ac57a --- /dev/null +++ b/single_node/nginx.conf @@ -0,0 +1,136 @@ +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + +events { + worker_connections 10240; +} + +stream { + + upstream emqxtcp { + server emqx1:1883; + server emqx2:1883; + server emqx3:1883; + } + + upstream emqxtls { + # weight + + # down: Indicates that the current server is temporarily excluded from load balancing. + # weight: Default is 1, where higher weight results in a larger load share. + # max_fails: Maximum number of allowed request failures; defaults to 1. + # fail_timeout: Timeout after which failures are considered; default is 10 seconds. After reaching max_fails failures, the server is paused. + # backup: When other non-backup servers are down or busy, requests are sent to the backup server. + + server emqx1-cluster.emqx.io:1883 weight=1 max_fails=2 ; + server emqx2-cluster.emqx.io:1883 weight=1 max_fails=2 down; + server emqx3-cluster.emqx.io:1883 weight=2 max_fails=2; + } + + # 多网卡 + # split_clients "$remote_addr$remote_port" $multi_ip { + # 20% 10.211.55.5; + # 20% 10.211.55.20; + # 20% 10.211.55.21; + # 20% 10.211.55.22; + # * 10.211.55.23; + # } + + # TCP + server { + listen 1883; + # Multiple Network Interfaces + #proxy_bind $multi_ip; + + proxy_pass emqxtcp; + # EMQX corresponding listeners need to enable the proxy protocol. + # proxy_protocol on; + } + + # TLS + server { + listen 8883 ssl; + + + # If the certificate doesn't match the hostname, validation needs to be disabled. + ssl_verify_client off; + ssl_verify_depth 0; + + ssl_certificate /etc/nginx/certs/cert.pem; + ssl_certificate_key /etc/nginx/certs/key.pem; + ssl_handshake_timeout 15s; + + proxy_pass emqxtls; + proxy_buffer_size 4k; + + # EMQX corresponding listeners need to enable the proxy protocol. + # proxy_protocol on; + } + +} + +http { + # Nginx status + server { + listen 8888; + + location /status { + stub_status on; + access_log off; + } + } + + upstream emqxws { + server emqx1-cluster.emqx.io:8083; + server emqx2-cluster.emqx.io:8083; + server emqx3-cluster.emqx.io:8083; + } + + # ws + server { + listen 8083; + + location /mqtt { + proxy_pass http://emqxws; + + # websocket连接的Upgrade必须设置为WebSocket,表示在取得服务器响应之后,使用HTTP升级将HTTP协议转换(升级)为WebSocket协议 + proxy_set_header Upgrade $http_upgrade; + # websocket 的Connection必须设置为Upgrade,表示客户端希望连接升级 + proxy_set_header Connection "Upgrade"; + #反向代理真实IP + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header REMOTE-HOST $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + #禁用缓存 + proxy_buffering off; + } + } + + # wss + server { + listen 8084 ssl; + ssl_certificate /etc/nginx/certs/cert.pem; + ssl_certificate_key /etc/nginx/certs/key.pem; + + location /mqtt { + proxy_pass http://emqxws; + + # WebSocket Connection Upgrade must be set to "WebSocket," indicating that after receiving a server response, the HTTP protocol is transformed (upgraded) to the WebSocket protocol. + proxy_set_header Upgrade $http_upgrade; + # WebSocket Connection header must be set to "Upgrade," indicating that the client wishes to upgrade the connection. + proxy_set_header Connection "Upgrade"; + # Proxy Real IP + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header REMOTE-HOST $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # Disable Caching + proxy_buffering off; + } + } +} +