所有服务运行在同一台服务器上,适合开发、测试或小规模演示环境。
┌─────────────────────────────────────────┐
│ 单台服务器 (8核/16GB) │
│ │
│ ┌────────────────────────────────┐ │
│ │ 数据服务 │ │
│ │ - MySQL │ │
│ │ - Redis Cache │ │
│ │ - Redis Market │ │
│ │ - Elasticsearch │ │
│ └────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────┐ │
│ │ 业务服务 │ │
│ │ - SODOS RunServer (Hyperf) │ │
│ │ - WS Gateway (Go) │ │
│ │ - Market Data (Go) │ │
│ └────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────┐ │
│ │ 前端服务 │ │
│ │ - Nginx │ │
│ │ - Manager Admin │ │
│ └────────────────────────────────┘ │
└─────────────────────────────────────────┘
将数据服务和业务服务隔离到不同的物理服务器,提高性能、稳定性和安全性。
┌──────────────────────────────┐
│ 数据工具服务器 (8核/32GB) │
│ │
│ - MySQL 8.0 │
│ - Redis Cache │
│ - Redis Market │
│ - Elasticsearch 8.12 │
│ - Market Data (Go) │
│ - Match Engine (Go) │
│ - Market Maker (Go) │
│ - LibreTranslate (可选) │
│ - ElasticVue (可选) │
│ │
│ 端口: 3306, 6380, 6381, │
│ 9200, 9000, 8080 │
└──────────────────────────────┘
↑
│ 内网通信
↓
┌──────────────────────────────┐
│ 业务服务器 (8核/16GB) │
│ │
│ - SODOS RunServer (Hyperf) │
│ - WS Gateway (Go) │
│ │
│ 端口: 9501, 9510, 9602 │
└──────────────────────────────┘
↑
│ HTTP/WebSocket
↓
┌──────────────────────────────┐
│ Web服务器 (4核/8GB) │
│ │
│ - Nginx (反向代理) │
│ - SODOS Manager (静态) │
│ - H5/PC 静态资源 │
│ │
│ 端口: 80, 443 │
└──────────────────────────────┘
↑
│ HTTPS
↓
[ 公网用户 ]
为什么 Market Data/Match Engine/Market Maker 在数据服务器?
这些服务需要频繁访问 MySQL、Redis 和 Elasticsearch,将它们与数据服务部署在同一服务器上可以:
如果追求极致性能或单机资源不足,可以将核心业务逻辑服务独立部署:
┌──────────────────────────────┐
│ 数据服务器 (8核/32GB) │
│ │
│ - MySQL 8.0 │
│ - Redis Cache │
│ - Redis Market │
│ - Elasticsearch 8.12 │
│ │
└──────────────────────────────┘
↑
│ 万兆内网
↓
┌──────────────────────────────┐
│ 核心服务器 (16核/32GB) │
│ │
│ - Market Data (Go) │
│ - Match Engine (Go) │
│ - Market Maker (Go) │
│ │
└──────────────────────────────┘
↑
│ 内网通信
↓
┌──────────────────────────────┐
│ 业务服务器 (8核/16GB) │
│ │
│ - SODOS RunServer (Hyperf) │
│ - WS Gateway (Go) │
│ │
└──────────────────────────────┘
↑
│ HTTP/WebSocket
↓
┌──────────────────────────────┐
│ Web服务器 (4核/8GB) │
│ │
│ - Nginx (反向代理) │
│ │
└──────────────────────────────┘
↑
│ HTTPS
↓
[ 公网用户 ]
生产环境建议
确保已完成 环境要求 文档中的所有配置:
# 检查 Docker 版本
docker --version
docker compose version
# 检查端口占用
sudo lsof -i :3306
sudo lsof -i :6380
sudo lsof -i :9200
# 检查内核参数
sysctl vm.max_map_count
# 检查磁盘空间
df -h
克隆或下载 SODOS_BUILD 部署配置仓库:
# 方式一:使用 Git 克隆
git clone https://github.com/sodos66/SODOS_BUILD.git
cd SODOS_BUILD
# 方式二:下载压缩包并解压
wget https://github.com/sodos66/SODOS_BUILD/archive/main.zip
unzip main.zip
cd SODOS_BUILD-main
重要
生产环境部署前必须修改默认密码,否则存在严重安全风险!
编辑 runner-compose.yml:
vim runner-compose.yml
修改以下密码配置:
# MySQL 密码
MYSQL_ROOT_PASSWORD: 请修改为强密码
MYSQL_PASSWORD: 请修改为强密码
# Elasticsearch 密码
ELASTIC_PASSWORD: 请修改为强密码
编辑 Redis 配置文件:
# Redis Cache
vim redis_cache/redis.conf
# 修改行: requirepass 请修改为强密码
# Redis Market
vim redis_market/redis.conf
# 修改行: requirepass 请修改为强密码
适合开发、测试环境,所有服务运行在一台服务器上。
运行初始化脚本:
chmod +x init-volumes.sh
./init-volumes.sh
脚本会自动:
redis_*/data、elasticsearch/data、mysql/data)首次启动需要拉取 Docker 镜像和初始化数据库,约需 5-10 分钟:
# 查看容器状态
docker compose -f runner-compose.yml ps
# 查看启动日志
docker compose -f runner-compose.yml logs -f
等待所有容器状态变为 healthy 或 Up。
docker exec -it mysql_sodos mysql -uroot -p
# 输入 MYSQL_ROOT_PASSWORD
# 验证数据库
SHOW DATABASES;
USE sodos_exchange;
SHOW TABLES;
EXIT;
# Redis Cache
docker exec -it redis_cache redis-cli -a 你的密码
PING
# 应返回 PONG
# Redis Market
docker exec -it redis_market redis-cli -a 你的密码
PING
curl -u elastic:你的密码 http://localhost:9200/_cluster/health?pretty
应返回 JSON 格式的集群健康状态。
进入 Nginx 目录:
cd nginx
编辑配置文件 conf.d/sodos_exchange.conf,修改域名:
server {
listen 80;
server_name api.yourdomain.com; # 修改为你的域名
# ...
}
server {
listen 80;
server_name manager.yourdomain.com; # 修改为你的域名
# ...
}
# 修改其他 server 块...
启动 Nginx:
docker compose up -d
将数据服务和业务服务分离到不同服务器,提高性能和安全性。
| 服务器 | 配置 | 服务 | 内网 IP 示例 |
|---|---|---|---|
| 数据服务器 | 8核/32GB/500GB SSD | MySQL, Redis, ES, Market Data, Match Engine, Market Maker | 192.168.1.10 |
| 业务服务器 | 8核/16GB/100GB SSD | SODOS RunServer, WS Gateway | 192.168.1.20 |
| Web服务器 | 4核/8GB/50GB SSD | Nginx | 公网IP: x.x.x.x |
| 服务器 | 配置 | 服务 | 内网 IP 示例 |
|---|---|---|---|
| 数据服务器 | 8核/32GB/500GB NVMe SSD | MySQL, Redis, ES | 192.168.1.10 |
| 核心服务器 | 16核/32GB/200GB SSD | Market Data, Match Engine, Market Maker | 192.168.1.11 |
| 业务服务器 | 8核/16GB/100GB SSD | SODOS RunServer, WS Gateway | 192.168.1.20 |
| Web服务器 | 4核/8GB/50GB SSD | Nginx | 公网IP: x.x.x.x |
SSH 登录到数据服务器,克隆部署文件:
cd ~
git clone https://github.com/sodos66/SODOS_BUILD.git
cd SODOS_BUILD
修改 runner-compose.yml,仅保留数据服务:
services:
redis_market:
# ... 保留 ...
redis_cache:
# ... 保留 ...
elasticsearch:
# ... 保留 ...
elasticvue:
# ... 保留(可选)...
libretranslate:
# ... 保留(可选)...
mysql:
# ... 保留 ...
# 删除或注释掉以下服务:
# sodos_runserver:
# ...
# sodos_manager:
# ...
修改网络配置,允许外部访问:
services:
mysql:
ports:
- "0.0.0.0:3306:3306" # 允许内网访问
redis_cache:
ports:
- "0.0.0.0:6380:6379"
redis_market:
ports:
- "0.0.0.0:6381:6379"
elasticsearch:
ports:
- "0.0.0.0:9200:9200"
- "0.0.0.0:9300:9300"
初始化并启动:
chmod +x init-volumes.sh
./init-volumes.sh
配置防火墙,仅允许业务服务器访问:
# Ubuntu/Debian (UFW)
sudo ufw allow from 192.168.1.20 to any port 3306 proto tcp
sudo ufw allow from 192.168.1.20 to any port 6380 proto tcp
sudo ufw allow from 192.168.1.20 to any port 6381 proto tcp
sudo ufw allow from 192.168.1.20 to any port 9200 proto tcp
sudo ufw enable
# CentOS/RHEL (firewalld)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.20" port protocol="tcp" port="3306" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.20" port protocol="tcp" port="6380" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.20" port protocol="tcp" port="6381" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.20" port protocol="tcp" port="9200" accept'
sudo firewall-cmd --reload
部署 Go 核心服务(Market Data、Match Engine、Market Maker):
cd ~
git clone https://github.com/sodos66/SODOS_EXCHANGE_GO.git
cd SODOS_EXCHANGE_GO
创建 .env 配置文件:
cat > .env << 'EOF'
# 数据库配置(本地访问)
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=sodos_exchange
DB_USERNAME=sodos_exchange
DB_PASSWORD=你的密码
# Redis 配置(本地访问)
REDIS_HOST=127.0.0.1
REDIS_PORT=6380
REDIS_AUTH=你的密码
REDIS_DB=0
# 行情 Redis 配置(本地访问)
MARKET_REDIS_HOST=127.0.0.1
MARKET_REDIS_PORT=6381
MARKET_REDIS_AUTH=你的密码
MARKET_REDIS_DB=0
# Elasticsearch 配置(本地访问)
ES_HOST=http://127.0.0.1:9200
ES_USERNAME=elastic
ES_PASSWORD=你的密码
# 代理配置(如果需要访问 Binance)
REQUEST_PROXY=true
HTTP_PROXY=http://your-proxy:port
EOF
编译并运行服务(使用 Docker 或直接编译):
# 方式一:使用 Docker Compose
docker compose up -d market-data match-engine market-maker
# 方式二:直接编译运行(需要 Go 1.20+)
cd services/market-data
go build -o bin/market-data cmd/market-data/main.go
nohup ./bin/market-data > logs/market-data.log 2>&1 &
cd ../match-engine
go build -o bin/match-engine cmd/match-engine/main.go
nohup ./bin/match-engine > logs/match-engine.log 2>&1 &
cd ../market-maker
go build -o bin/market-maker cmd/market-maker/main.go
nohup ./bin/market-maker > logs/market-maker.log 2>&1 &
为什么在数据服务器部署?
Market Data、Match Engine、Market Maker 需要极低延迟访问数据库和 Redis,部署在数据服务器上可以使用本地连接(127.0.0.1),避免网络延迟。
SSH 登录到业务服务器,克隆部署文件:
cd ~
git clone https://github.com/sodos66/SODOS_BUILD.git
cd SODOS_BUILD
修改 runner-compose.yml,仅保留业务服务:
services:
# 删除或注释掉数据服务:
# redis_market:
# redis_cache:
# elasticsearch:
# mysql:
# 保留业务服务:
sodos_runserver:
image: sodosexchange/run_server:prod
# ... 保留配置 ...
environment:
# 修改数据库连接为数据服务器 IP
- DB_HOST=192.168.1.10
- DB_PORT=3306
- REDIS_HOST=192.168.1.10
- REDIS_PORT=6380
- MARKET_REDIS_HOST=192.168.1.10
- MARKET_REDIS_PORT=6381
- ES_HOST=http://192.168.1.10:9200
# 移除 depends_on(因为服务不在同一网络)
或者修改 .env 文件(推荐):
# 创建 .env 文件
cat > app/SODOS_EXCHANGE/.env << 'EOF'
DB_HOST=192.168.1.10
DB_PORT=3306
DB_DATABASE=sodos_exchange
DB_USERNAME=sodos_exchange
DB_PASSWORD=你的密码
REDIS_HOST=192.168.1.10
REDIS_PORT=6380
REDIS_AUTH=你的密码
MARKET_REDIS_HOST=192.168.1.10
MARKET_REDIS_PORT=6381
MARKET_REDIS_AUTH=你的密码
ES_HOST=http://192.168.1.10:9200
ES_USERNAME=elastic
ES_PASSWORD=你的密码
EOF
启动业务服务:
docker compose -f runner-compose.yml up -d sodos_runserver
在业务服务器上部署 WS Gateway 服务:
cd ~
git clone https://github.com/sodos66/SODOS_EXCHANGE_GO.git
cd SODOS_EXCHANGE_GO
创建 .env 配置文件:
cat > .env << 'EOF'
# 数据库配置
DB_HOST=192.168.1.10
DB_PORT=3306
DB_DATABASE=sodos_exchange
DB_USERNAME=sodos_exchange
DB_PASSWORD=你的密码
# Redis 配置
REDIS_HOST=192.168.1.10
REDIS_PORT=6380
REDIS_AUTH=你的密码
REDIS_DB=0
# 行情 Redis 配置
MARKET_REDIS_HOST=192.168.1.10
MARKET_REDIS_PORT=6381
MARKET_REDIS_AUTH=你的密码
MARKET_REDIS_DB=0
# Elasticsearch 配置
ES_HOST=http://192.168.1.10:9200
ES_USERNAME=elastic
ES_PASSWORD=你的密码
# WebSocket Gateway 配置
WS_ADDR=:9602
EOF
编译并运行 WS Gateway:
# 方式一:使用 Docker Compose
docker compose up -d ws-gateway
# 方式二:直接编译运行(需要 Go 1.20+)
cd services/ws-gateway
go build -o bin/ws-gateway cmd/ws-gateway/main.go
nohup ./bin/ws-gateway > logs/ws-gateway.log 2>&1 &
SSH 登录到 Web 服务器:
cd ~
git clone https://github.com/sodos66/SODOS_BUILD.git
cd SODOS_BUILD/nginx
修改 Nginx 配置,upstream 指向业务服务器:
# conf.d/sodos_exchange.conf
upstream sodos_api {
server 192.168.1.20:9510; # 业务服务器 IP
# 如果有多台业务服务器,可以添加负载均衡
# server 192.168.1.21:9510;
keepalive 64;
}
upstream sodos_ws {
server 192.168.1.20:9602; # WS Gateway
keepalive 64;
}
server {
listen 80;
server_name api.yourdomain.com;
location / {
proxy_pass http://sodos_api;
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;
}
}
server {
listen 80;
server_name ws.yourdomain.com;
location /ws {
proxy_pass http://sodos_ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# 其他静态资源 server 块...
启动 Nginx:
docker compose up -d
配置 SSL 证书(可选,推荐):
# 使用 Certbot 自动获取 Let's Encrypt 证书
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d api.yourdomain.com -d manager.yourdomain.com
如果追求极致性能,可以将核心服务独立部署到专用服务器。
将 Market Data、Match Engine、Market Maker 从数据服务器移至核心服务器(192.168.1.11)。
按照标准三机部署的步骤 1,但不部署 Go 核心服务,仅部署:
防火墙需要同时允许核心服务器(192.168.1.11)访问:
# Ubuntu/Debian (UFW)
sudo ufw allow from 192.168.1.11 to any port 3306 proto tcp
sudo ufw allow from 192.168.1.11 to any port 6380 proto tcp
sudo ufw allow from 192.168.1.11 to any port 6381 proto tcp
sudo ufw allow from 192.168.1.11 to any port 9200 proto tcp
SSH 登录到核心服务器,克隆代码:
cd ~
git clone https://github.com/sodos66/SODOS_EXCHANGE_GO.git
cd SODOS_EXCHANGE_GO
创建 .env 配置文件(连接数据服务器):
cat > .env << 'EOF'
# 数据库配置(连接数据服务器)
DB_HOST=192.168.1.10
DB_PORT=3306
DB_DATABASE=sodos_exchange
DB_USERNAME=sodos_exchange
DB_PASSWORD=你的密码
# Redis 配置(连接数据服务器)
REDIS_HOST=192.168.1.10
REDIS_PORT=6380
REDIS_AUTH=你的密码
REDIS_DB=0
# 行情 Redis 配置(连接数据服务器)
MARKET_REDIS_HOST=192.168.1.10
MARKET_REDIS_PORT=6381
MARKET_REDIS_AUTH=你的密码
MARKET_REDIS_DB=0
# Elasticsearch 配置(连接数据服务器)
ES_HOST=http://192.168.1.10:9200
ES_USERNAME=elastic
ES_PASSWORD=你的密码
# 代理配置(如果需要访问 Binance)
REQUEST_PROXY=true
HTTP_PROXY=http://your-proxy:port
EOF
编译并运行核心服务:
# Market Data
cd services/market-data
go build -o bin/market-data cmd/market-data/main.go
nohup ./bin/market-data > logs/market-data.log 2>&1 &
# Match Engine
cd ../match-engine
go build -o bin/match-engine cmd/match-engine/main.go
nohup ./bin/match-engine > logs/match-engine.log 2>&1 &
# Market Maker
cd ../market-maker
go build -o bin/market-maker cmd/market-maker/main.go
nohup ./bin/market-maker > logs/market-maker.log 2>&1 &
按照标准三机部署的步骤 2-4 进行。
性能优化建议
正确的启动顺序可以避免服务依赖错误:
# 启动 MySQL
docker compose -f runner-compose.yml up -d mysql
# 等待 MySQL 就绪(约 30-60 秒)
docker compose -f runner-compose.yml logs -f mysql
# 启动 Redis
docker compose -f runner-compose.yml up -d redis_cache redis_market
# 启动 Elasticsearch
docker compose -f runner-compose.yml up -d elasticsearch
# 启动 Market Data(订阅外部行情)
cd ~/SODOS_EXCHANGE_GO/services/market-data && ./bin/market-data &
# 启动 Match Engine(撮合引擎)
cd ~/SODOS_EXCHANGE_GO/services/match-engine && ./bin/match-engine &
# 启动 Market Maker(做市策略)
cd ~/SODOS_EXCHANGE_GO/services/market-maker && ./bin/market-maker &
# 启动 SODOS RunServer(Hyperf 后端)
docker compose -f runner-compose.yml up -d sodos_runserver
# 启动 WS Gateway(WebSocket 服务)
cd ~/SODOS_EXCHANGE_GO/services/ws-gateway && ./bin/ws-gateway &
# 启动 Nginx
cd nginx && docker compose up -d
# MySQL
docker exec -it mysql_sodos mysqladmin -uroot -p你的密码 ping
# Redis Cache
docker exec -it redis_cache redis-cli -a 你的密码 ping
# Redis Market
docker exec -it redis_market redis-cli -a 你的密码 ping
# Elasticsearch
curl -u elastic:你的密码 http://localhost:9200/_cluster/health
# SODOS RunServer
curl http://localhost:9510/health
# WS Gateway
curl http://localhost:9602/health
# Market Data(查看日志)
tail -f logs/market-data.log
# 检查所有容器状态
docker compose -f runner-compose.yml ps
# 应该看到所有容器状态为 Up 或 healthy
错误:max virtual memory areas vm.max_map_count [65530] is too low
解决:
sudo sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
错误:Connection refused 或 Access denied
解决:
# 检查 MySQL 是否启动
docker compose -f runner-compose.yml ps mysql
# 检查网络连通性
telnet 192.168.1.10 3306
# 检查防火墙规则
sudo ufw status
错误:Could not connect to Redis
解决:
# 检查 Redis 配置中的 bind 地址
docker exec -it redis_cache cat /usr/local/etc/redis/redis.conf | grep bind
# 应该是 bind 0.0.0.0,而非 127.0.0.1
错误:WebSocket 频繁断开重连
解决:
# 检查 Nginx 超时配置
# 在 nginx.conf 中添加:
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 75s;
错误:port is already allocated
解决:
# 查找占用端口的进程
sudo lsof -i :3306
# 停止占用端口的服务
sudo systemctl stop mysql # 如果是系统自带的 MySQL
# 拉取最新镜像
docker compose -f runner-compose.yml pull
# 重启服务(使用新镜像)
docker compose -f runner-compose.yml up -d --force-recreate
# MySQL 备份
docker exec mysql_sodos mysqldump -uroot -p你的密码 sodos_exchange > backup_$(date +%Y%m%d).sql
# Redis 备份(RDB 文件)
docker exec redis_cache redis-cli -a 你的密码 SAVE
cp redis_cache/data/dump.rdb backup/redis_cache_$(date +%Y%m%d).rdb
# Elasticsearch 快照
curl -X PUT "http://localhost:9200/_snapshot/my_backup/snapshot_$(date +%Y%m%d)" \
-u elastic:你的密码
# 查看日志
docker compose -f runner-compose.yml logs -f --tail 100 mysql
docker compose -f runner-compose.yml logs -f --tail 100 sodos_runserver
# 清理旧日志
docker system prune -a --volumes # 危险:会删除所有未使用的数据
安装完成后,您可以:
提示
生产环境建议配置: