# RWA Durian 系统部署指南 本文档描述了 RWA Durian 系统的完整部署架构,包括前端 API 调用、Nginx 反向代理配置和后端服务部署。 ## 1. 系统架构概览 ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ 用户设备 │ │ (Android/iOS App) │ └─────────────────────────────────┬───────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ Nginx + MPC-System 服务器 192.168.1.100 (公网) │ │ https://rwaapi.szaiai.com │ │ │ │ ┌────────────────────────────────────────────────────────────────────────┐ │ │ │ Nginx 反向代理 │ │ │ │ /etc/nginx/conf.d/rwaapi.conf │ │ │ │ │ │ │ │ /api/v1/user/* → 192.168.1.111:3000 (Identity) │ │ │ │ /api/v1/auth/* → 192.168.1.111:3000 (Identity) │ │ │ │ /api/v1/wallet/* → 192.168.1.111:3002 (Wallet) │ │ │ │ /api/v1/trading/* → 192.168.1.111:3002 (Wallet) │ │ │ │ /api/v1/planting/* → 192.168.1.111:3003 (Planting) │ │ │ │ /api/v1/referral/* → 192.168.1.111:3004 (Referral) │ │ │ │ /api/v1/mining/* → 192.168.1.111:3005 (Reward) │ │ │ │ /api/v1/ranking/* → 192.168.1.111:3007 (Leaderboard) │ │ │ │ /api/v1/telemetry/*→ 192.168.1.111:3008 (Reporting) │ │ │ └────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────────────────┐ │ │ │ MPC-System (Go 服务) │ │ │ │ localhost:4000 │ │ │ │ • TSS 密钥生成 (Keygen) │ │ │ │ • TSS 签名 (Sign) │ │ │ │ • 密钥分片管理 │ │ │ └───────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────┬───────────────────────────────────────────┘ │ 内网 ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 后端服务器 192.168.1.111 │ │ │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │ │ Identity │ │ MPC-Service │ │ Wallet │ │ Planting │ │ │ │ :3000 │ │ :3001 │ │ :3002 │ │ :3003 │ │ │ └───────────────┘ └───────────────┘ └───────────────┘ └───────────────┘ │ │ │ │ │ │ │ │ 调用 MPC-System │ │ │ └──────────────────────► 192.168.1.100:4000 │ │ │ │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │ │ Referral │ │ Reward │ │ Authorization │ │ Leaderboard │ │ │ │ :3004 │ │ :3005 │ │ :3006 │ │ :3007 │ │ │ └───────────────┘ └───────────────┘ └───────────────┘ └───────────────┘ │ │ │ │ ┌───────────────┐ ┌───────────────┐ │ │ │ Reporting │ │ Backup │ │ │ │ :3008 │ │ :3009 │ │ │ └───────────────┘ └───────────────┘ │ │ │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │ │ PostgreSQL │ │ Redis │ │ Kafka │ │ │ │ :5432 │ │ :6379 │ │ :9092 │ │ │ └───────────────┘ └───────────────┘ └───────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` ### 服务器角色说明 | 服务器 | IP 地址 | 角色 | 部署服务 | |-------|---------|------|---------| | Nginx + MPC 服务器 | 192.168.1.100 (公网) | API 网关 + MPC 核心 | Nginx, MPC-System (Go) | | 后端服务器 | 192.168.1.111 (内网) | 业务微服务 | 所有 NestJS 微服务 + 基础设施 | ### 为什么 MPC-System 部署在 Nginx 服务器上? **安全隔离原则**: MPC-System 是处理密钥分片的核心安全组件,与业务数据库隔离部署可以: 1. 减少攻击面 - 即使业务服务器被入侵,MPC 密钥分片仍然安全 2. 物理隔离 - 密钥分片和业务数据在不同机器上 3. 独立运维 - MPC 系统可以独立升级和维护 ## 2. 服务端口规划 ### 2.1 Nginx + MPC 服务器 (192.168.1.100) | 服务名称 | 端口 | 说明 | |---------|------|------| | Nginx | 80, 443 | HTTP/HTTPS 反向代理 | | MPC-System (Go) | 4000 | TSS 密钥生成、签名服务 | ### 2.2 后端服务器 (192.168.1.111) | 服务名称 | 端口 | API 前缀 | 说明 | |---------|------|----------|------| | Identity Service | 3000 | `/api/v1` | 用户身份、认证、钱包创建 | | MPC Service (NestJS) | 3001 | `/api/v1` | MPC 中间层,调用 MPC-System | | Wallet Service | 3002 | `/api/v1` | 钱包余额、交易、充值 | | Planting Service | 3003 | `/api/v1` | 认种业务 | | Referral Service | 3004 | `/api/v1` | 推荐关系、分享链接 | | Reward Service | 3005 | `/api/v1` | 挖矿奖励、收益 | | Authorization Service | 3006 | `/api/v1` | 权限管理 (内部) | | Leaderboard Service | 3007 | `/api` | 排行榜 | | Reporting Service | 3008 | `/api/v1` | 遥测统计、报表 | | Backup Service | 3009 | - | MPC 备份 (内部服务) | ### 2.3 MPC 调用链路 ``` 用户请求 → Identity Service (3000) → MPC Service (3001) → MPC-System (192.168.1.100:4000) ↓ TSS 密钥生成/签名 ``` ## 3. Nginx 配置文件 ### 3.1 目录结构 在 Nginx 服务器上使用 `sites-available` / `sites-enabled` 标准结构: ``` /etc/nginx/ ├── nginx.conf # 主配置文件 ├── sites-available/ # 可用站点配置 │ └── rwaapi.szaiai.com.conf # API 网关配置 ├── sites-enabled/ # 已启用站点 (软链接) │ └── rwaapi.szaiai.com.conf → ../sites-available/rwaapi.szaiai.com.conf └── snippets/ # 可复用配置片段 ├── proxy-params.conf # 代理参数 ├── cors-params.conf # CORS 跨域配置 └── ssl-params.conf # SSL 安全参数 /etc/letsencrypt/live/rwaapi.szaiai.com/ # Let's Encrypt SSL 证书 (自动管理) ├── fullchain.pem # 完整证书链 ├── privkey.pem # 私钥 ├── cert.pem # 服务器证书 └── chain.pem # 中间证书 ``` **使用 `sites-available/sites-enabled` 的优势:** - 快速启用/禁用站点:`ln -s` / `rm` 软链接 - 保留配置历史,方便回滚 - 多站点管理更清晰 ### 3.2 主配置文件 `/etc/nginx/nginx.conf` ```nginx user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; use epoll; multi_accept on; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' 'rt=$request_time uct="$upstream_connect_time" ' 'uht="$upstream_header_time" urt="$upstream_response_time"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; client_max_body_size 10m; # Gzip 压缩 gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css text/xml application/json application/javascript application/xml application/xml+rss text/javascript; # 限流配置 limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=conn_limit:10m; # 加载已启用的站点配置 include /etc/nginx/sites-enabled/*.conf; } ``` ### 3.3 代理参数配置 `/etc/nginx/snippets/proxy-params.conf` ```nginx proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Connection ""; proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; proxy_busy_buffers_size 8k; ``` ### 3.4 CORS 配置 `/etc/nginx/snippets/cors-params.conf` ```nginx # CORS 预检请求处理 if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } # CORS 响应头 add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always; ``` ### 3.5 SSL 安全参数 `/etc/nginx/snippets/ssl-params.conf` ```nginx # SSL 会话配置 ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; # 现代 SSL 协议配置 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; # HSTS add_header Strict-Transport-Security "max-age=63072000" always; ``` ### 3.6 API 网关配置 `/etc/nginx/sites-available/rwaapi.szaiai.com.conf` ```nginx # ============================================ # 后端服务器地址 (192.168.1.111) # ============================================ upstream identity_service { server 192.168.1.111:3000; keepalive 32; } upstream wallet_service { server 192.168.1.111:3002; keepalive 32; } upstream planting_service { server 192.168.1.111:3003; keepalive 32; } upstream referral_service { server 192.168.1.111:3004; keepalive 32; } upstream reward_service { server 192.168.1.111:3005; keepalive 32; } upstream leaderboard_service { server 192.168.1.111:3007; keepalive 32; } upstream reporting_service { server 192.168.1.111:3008; keepalive 32; } # ============================================ # HTTP -> HTTPS 重定向 # ============================================ server { listen 80; server_name rwaapi.szaiai.com; return 301 https://$server_name$request_uri; } # ============================================ # HTTPS 服务器 # ============================================ server { listen 443 ssl http2; server_name rwaapi.szaiai.com; # Let's Encrypt SSL 证书 (默认路径) ssl_certificate /etc/letsencrypt/live/rwaapi.szaiai.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/rwaapi.szaiai.com/privkey.pem; # 引入 SSL 安全参数 include snippets/ssl-params.conf; # 安全头 add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; # 限流 limit_req zone=api_limit burst=20 nodelay; limit_conn conn_limit 10; # ============================================ # 健康检查端点 # ============================================ location /health { access_log off; return 200 '{"status":"ok","timestamp":"$time_iso8601"}'; add_header Content-Type application/json; } # ============================================ # Identity Service - 用户身份认证 # POST /api/v1/user/auto-create - 自动创建用户 # POST /api/v1/user/login - 用户登录 # GET /api/v1/user/profile - 获取用户信息 # ============================================ location /api/v1/user { include snippets/cors-params.conf; proxy_pass http://identity_service/api/v1/user; include snippets/proxy-params.conf; } location /api/v1/auth { include snippets/cors-params.conf; proxy_pass http://identity_service/api/v1/auth; include snippets/proxy-params.conf; } # ============================================ # Wallet Service - 钱包操作 # GET /api/v1/wallet/balance - 查询余额 # POST /api/v1/wallet/create - 创建钱包 # ============================================ location /api/v1/wallet { include snippets/cors-params.conf; proxy_pass http://wallet_service/api/v1/wallet; include snippets/proxy-params.conf; } # Trading - 交易 location /api/v1/trading { include snippets/cors-params.conf; proxy_pass http://wallet_service/api/v1/trading; include snippets/proxy-params.conf; } # Deposit - 充值 location /api/v1/deposit { include snippets/cors-params.conf; proxy_pass http://wallet_service/api/v1/deposit; include snippets/proxy-params.conf; } # ============================================ # Planting Service - 认种业务 # GET /api/v1/planting/price - 认种价格 # POST /api/v1/planting/submit - 提交认种 # ============================================ location /api/v1/planting { include snippets/cors-params.conf; proxy_pass http://planting_service/api/v1/planting; include snippets/proxy-params.conf; } # ============================================ # Referral Service - 推荐系统 # GET /api/v1/referral/generate-link - 生成推荐链接 # GET /api/v1/community/referrals - 获取推荐列表 # ============================================ location /api/v1/referral { include snippets/cors-params.conf; proxy_pass http://referral_service/api/v1/referral; include snippets/proxy-params.conf; } location /api/v1/community { include snippets/cors-params.conf; proxy_pass http://referral_service/api/v1/community; include snippets/proxy-params.conf; } # ============================================ # Reward Service - 挖矿奖励 # GET /api/v1/mining/status - 挖矿状态 # POST /api/v1/mining/start - 开始挖矿 # POST /api/v1/mining/claim - 领取奖励 # ============================================ location /api/v1/mining { include snippets/cors-params.conf; proxy_pass http://reward_service/api/v1/mining; include snippets/proxy-params.conf; } location /api/v1/reward { include snippets/cors-params.conf; proxy_pass http://reward_service/api/v1/reward; include snippets/proxy-params.conf; } # ============================================ # Leaderboard Service - 排行榜 # GET /api/v1/ranking/daily - 日榜 # GET /api/v1/ranking/weekly - 周榜 # ============================================ location /api/v1/ranking { include snippets/cors-params.conf; proxy_pass http://leaderboard_service/api/ranking; include snippets/proxy-params.conf; } location /api/v1/leaderboard { include snippets/cors-params.conf; proxy_pass http://leaderboard_service/api/leaderboard; include snippets/proxy-params.conf; } # ============================================ # Reporting Service - 遥测统计 # POST /api/v1/telemetry/session - 上报会话 # POST /api/v1/telemetry/heartbeat - 心跳 # POST /api/v1/telemetry/events - 事件上报 # ============================================ location /api/v1/telemetry { include snippets/cors-params.conf; proxy_pass http://reporting_service/api/v1/telemetry; include snippets/proxy-params.conf; } location /api/v1/report { include snippets/cors-params.conf; proxy_pass http://reporting_service/api/v1/report; include snippets/proxy-params.conf; } # ============================================ # 默认 404 # ============================================ location / { return 404 '{"error":"Not Found","message":"API endpoint not found"}'; add_header Content-Type application/json; } } ``` ## 4. MPC-System 部署 (192.168.1.100) MPC-System 是一组 Go 微服务,负责 TSS (Threshold Signature Scheme) 密钥生成和签名操作。 采用 2-of-3 阈值签名方案,包含多个内部服务。 > **注意**: 由于中国网络环境无法正常使用 Docker,本部署采用原生安装方式。 ### 4.1 系统要求 - Ubuntu 20.04+ / Debian 11+ - Go 1.21+ (脚本自动安装) - PostgreSQL 15+ (脚本自动安装) - Redis 7+ (脚本自动安装) - RabbitMQ 3+ (脚本自动安装) - 最小 4GB RAM - 20GB 磁盘空间 ### 4.2 服务架构 ``` MPC-System (原生部署) ├── mpc-account # 对外 API 入口 (端口 8080 → 4000) ├── mpc-session-coordinator # 会话协调器 (gRPC :50051) ├── mpc-message-router # 消息路由 (gRPC :50052) ├── mpc-server-party-1 # TSS 参与方 1 ├── mpc-server-party-2 # TSS 参与方 2 ├── mpc-server-party-3 # TSS 参与方 3 └── 基础设施 (PostgreSQL, Redis, RabbitMQ) ``` ### 4.3 一键部署脚本 MPC-System 提供了一键部署脚本 `scripts/deploy.sh`,支持以下命令: | 命令 | 说明 | |------|------| | `install` | 安装系统依赖 (Go, PostgreSQL, Redis, RabbitMQ) | | `build` | 编译服务并配置基础设施 | | `start` | 启动所有 MPC 服务 | | `stop` | 停止所有 MPC 服务 | | `restart` | 重启所有 MPC 服务 | | `status` | 查看服务状态 | | `logs` | 查看服务日志 | | `uninstall` | 卸载 MPC 服务 | ### 4.4 部署步骤 ```bash # ============================================ # 步骤 1: 克隆代码 # ============================================ cd /home/ceshi git clone https://github.com/your-org/rwadurian.git cd rwadurian/backend/mpc-system # ============================================ # 步骤 2: 安装依赖 # ============================================ # 需要 root 权限 sudo bash scripts/deploy.sh install # 脚本将自动安装: # - Go 1.21 (从 go.dev 下载,使用 goproxy.cn 加速) # - PostgreSQL 15 # - Redis 7 # - RabbitMQ 3 # ============================================ # 步骤 3: 配置环境变量 # ============================================ sudo vim /opt/mpc-system/config/mpc.env ``` **mpc.env 配置文件内容:** ```bash # MPC-System 环境配置 # 请修改以下值为生产环境的安全密码 # 环境标识 ENVIRONMENT=production # PostgreSQL 数据库 POSTGRES_USER=mpc_user POSTGRES_PASSWORD=your_secure_postgres_password_here MPC_DATABASE_HOST=localhost MPC_DATABASE_PORT=5432 MPC_DATABASE_USER=mpc_user MPC_DATABASE_PASSWORD=your_secure_postgres_password_here MPC_DATABASE_DBNAME=mpc_system MPC_DATABASE_SSLMODE=disable # Redis 缓存 (留空表示不需要密码) REDIS_PASSWORD= MPC_REDIS_HOST=localhost MPC_REDIS_PORT=6379 MPC_REDIS_PASSWORD= # RabbitMQ 消息队列 RABBITMQ_USER=mpc_user RABBITMQ_PASSWORD=your_secure_rabbitmq_password_here MPC_RABBITMQ_HOST=localhost MPC_RABBITMQ_PORT=5672 MPC_RABBITMQ_USER=mpc_user MPC_RABBITMQ_PASSWORD=your_secure_rabbitmq_password_here # JWT 配置 (至少 32 字符) JWT_SECRET_KEY=your_super_secure_jwt_secret_key_at_least_32_characters MPC_JWT_SECRET_KEY=your_super_secure_jwt_secret_key_at_least_32_characters MPC_JWT_ISSUER=mpc-system # 主加密密钥 (64 位十六进制 = 256 位密钥,用于加密密钥分片) CRYPTO_MASTER_KEY=your_64_hex_characters_master_key_here MPC_CRYPTO_MASTER_KEY=your_64_hex_characters_master_key_here # API 认证密钥 (与 mpc-service 配置的 MPC_API_KEY 一致) MPC_API_KEY=your_very_secure_api_key_at_least_32_characters # 允许访问的 IP 地址 (后端服务器) ALLOWED_IPS=192.168.1.111 # 服务配置 MPC_SERVER_ENVIRONMENT=production MPC_SERVER_HTTP_PORT=8080 MPC_SERVER_GRPC_PORT=50051 # 内部服务地址 SESSION_COORDINATOR_ADDR=localhost:50051 MESSAGE_ROUTER_ADDR=localhost:50052 ``` ```bash # ============================================ # 步骤 4: 编译并配置服务 # ============================================ sudo bash scripts/deploy.sh build # 此步骤会: # - 编译所有 Go 服务到 /opt/mpc-system/bin/ # - 创建 systemd 服务文件 # - 配置 PostgreSQL 数据库和用户 # - 配置 Redis # - 配置 RabbitMQ 用户 # - 运行数据库迁移 # ============================================ # 步骤 5: 启动服务 # ============================================ sudo bash scripts/deploy.sh start # ============================================ # 步骤 6: 验证部署 # ============================================ # 查看服务状态 sudo bash scripts/deploy.sh status # 健康检查 curl http://localhost:8080/health # 查看日志 sudo bash scripts/deploy.sh logs mpc-account ``` ### 4.5 配置 Nginx 反向代理 (端口 4000) 为了保持与 Docker 部署相同的端口映射 (4000 → 8080),配置 Nginx: ```bash # 创建 MPC 代理配置 cat > /etc/nginx/conf.d/mpc-proxy.conf << 'EOF' # MPC-System 内部代理 # 将外部端口 4000 代理到内部 8080 server { listen 4000; server_name localhost; location / { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 仅允许后端服务器访问 allow 192.168.1.111; deny all; } } EOF # 测试并重载 Nginx nginx -t && nginx -s reload ``` 或者直接使用 iptables 端口转发: ```bash # 端口转发: 4000 → 8080 iptables -t nat -A PREROUTING -p tcp --dport 4000 -j REDIRECT --to-port 8080 iptables -t nat -A OUTPUT -p tcp --dport 4000 -j REDIRECT --to-port 8080 # 保存规则 iptables-save > /etc/iptables/rules.v4 ``` ### 4.6 服务端口说明 | 服务 | 端口 | 说明 | |------|------|------| | mpc-account | 8080 (→ 4000) | 对外 API 入口,供 mpc-service 调用 | | mpc-session-coordinator | 50051 | 会话协调 gRPC (内部) | | mpc-message-router | 50052 | 消息路由 gRPC (内部) | | mpc-server-party-1/2/3 | 8081-8083 | TSS 参与方 HTTP (内部) | | PostgreSQL | 5432 | 数据库 (内部) | | Redis | 6379 | 缓存 (内部) | | RabbitMQ | 5672 | 消息队列 (内部) | > **注意**: 生产环境仅对外暴露端口 4000 (通过 Nginx 或 iptables 代理到 8080) ### 4.7 MPC-System API 端点 Account Service (端口 4000/8080) 对外提供以下 API: | 端点 | 方法 | 说明 | |------|------|------| | `/health` | GET | 健康检查 | | `/api/v1/account/create` | POST | 创建 MPC 账户 (触发密钥生成) | | `/api/v1/account/sign` | POST | 请求签名 | | `/api/v1/account/recovery` | POST | 账户恢复 | ### 4.8 防火墙配置 ```bash # 只允许后端服务器 (192.168.1.111) 访问 MPC-System 端口 4000/8080 iptables -A INPUT -p tcp --dport 4000 -s 192.168.1.111 -j ACCEPT iptables -A INPUT -p tcp --dport 4000 -j DROP iptables -A INPUT -p tcp --dport 8080 -s 192.168.1.111 -j ACCEPT iptables -A INPUT -p tcp --dport 8080 -j DROP # 保存规则 iptables-save > /etc/iptables/rules.v4 ``` ### 4.9 运维命令 ```bash cd /home/ceshi/rwadurian/backend/mpc-system # 查看服务状态 sudo bash scripts/deploy.sh status # 或使用 systemctl systemctl status mpc-account systemctl status mpc-session-coordinator systemctl status mpc-message-router systemctl status mpc-server-party-1 systemctl status mpc-server-party-2 systemctl status mpc-server-party-3 # 查看日志 sudo bash scripts/deploy.sh logs mpc-account # 或 journalctl -u mpc-account -f tail -f /opt/mpc-system/logs/mpc-account.log # 重启单个服务 systemctl restart mpc-account # 重启所有 MPC 服务 sudo bash scripts/deploy.sh restart # 停止所有 MPC 服务 sudo bash scripts/deploy.sh stop # 启动所有 MPC 服务 sudo bash scripts/deploy.sh start # 重新编译 (代码更新后) cd /home/ceshi/rwadurian/backend/mpc-system git pull sudo bash scripts/deploy.sh build sudo bash scripts/deploy.sh restart ``` ### 4.10 目录结构 安装后的目录结构: ``` /opt/mpc-system/ ├── bin/ # 编译后的可执行文件 │ ├── account-service │ ├── session-coordinator │ ├── message-router │ └── server-party ├── config/ │ └── mpc.env # 环境配置文件 ├── data/ # 数据目录 ├── logs/ # 日志目录 │ ├── mpc-account.log │ ├── mpc-account.error.log │ ├── mpc-session-coordinator.log │ └── ... ├── migrations/ # 数据库迁移文件 │ └── 001_init_schema.up.sql └── pids/ # PID 文件目录 ``` ### 4.11 故障排查 ```bash # 检查服务是否在运行 sudo bash scripts/deploy.sh status # 检查端口是否监听 ss -tlnp | grep -E '8080|50051|50052' # 检查 PostgreSQL 连接 sudo -u postgres psql -c "SELECT 1;" # 检查 Redis 连接 redis-cli ping # 检查 RabbitMQ 连接 rabbitmqctl status # 查看服务错误日志 tail -100 /opt/mpc-system/logs/mpc-account.error.log # 手动启动服务调试 sudo -u mpc /opt/mpc-system/bin/account-service ``` ## 5. 后端服务器配置 (192.168.1.111) ### 5.1 Docker Compose 部署文件 在 192.168.1.111 服务器上创建 `/opt/rwadurian/docker-compose.yml`: ```yaml services: # ============================================ # 微服务 # ============================================ identity-service: build: ./services/identity-service ports: - "3000:3000" environment: - DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_identity - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - KAFKA_BROKERS=kafka:29092 - MPC_SERVICE_URL=http://mpc-service:3001 - BACKUP_SERVICE_URL=http://backup-service:3009 - APP_ENV=production depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - rwa-network restart: unless-stopped mpc-service: build: ./services/mpc-service ports: - "3001:3001" environment: - DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_mpc - REDIS_HOST=redis - APP_ENV=production # MPC-System 部署在 192.168.1.100 (Nginx 服务器) - MPC_SYSTEM_URL=http://192.168.1.100:4000 depends_on: postgres: condition: service_healthy networks: - rwa-network restart: unless-stopped wallet-service: build: ./services/wallet-service ports: - "3002:3002" environment: - DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_wallet - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - KAFKA_BROKERS=kafka:29092 - IDENTITY_SERVICE_URL=http://identity-service:3000 - APP_ENV=production depends_on: postgres: condition: service_healthy networks: - rwa-network restart: unless-stopped planting-service: build: ./services/planting-service ports: - "3003:3003" environment: - DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_planting - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - KAFKA_BROKERS=kafka:29092 - WALLET_SERVICE_URL=http://wallet-service:3002 - IDENTITY_SERVICE_URL=http://identity-service:3000 - APP_ENV=production depends_on: postgres: condition: service_healthy networks: - rwa-network restart: unless-stopped referral-service: build: ./services/referral-service ports: - "3004:3004" environment: - DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_referral - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - KAFKA_BROKERS=kafka:29092 - IDENTITY_SERVICE_URL=http://identity-service:3000 - PLANTING_SERVICE_URL=http://planting-service:3003 - APP_ENV=production depends_on: postgres: condition: service_healthy networks: - rwa-network restart: unless-stopped reward-service: build: ./services/reward-service ports: - "3005:3005" environment: - DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_reward - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - KAFKA_BROKERS=kafka:29092 - IDENTITY_SERVICE_URL=http://identity-service:3000 - WALLET_SERVICE_URL=http://wallet-service:3002 - REFERRAL_SERVICE_URL=http://referral-service:3004 - APP_ENV=production depends_on: postgres: condition: service_healthy networks: - rwa-network restart: unless-stopped authorization-service: build: ./services/authorization-service ports: - "3006:3006" environment: - DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_authorization - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - IDENTITY_SERVICE_URL=http://identity-service:3000 - APP_ENV=production depends_on: postgres: condition: service_healthy networks: - rwa-network restart: unless-stopped leaderboard-service: build: ./services/leaderboard-service ports: - "3007:3007" environment: - DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_leaderboard - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - KAFKA_BROKERS=kafka:29092 - IDENTITY_SERVICE_URL=http://identity-service:3000 - REFERRAL_SERVICE_URL=http://referral-service:3004 - APP_ENV=production depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - rwa-network restart: unless-stopped reporting-service: build: ./services/reporting-service ports: - "3008:3008" environment: - DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/rwa_reporting - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - KAFKA_BROKERS=kafka:29092 - APP_ENV=production depends_on: postgres: condition: service_healthy networks: - rwa-network restart: unless-stopped backup-service: build: ./services/backup-service ports: - "3009:3009" environment: - DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres-backup:5432/rwa_backup - SERVICE_JWT_SECRET=${SERVICE_JWT_SECRET} - APP_ENV=production networks: - rwa-network restart: unless-stopped # ============================================ # 基础设施 # ============================================ postgres: image: postgres:16-alpine environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=${DB_PASSWORD} volumes: - postgres_data:/var/lib/postgresql/data - ./scripts/init-databases.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 10 networks: - rwa-network restart: unless-stopped redis: image: redis:7-alpine command: redis-server --requirepass ${REDIS_PASSWORD} volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] interval: 5s timeout: 5s retries: 10 networks: - rwa-network restart: unless-stopped zookeeper: image: confluentinc/cp-zookeeper:7.5.0 environment: ZOOKEEPER_CLIENT_PORT: 2181 networks: - rwa-network restart: unless-stopped kafka: image: confluentinc/cp-kafka:7.5.0 depends_on: - zookeeper environment: KAFKA_BROKER_ID: 1 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT_INTERNAL://kafka:29092 KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT_INTERNAL:PLAINTEXT KAFKA_LISTENERS: PLAINTEXT_INTERNAL://0.0.0.0:29092 KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT_INTERNAL KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true" networks: - rwa-network restart: unless-stopped networks: rwa-network: driver: bridge volumes: postgres_data: redis_data: ``` ### 5.2 数据库初始化脚本 在 192.168.1.111 服务器上创建 `/opt/rwadurian/scripts/init-databases.sql`: ```sql -- 创建所有微服务数据库 CREATE DATABASE rwa_identity; CREATE DATABASE rwa_mpc; CREATE DATABASE rwa_wallet; CREATE DATABASE rwa_planting; CREATE DATABASE rwa_referral; CREATE DATABASE rwa_reward; CREATE DATABASE rwa_authorization; CREATE DATABASE rwa_leaderboard; CREATE DATABASE rwa_reporting; CREATE DATABASE rwa_backup; ``` ### 5.3 环境变量文件 在 192.168.1.111 服务器上创建 `/opt/rwadurian/.env`: ```bash # Database DB_PASSWORD=your_secure_database_password_here # JWT (所有服务共享) JWT_SECRET=your_super_secure_jwt_secret_at_least_32_characters # Redis REDIS_PASSWORD=your_secure_redis_password # Service JWT (服务间通信) SERVICE_JWT_SECRET=your_service_jwt_secret_for_internal_calls # Wallet Encryption WALLET_ENCRYPTION_SALT=your_wallet_encryption_salt ``` ## 6. 部署步骤 ### 6.1 Nginx + MPC 服务器 (192.168.1.100) 配置 ```bash # ============================================ # 步骤 1: 安装 Nginx 和 Let's Encrypt # ============================================ apt update && apt install -y nginx certbot python3-certbot-nginx # ============================================ # 步骤 2: 创建目录结构 # ============================================ mkdir -p /etc/nginx/sites-available mkdir -p /etc/nginx/sites-enabled mkdir -p /etc/nginx/snippets # ============================================ # 步骤 3: 获取 SSL 证书 (必须在配置 HTTPS 站点之前) # ============================================ # 重要:在全新系统上,必须先获取证书,否则 Nginx 配置引用证书路径会报错 # 方式 A: 使用 standalone 模式 (推荐用于首次部署) # 临时停止 Nginx (如果正在运行) systemctl stop nginx # 获取证书 certbot certonly --standalone -d rwaapi.szaiai.com # 证书保存位置: # /etc/letsencrypt/live/rwaapi.szaiai.com/fullchain.pem (完整证书链) # /etc/letsencrypt/live/rwaapi.szaiai.com/privkey.pem (私钥) # 方式 B: 使用 webroot 模式 (需要先配置 HTTP 站点) # 1. 先配置一个简单的 HTTP 站点 (不含 SSL) # 2. certbot certonly --webroot -w /var/www/html -d rwaapi.szaiai.com # ============================================ # 步骤 4: 复制 Nginx 配置文件 # ============================================ # 将上面的配置文件复制到对应目录: # - nginx.conf → /etc/nginx/nginx.conf # - proxy-params.conf → /etc/nginx/snippets/proxy-params.conf # - cors-params.conf → /etc/nginx/snippets/cors-params.conf # - ssl-params.conf → /etc/nginx/snippets/ssl-params.conf # - rwaapi.szaiai.com.conf → /etc/nginx/sites-available/rwaapi.szaiai.com.conf # ============================================ # 步骤 5: 启用站点 # ============================================ # 禁用默认站点 (如果存在) rm -f /etc/nginx/sites-enabled/default # 创建软链接启用站点 ln -s /etc/nginx/sites-available/rwaapi.szaiai.com.conf /etc/nginx/sites-enabled/ # ============================================ # 步骤 6: 测试并启动 Nginx # ============================================ # 测试配置 (此时证书已存在,不会报错) nginx -t # 启动 Nginx systemctl start nginx systemctl enable nginx # ============================================ # 步骤 7: 配置证书自动续期 # ============================================ # Let's Encrypt 证书有效期 90 天,certbot 已自动配置 systemd timer # 验证自动续期任务: systemctl list-timers | grep certbot # 手动测试续期 (不会实际续期,只是测试流程): certbot renew --dry-run # ============================================ # 站点管理命令 (日常运维) # ============================================ # 禁用站点: rm /etc/nginx/sites-enabled/rwaapi.szaiai.com.conf && nginx -s reload # 启用站点: ln -s /etc/nginx/sites-available/rwaapi.szaiai.com.conf /etc/nginx/sites-enabled/ && nginx -s reload # 重新加载: nginx -s reload # 查看状态: systemctl status nginx ``` ### 6.2 后端服务器 (192.168.1.111) 配置 ```bash # 1. 安装 Docker curl -fsSL https://get.docker.com | sh usermod -aG docker $USER # 2. 安装 Docker Compose apt install -y docker-compose-plugin # 3. 创建部署目录 mkdir -p /opt/rwadurian cd /opt/rwadurian # 4. 克隆代码 git clone https://github.com/your-org/rwadurian.git . # 5. 配置环境变量 cp .env.example .env vim .env # 修改为生产环境配置 # 6. 创建数据库初始化脚本 mkdir -p scripts # 将上面的 init-databases.sql 复制到 scripts/ # 7. 启动所有服务 docker compose up -d # 8. 查看服务状态 docker compose ps # 9. 运行数据库迁移 docker compose exec identity-service npx prisma migrate deploy docker compose exec wallet-service npx prisma migrate deploy docker compose exec planting-service npx prisma migrate deploy docker compose exec referral-service npx prisma migrate deploy docker compose exec reward-service npx prisma migrate deploy docker compose exec leaderboard-service npx prisma migrate deploy docker compose exec reporting-service npx prisma migrate deploy ``` ### 6.3 验证部署 ```bash # 从 Nginx 服务器测试 curl -k https://rwaapi.szaiai.com/health # 测试 API 端点 curl -k https://rwaapi.szaiai.com/api/v1/user/auto-create \ -H "Content-Type: application/json" \ -d '{"deviceId": "test-device-123"}' # 从后端服务器直接测试 curl http://localhost:3000/api/v1/user/auto-create \ -H "Content-Type: application/json" \ -d '{"deviceId": "test-device-123"}' ``` ## 7. API 端点对照表 | 前端调用路径 | Nginx 转发 | 后端服务 | 端口 | |-------------|-----------|---------|------| | `/api/v1/user/*` | → | Identity Service | 3000 | | `/api/v1/auth/*` | → | Identity Service | 3000 | | `/api/v1/wallet/*` | → | Wallet Service | 3002 | | `/api/v1/trading/*` | → | Wallet Service | 3002 | | `/api/v1/deposit/*` | → | Wallet Service | 3002 | | `/api/v1/mining/*` | → | Reward Service | 3005 | | `/api/v1/reward/*` | → | Reward Service | 3005 | | `/api/v1/ranking/*` | → | Leaderboard Service | 3007 | | `/api/v1/leaderboard/*` | → | Leaderboard Service | 3007 | | `/api/v1/planting/*` | → | Planting Service | 3003 | | `/api/v1/referral/*` | → | Referral Service | 3004 | | `/api/v1/community/*` | → | Referral Service | 3004 | | `/api/v1/telemetry/*` | → | Reporting Service | 3008 | | `/api/v1/report/*` | → | Reporting Service | 3008 | ## 8. 监控与运维 ### 8.1 查看 Nginx 日志 ```bash # 访问日志 tail -f /var/log/nginx/access.log # 错误日志 tail -f /var/log/nginx/error.log # 过滤特定服务请求 grep "/api/v1/user" /var/log/nginx/access.log | tail -100 ``` ### 8.2 查看服务日志 ```bash # ======================================== # 192.168.1.100 (Nginx + MPC 服务器) 日志 # ======================================== # MPC-System 日志 cd /home/ceshi/rwadurian/backend/mpc-system sudo bash scripts/deploy.sh logs mpc-account # 或 tail -f /opt/mpc-system/logs/mpc-account.log journalctl -u mpc-account -f # ======================================== # 192.168.1.111 (后端服务器) 日志 # ======================================== # 查看所有服务日志 docker compose logs -f # 查看特定服务日志 docker compose logs -f identity-service docker compose logs -f mpc-service docker compose logs -f wallet-service # 查看最近 100 行 docker compose logs --tail=100 identity-service ``` ### 8.3 服务健康检查 ```bash # ======================================== # 192.168.1.100 (Nginx + MPC 服务器) 健康检查 # ======================================== curl http://192.168.1.100:8080/health # MPC-System (原生端口) curl http://192.168.1.100:4000/health # MPC-System (代理端口) curl https://rwaapi.szaiai.com/health # Nginx 反向代理 # ======================================== # 192.168.1.111 (后端服务器) 健康检查 # ======================================== # 检查所有服务状态 docker compose ps # 检查各微服务健康 curl http://192.168.1.111:3000/health # Identity curl http://192.168.1.111:3001/health # MPC Service (NestJS) curl http://192.168.1.111:3002/health # Wallet curl http://192.168.1.111:3003/health # Planting curl http://192.168.1.111:3004/health # Referral curl http://192.168.1.111:3005/health # Reward curl http://192.168.1.111:3007/health # Leaderboard curl http://192.168.1.111:3008/health # Reporting ``` ### 8.4 重启服务 ```bash # 重启单个服务 docker compose restart identity-service # 重启所有服务 docker compose restart # 重建并重启 docker compose up -d --build identity-service ``` ## 9. 常见问题 ### Q1: 502 Bad Gateway - 检查后端服务是否运行: `docker compose ps` - 检查 Nginx 到 192.168.1.111 网络是否通: `ping 192.168.1.111` - 检查端口是否开放: `telnet 192.168.1.111 3000` ### Q2: CORS 错误 - 确认 Nginx 配置中 CORS 头已正确设置 - 检查 OPTIONS 预检请求是否返回 204 ### Q3: SSL 证书问题 - 检查 Let's Encrypt 证书: `ls -la /etc/letsencrypt/live/rwaapi.szaiai.com/` - 测试 SSL 连接: `openssl s_client -connect rwaapi.szaiai.com:443` - 检查证书有效期: `openssl x509 -in /etc/letsencrypt/live/rwaapi.szaiai.com/fullchain.pem -noout -dates` - 手动续期证书: `certbot renew` - 查看续期日志: `journalctl -u certbot.timer` ### Q4: 服务间通信失败 - 检查 Docker 网络: `docker network inspect rwa-network` - 检查服务名解析: `docker compose exec identity-service ping wallet-service` ### Q5: MPC-System 连接失败 - 检查 MPC-System 服务状态: `sudo bash scripts/deploy.sh status` (在 192.168.1.100 上) - 检查 MPC-System 健康: `curl http://192.168.1.100:4000/health` 或 `curl http://192.168.1.100:8080/health` - 检查防火墙规则是否允许 192.168.1.111 访问 4000/8080 端口 - 检查 mpc-service 环境变量 `MPC_SYSTEM_URL` 是否正确设置为 `http://192.168.1.100:4000` - 查看 MPC-System 日志: `tail -f /opt/mpc-system/logs/mpc-account.log` ### Q6: TSS 密钥生成/签名超时 - MPC 操作可能需要较长时间,检查超时配置 - 确保网络延迟在合理范围内: `ping 192.168.1.100` - 检查 MPC-System 资源使用: `htop` 或 `top` --- **最后更新**: 2025-12-01 **维护者**: RWA Team