Skip to content

二进制部署 ​

不使用容器,把各服务编译为可执行文件,用 systemd 托管。

适用场景 ​

  • 服务器不允许安装 Docker
  • 需要把服务纳入既有的 systemd / 进程管理体系统一运维
  • 需要针对特定 CPU 架构或内核参数做优化

构建环境 ​

项要求
Go按各服务 go.mod 要求,最低 1.23(见下表)
GCCadmin-svr 需要(CGO_ENABLED=1,内存库用 SQLite)
系统建议与目标服务器同发行版,避免 libc 差异
bash
# Debian / Ubuntu
apt-get install -y build-essential

# CentOS / Rocky
yum groupinstall -y "Development Tools"

其余服务可静态编译

除 admin-svr 外,其余服务 CGO_ENABLED=0,产物为静态二进制,可直接拷到任意同架构 Linux 运行。

各服务构建参数 ​

全部服务在同一仓的不同目录下,下表「目录」即 git clone 后的相对路径。

服务目录Go 版本CGO构建目录产物名监听端口
admin-svradmin-svr/1.23需开启server/iotlcmadmin_svc8008
openapiopenapi/1.23关闭根目录iotlcm-openapi8000
worker-svrworker-svr/1.25关闭根目录iotlcm-worker-svr无(队列消费)
upstream-chanupstream-chan/1.25关闭根目录iotlcmupstreamchan_svc8110 / 8310
upstream-proxyupstream-proxy/1.25关闭根目录iotlcmupstreamproxy_svc8510
app-serverapp/server/1.23关闭server/iotlcm-app-server8010
smssms/1.25关闭根目录iotlcm-sms11190 / 11200
botbot/1.23关闭cmd/iotlcm-botiotlcm-bot无

基础镜像可替换

所有构建用 Dockerfile 的 FROM 都走 ARG BASE_REGISTRY(默认 docker.io/library),需要私有基础镜像时用 --build-arg BASE_REGISTRY=... 覆盖即可,见自建镜像。

构建 ​

admin-svr(需要 CGO) ​

bash
git clone <仓库地址> iotlcm
cd iotlcm/admin-svr/server

CGO_ENABLED=1 GOOS=linux GOARCH=amd64 \
go build -trimpath \
  -ldflags "-s -w \
    -X main.BuildVersion=$(git describe --tags --always) \
    -X main.CommitID=$(git rev-parse --short HEAD) \
    -X main.BuildTime=$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
  -o iotlcmadmin_svc .

其余服务(静态编译) ​

bash
git clone <仓库地址> iotlcm
cd iotlcm/openapi

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -trimpath \
  -ldflags "-s -w \
    -X main.BuildVersion=$(git describe --tags --always) \
    -X main.CommitID=$(git rev-parse --short HEAD) \
    -X main.BuildTime=$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
  -o iotlcm-openapi .

替换服务目录与产物名即可用于其他服务,bot 需要指定子目录:

bash
cd iotlcm/bot
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -o iotlcm-bot ./cmd/iotlcm-bot

交叉编译说明 ​

服务能否交叉编译
admin-svr(CGO)❌ 需在目标架构上编译,或用对应架构的交叉工具链
其余(静态)✅ 可直接 GOOS=linux GOARCH=arm64

查看服务器架构:

bash
uname -m          # x86_64 → amd64;aarch64 → arm64

部署布局 ​

text
/opt/iotlcm/
├── admin-svr/
│   ├── iotlcmadmin_svc
│   ├── config/config.yaml      ← 从 config/admin-svr 复制
│   ├── logs/
│   ├── upload/
│   └── cache/
├── openapi/
│   ├── iotlcm-openapi
│   ├── config/config.yaml
│   └── logs/
├── worker-svr/
│   ├── iotlcm-worker-svr
│   ├── config/config.yaml
│   └── logs/
├── upstream-chan/
├── upstream-proxy/
├── app-server/
│   ├── iotlcm-app-server
│   ├── config/config.yaml
│   └── resource/
│       ├── log/server/
│       └── upload/
├── sms/
└── bot/

配置文件放 config/config.yaml(相对工作目录),这是 GoFrame 的默认搜索路径。启动时工作目录必须在服务目录内。

目录准备 ​

bash
sudo mkdir -p /opt/iotlcm/{admin-svr,openapi,worker-svr,upstream-chan,upstream-proxy,app-server,sms,bot}
sudo useradd -r -s /sbin/nologin iotlcm
sudo chown -R iotlcm:iotlcm /opt/iotlcm

修改配置中的服务地址 ​

容器部署时配置里写的是服务名(mysql:3306、upstream-proxy:8510),二进制部署必须改为实际地址:

yaml
# admin-svr / openapi / worker-svr / app-server
database:
  default:
    link: "mysql:u_iotlcm:<口令>@tcp(127.0.0.1:3306)/db_iotlcm?charset=utf8mb4&parseTime=True&loc=Asia%2FShanghai"
