低空智控平台 后端go
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

6.9 KiB

laic-backend

低空智控平台 后端 Go 服务。

生产部署

部署脚本参考 D:/GoProject/roller-service/roller-manage/publish-prod.sh,使用 Supervisor 管理服务。

服务器准备

在生产服务器安装 Supervisor。生产配置保存在仓库根目录的 config-prod.yaml,部署脚本会将它上传为服务器部署目录中的 config.yaml:

sudo apt update
sudo apt install supervisor -y
sudo systemctl enable --now supervisor

生产配置至少包含:

oss:
  endpoint: https://obs.cn-east-2.myhuaweicloud.com
  access-key: 实际的华为云 OBS AK
  secret-key: 实际的华为云 OBS SK
  bucket: gcs-edu
  region: cn-east-2
  use-ssl: true

后端启动时直接读取部署目录下的 config.yaml。本地开发不设置 LAIC_CONFIG_FILE 时读取本地 config.yaml;Supervisor 显式设置 LAIC_CONFIG_FILE=config.yaml。

执行部署

修改 publish-prod.sh 顶部的 REMOTE、REMOTE_DIR 和服务参数,然后执行:

chmod +x publish-prod.sh
./publish-prod.sh

脚本会完成:

  1. 交叉编译 Linux amd64 二进制。
  2. 创建远程部署目录、日志目录和备份目录。
  3. 备份旧二进制和 config.yaml(首次部署没有旧文件时跳过)。
  4. 将本地 config-prod.yaml 上传为远程 config.yaml。
  5. 更新 Supervisor 配置、重启服务并检查状态。
  6. 启动失败时自动恢复最近的旧二进制。

首次部署前确认远程服务器已安装并运行 Supervisor:

sudo apt update
sudo apt install supervisor -y
sudo systemctl enable --now supervisor

查看状态和日志:

sudo supervisorctl status laic-backend-prod
sudo tail -f /usr/local/laic-backend-prod/log/info.log
sudo tail -f /usr/local/laic-backend-prod/log/err.log

部署目录和服务名可以在 publish-prod.sh 顶部调整。回滚时,脚本会使用远程 backup/ 目录中最近的二进制备份;也可以手工恢复后执行:

sudo supervisorctl restart laic-backend-prod

Payment and SIM schema reconciliation

If a production database was upgraded from an older partial release, back it up first and then run sql/019_reconcile_payment_schema.sql. The migration is repeatable and fills missing traffic_order.updated_at, payment fields, pending order guards, and normalizes legacy empty payment idempotency keys. It also creates the payment/SIM tables. It does not create orders, charge users, or create SIM cards. Verify the schema and platform resource pool after it finishes, then restart the backend before retrying payment.

AGPay returns the WeChat QR code as binary image/png. The backend converts it to a JSON-safe providerPayload data URI (data:image/png;base64,...); clients should use that value directly as the image src and must not UTF-8 decode the original response body.

Live session device event uniqueness

live_session.uk_live_session_device_event was originally built directly on device_event_id. MySQL unique indexes treat multiple NULL values as distinct but multiple empty strings as duplicates, so only one live session without a reported device event could exist at a time. Creating a second live session then failed with:

Error 1062 (23000): Duplicate entry '' for key 'live_session.uk_live_session_device_event'

Run sql/023_live_session_device_event_nullable.sql on any database created before this fix. It adds a device_event_key generated column (NULLIF(device_event_id, '')) and moves the unique index onto it. The migration is repeatable. sql/001_schema.sql already contains the fixed schema for new databases.

Live stop convergence

stopping is never moved back to an active phase (starting/streaming/ reconnecting). Any transition that did so would make the reconciler see an active session again and publish another video.stop_stream, producing an unbounded stop loop when the edge no longer knows the session.

If the edge restarts dock-video-relay, it returns to idle and rejects the stop with VIDEO_SESSION_MISMATCH (protocol section 5.2.4; the mock uses SESSION_NOT_FOUND). Both codes mark the session stopped immediately. Otherwise the session stays stopping and is forced to stopped after 120 seconds (stopForceAfter), including when the stop command times out because the edge is offline. That bound also keeps uk_live_session_active_dock released so the dock can start a new session.

Live session lifetime

A live session's absolute deadline comes from live.max-session-seconds (falling back to live.auth-expire-seconds when unset). It is sent to the edge as video.start_stream.expiresAt and also bounds the signed push/play URLs, so it cannot be extended mid-session: re-sending video.start_stream with a different expiresAt changes the params digest and the edge rejects it with COMMAND_ID_CONFLICT (protocol section 5.1/6).

Idle shutdown is therefore handled by viewer leases, not by that deadline: with no active lease the session is stopped after live.stop-grace-seconds, while a viewer that keeps calling the heartbeat endpoint keeps the stream alive until the absolute deadline. The production value is 2 hours (max-session-seconds: 7200); raise it if users need longer continuous viewing. A stopping session is forced to stopped after 120 seconds even if the edge keeps reporting streaming=true, so a stuck publisher cannot block the dock from starting a new session.

Live billing bitrate

Live billing now charges the average bitrate the edge reports in state/video.bitrateBps (the protocol's expectedBitrateBps, 1 Mbps by default) instead of the session peak maxBitrateBps (1.5 Mbps). Run sql/024_live_session_billing_bitrate.sql before deploying; it adds live_session.billing_bitrate_bps. The migration is repeatable and sql/001_schema.sql already contains the column for new databases. Until the edge reports a bitrate the charged value falls back to max_bitrate_bps.

Live start params rehearsal

video.start_stream retries must resend the exact same params because the edge compares a params digest for commandId idempotency. The push URL carries a short-lived credential and is therefore stored in Redis under laic:live:startparams:{commandId} (never in MySQL, per the live backend design, section 11) and replayed verbatim on retry.

Test traffic grant

For QA environments, set the following configuration explicitly (it defaults to disabled):

testing:
  allow-traffic-grant: true

An authenticated administrator can then credit a regular user without creating a payment order:

POST /v1/admin/traffic/test-grants
Content-Type: application/json

{"userId":8243938201600,"amountGb":10,"reason":"live test"}

The operation updates the user snapshot, appends a test_grant traffic ledger entry, invalidates the Redis balance cache, and writes an operation log. Keep the switch disabled in production after testing.