尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Docker部署物联网设备管理系统实战:从架构到一键部署

Docker部署物联网设备管理系统实战:从架构到一键部署 为什么用Docker部署物联网系统物联网项目的部署环境五花八门客户机房的服务器、工控机、树莓派、云服务器。每个环境的操作系统版本、依赖库版本都不一样。Docker解决的就是在我电脑上能跑的问题。把你的物联网平台、MQTT Broker、数据库、管理后端全部容器化任何装了Docker的机器上docker-compose up一把启动不用管底层的OS差异。这在实际项目中意味着什么你在公司开发机上调试好的系统部署到客户机房时不用再花两天时间装环境、排依赖。镜像拉下来配置文件改一改跑起来。整体架构一个完整的物联网设备管理系统Docker化后的架构docker-compose.yml ├── emqx # MQTT Broker ├── mysql # 业务数据库 ├── redis # 缓存 ├── go-worker # MQTT消息处理微服务 ├── php-api # 管理API Web界面 └── nginx # 反向代理所有组件跑在同一台服务器上通过Docker内部网络通信。完整docker-compose.ymlversion:3.8services:mysql:image:mysql:8.0container_name:iot_mysqlrestart:alwaysenvironment:MYSQL_ROOT_PASSWORD:${MYSQL_ROOT_PASSWORD}MYSQL_DATABASE:iot_platformports:-3306:3306volumes:-mysql_data:/var/lib/mysql-./sql/init.sql:/docker-entrypoint-initdb.d/init.sqlnetworks:-iot_netredis:image:redis:7-alpinecontainer_name:iot_redisrestart:alwayscommand:redis-server--requirepass ${REDIS_PASSWORD}ports:-6379:6379volumes:-redis_data:/datanetworks:-iot_netemqx:image:emqx/emqx:5.8container_name:iot_emqxrestart:alwaysenvironment:EMQX_NAME:iot_emqxEMQX_HOST:127.0.0.1EMQX_DASHBOARD__DEFAULT_PASSWORD:${EMQX_DASHBOARD_PASSWORD}ports:-1883:1883# MQTT TCP-8083:8083# WebSocket-18083:18083# Dashboardvolumes:-emqx_data:/opt/emqx/datanetworks:-iot_netgo-worker:build:./go-workercontainer_name:iot_workerrestart:alwaysdepends_on:-emqx-mysql-redisenvironment:MQTT_BROKER:emqx:1883MYSQL_DSN:root:${MYSQL_ROOT_PASSWORD}tcp(mysql:3306)/iot_platformREDIS_ADDR:redis:6379REDIS_PASSWORD:${REDIS_PASSWORD}networks:-iot_netphp-api:build:./php-apicontainer_name:iot_apirestart:alwaysdepends_on:-mysql-redisenvironment:DB_HOST:mysqlDB_DATABASE:iot_platformDB_USERNAME:rootDB_PASSWORD:${MYSQL_ROOT_PASSWORD}REDIS_HOST:redisREDIS_PASSWORD:${REDIS_PASSWORD}volumes:-./php-api/src:/var/www/htmlnetworks:-iot_netnginx:image:nginx:alpinecontainer_name:iot_nginxrestart:alwaysdepends_on:-php-apiports:-80:80volumes:-./nginx/default.conf:/etc/nginx/conf.d/default.conf-./php-api/src:/var/www/htmlnetworks:-iot_netvolumes:mysql_data:redis_data:emqx_data:networks:iot_net:driver:bridge.env配置MYSQL_ROOT_PASSWORDyour_secure_password_here REDIS_PASSWORDyour_redis_password_here EMQX_DASHBOARD_PASSWORDyour_emqx_password_hereGo Worker关键代码Go Worker负责订阅MQTT消息处理设备上报数据并写入数据库packagemainimport(encoding/jsonfmtlogosos/signalsyscallmqttgithub.com/eclipse/paho.mqtt.golanggithub.com/joho/godotenv_github.com/go-sql-driver/mysqlgithub.com/gomodule/redigo/redisdatabase/sql)typeTelemetrystruct{DeviceIDstringjson:device_idTempfloat64json:tempHumfloat64json:humVoltagefloat64json:voltage}vardb*sql.DBvarredisConn redis.Connfuncmain(){godotenv.Load()// 初始化MySQLdsn:os.Getenv(MYSQL_DSN)db,_sql.Open(mysql,dsn)deferdb.Close()// 初始化RedisredisAddr:os.Getenv(REDIS_ADDR)redisConn,_redis.Dial(tcp,redisAddr)deferredisConn.Close()// 连接MQTTopts:mqtt.NewClientOptions()opts.AddBroker(os.Getenv(MQTT_BROKER))opts.SetClientID(go-worker-001)opts.OnConnectfunc(c mqtt.Client){c.Subscribe(devices///telemetry,1,handleMessage)log.Println(Subscribed to telemetry topic)}client:mqtt.NewClient(opts)iftoken:client.Connect();token.Wait()token.Error()!nil{log.Fatal(token.Error())}// 等待退出信号sig:make(chanos.Signal,1)signal.Notify(sig,syscall.SIGINT,syscall.SIGTERM)-sig}funchandleMessage(client mqtt.Client,msg mqtt.Message){vart Telemetryiferr:json.Unmarshal(msg.Payload(),t);err!nil{return}// 写入MySQL_,err:db.Exec(INSERT INTO device_telemetry (device_id, temp, hum, voltage, created_at) VALUES (?, ?, ?, ?, NOW()),t.DeviceID,t.Temp,t.Hum,t.Voltage,)iferr!nil{log.Printf(MySQL insert error: %v,err)}// 更新Redis缓存最新状态redisConn.Do(HSET,device:t.DeviceID,temp,t.Temp,hum,t.Hum,voltage,t.Voltage)redisConn.Do(HSET,device:t.DeviceID,last_seen,NOW())// 告警判断ift.Temp80{redisConn.Do(LPUSH,alerts,fmt.Sprintf({device:%s,type:high_temp,value:%.1f},t.DeviceID,t.Temp))}}Nginx配置server { listen 80; server_name _; root /var/www/html/public; index index.php index.html; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass php-api:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # WebSocket代理设备实时通信 location /ws { proxy_pass http://emqx:8083; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; } }部署步骤# 1. 克隆代码gitclone https://github.com/your-repo/iot-platform.gitcdiot-platform# 2. 配置环境变量cp.env.example .envnano.env# 修改密码# 3. 启动所有服务docker-composeup-d# 4. 初始化数据库dockerexec-itiot_mysql mysql-uroot-piot_platformsql/init.sql# 5. 检查服务状态docker-composepsdocker-composelogs-f整个过程5分钟。性能与资源占用在一台4核8G的云服务器上实测服务内存占用CPU占用MySQL~500MB5%Redis~30MB2%EMQX~200MB10%Go Worker~50MB5%PHP-FPM~100MB5%Nginx~20MB1%总计~900MB30%500台设备每5秒上报一次数据系统负载轻松hold住。实际踩坑坑1MySQL时区Docker MySQL默认UTC但业务需要东八区。在docker-compose.yml中加environment:TZ:Asia/Shanghai或者直接在MySQL配置文件中设置default-time-zone08:00。坑2EMQX WebSocket跨域前端通过WebSocket连接EMQX时可能遇到CORS问题。在EMQX配置中emqx:environment:EMQX_LISTENER__WS__DEFAULT__ACCESS_CONTROL__ALLOW_ORIGINS:*坑3Docker日志撑爆磁盘容器默认不限制日志大小。加上logging:driver:json-fileoptions:max-size:10mmax-file:3总结Docker化部署物联网系统核心好处是环境一致性和快速交付。你在本地调好的系统到客户现场5分钟部署完不需要在现场折腾环境问题。虎王科技的设备管理平台就是基于这套架构目前稳定运行中。Docker Compose文件和部分代码在GitHub上github.com/huwangkeji有问题欢迎评论区交流。沧州虎王科技专注物联网软硬件开发、通信设备、嵌入式系统与设备管理平台。
返回列表