redis:
  default:
    address: "127.0.0.1:6379"
rabbitmq:
  dsn: "amqp://<用户>:<口令>@127.0.0.1:5672/"

# upstream-chan / upstream-proxy
registry:
  address: "127.0.0.1:8500"

# 上游服务地址
upstream:
  proxy:
    address: "127.0.0.1:8510"
  gateway:
    address: "127.0.0.1:8110"

logger.path 也要改

配置里的 logger.path 在容器版本中是 /app/logs,二进制部署要改为实际路径,例如 /opt/iotlcm/admin-svr/logs,否则会因目录不存在启动失败。

systemd 托管 ​

以为 admin-svr 为例,保存为 /etc/systemd/system/iotlcm-admin-svr.service:

ini
[Unit]
Description=IotLCM Admin Service
After=network-online.target mysql.service redis.service
Wants=network-online.target

[Service]
Type=simple
User=iotlcm
Group=iotlcm
WorkingDirectory=/opt/iotlcm/admin-svr
ExecStart=/opt/iotlcm/admin-svr/iotlcmadmin_svc
Restart=always
RestartSec=5s
LimitNOFILE=65535

# 环境变量(JWT 密钥等敏感值建议放独立文件)
EnvironmentFile=-/etc/iotlcm/admin-svr.env

# 日志交给 journald,也可用配置里的文件日志
StandardOutput=journal
StandardError=journal

# 安全加固
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
ReadWritePaths=/opt/iotlcm/admin-svr

[Install]
WantedBy=multi-user.target

/etc/iotlcm/admin-svr.env:

bash
JWT_SIGNING_KEY=<与其它服务一致的密钥>

启用:

bash
sudo systemctl daemon-reload
sudo systemctl enable --now iotlcm-admin-svr
sudo systemctl status iotlcm-admin-svr

各服务的差异点 ​

服务特殊处理
admin-svr需 ReadWritePaths 包含 upload 与 logs 目录
worker-svr无监听端口,After 需包含 rabbitmq
upstream-chan / proxyAfter 需包含 consul
app-server需 resource/log/server 与 resource/upload 可写
botExecStart 需带参数:/opt/iotlcm/bot/iotlcm-bot watch --config /opt/iotlcm/bot/config/config.yaml

启动顺序 ​

text
MySQL / Redis / RabbitMQ / Consul
        ↓
admin-svr、openapi、worker-svr、upstream-chan、upstream-proxy、app-server、sms
        ↓
admin-ui、app-web、docs(静态文件,由 nginx 托管)

用 systemd 依赖表达:

ini
[Unit]
After=iotlcm-admin-svr.service
Requires=iotlcm-admin-svr.service

静态前端 ​

admin-ui、app-web、docs 是静态文件,二进制部署时不需要跑容器,把构建产物交给 nginx:

bash
# admin-ui:需 Node 构建
cd iotlcm-admin-ui/vue
npm ci && npm run build
sudo cp -r apps/web-antd/dist /var/www/iotlcm/admin-ui

nginx 配置参考部署仓的 config/admin-ui/default.conf 与 config/nginx/iotlcm.conf,把 proxy_pass http://admin-svr:8008 改为 http://127.0.0.1:8008。

验证 ​

bash
# 进程状态
systemctl status iotlcm-admin-svr
journalctl -u iotlcm-admin-svr -n 50 --no-pager

# 端口监听
ss -lntp | grep -E '8008|8000|8510|8110'

# 接口
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8008/api.json

与容器部署的差异 ​

项容器部署二进制部署
配置路径/app/config(挂载)<服务目录>/config
日志路径/app/logs需在配置里改成实际路径
服务互访服务名(Docker DNS)127.0.0.1 或内网 IP
进程管理Docker restart policysystemd
升级换镜像 + up -d停服务 → 换二进制 → 起服务
时区镜像已内置依赖宿主机 tzdata

升级流程 ​

bash
# 1. 备份配置与程序
sudo tar czf /backup/iotlcm-admin-svr-$(date +%F).tar.gz -C /opt/iotlcm admin-svr

# 2. 停服务
sudo systemctl stop iotlcm-admin-svr

# 3. 替换二进制
sudo cp iotlcmadmin_svc /opt/iotlcm/admin-svr/
sudo chown iotlcm:iotlcm /opt/iotlcm/admin-svr/iotlcmadmin_svc

# 4. 起服务并验证
sudo systemctl start iotlcm-admin-svr
sudo systemctl status iotlcm-admin-svr

回滚 ​

保留上一版二进制,回滚只需换回:

bash
sudo systemctl stop iotlcm-admin-svr
sudo cp /opt/iotlcm/admin-svr/iotlcmadmin_svc.bak /opt/iotlcm/admin-svr/iotlcmadmin_svc
sudo systemctl start iotlcm-admin-svr

iotLCM 文档中心