2025-10-16 18:54:27 +08:00
|
|
|
|
# M2Pool Payment System v2
|
|
|
|
|
|
|
|
|
|
|
|
<div align="center">
|
|
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
**基于以太坊区块链的分布式支付系统**
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
|
|
|
|
|
[](https://golang.org)
|
|
|
|
|
|
[](https://ethereum.org)
|
|
|
|
|
|
[](https://www.rabbitmq.com)
|
|
|
|
|
|
[](https://www.mysql.com)
|
2025-10-21 10:58:58 +08:00
|
|
|
|
[](LICENSE)
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
|
|
|
|
|
支持 **充值**、**提现**、**支付** 三大核心功能,实时监听链上交易,自动确认到账。
|
|
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
基于 Go 1.24 + Ethereum + RabbitMQ + MySQL 技术栈构建的企业级支付解决方案。
|
|
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
[快速开始](#快速开始) • [项目架构](#项目架构) • [功能特性](#功能特性) • [性能测试](#性能测试) • [常见问题](#常见问题)
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 📋 目录
|
|
|
|
|
|
|
|
|
|
|
|
- [项目简介](#项目简介)
|
2025-10-27 16:27:33 +08:00
|
|
|
|
- [项目架构](#项目架构)
|
2025-10-16 18:54:27 +08:00
|
|
|
|
- [功能特性](#功能特性)
|
|
|
|
|
|
- [快速开始](#快速开始)
|
|
|
|
|
|
- [配置说明](#配置说明)
|
|
|
|
|
|
- [使用示例](#使用示例)
|
|
|
|
|
|
- [常见问题](#常见问题)
|
2025-10-27 16:27:33 +08:00
|
|
|
|
- [部署指南](#部署指南)
|
|
|
|
|
|
- [性能测试](#性能测试)
|
2025-10-16 18:54:27 +08:00
|
|
|
|
- [贡献指南](#贡献指南)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 项目简介
|
|
|
|
|
|
|
|
|
|
|
|
M2Pool Payment System v2 是一个基于以太坊区块链的**分布式支付解决方案**,提供完整的数字货币充值、提现、支付功能。
|
|
|
|
|
|
|
|
|
|
|
|
### 核心能力
|
|
|
|
|
|
|
|
|
|
|
|
- 🔍 **实时监听**:订阅链上事件,实时检测 USDT 转账
|
|
|
|
|
|
- ⚡ **快速确认**:20 个区块确认,约 4-5 分钟到账
|
|
|
|
|
|
- 🔒 **安全可靠**:私钥加密存储,签名验证机制
|
2025-10-27 16:27:33 +08:00
|
|
|
|
- 📊 **高并发**:支持中等并发(50-200 TPS)
|
2025-10-16 18:54:27 +08:00
|
|
|
|
- 🔄 **自动重连**:WebSocket 断开自动重连
|
|
|
|
|
|
- 📨 **消息队列**:基于 RabbitMQ 的异步通信
|
|
|
|
|
|
|
|
|
|
|
|
### 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 组件 | 技术 | 版本 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| **语言** | Go | 1.24+ |
|
|
|
|
|
|
| **区块链** | Ethereum | go-ethereum v1.16.4 |
|
|
|
|
|
|
| **消息队列** | RabbitMQ | amqp091-go v1.10.0 |
|
|
|
|
|
|
| **数据库** | MySQL | 8.0+ |
|
|
|
|
|
|
| **网络协议** | WebSocket + RPC | - |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
## 项目架构
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
|
|
|
|
|
### 系统架构图
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ 业务系统 │
|
|
|
|
|
|
│ (Web/App/API Server) │
|
|
|
|
|
|
└────────────┬────────────────────────────┬───────────────────┘
|
|
|
|
|
|
│ │
|
|
|
|
|
|
│ 请求 │ 响应
|
|
|
|
|
|
↓ ↑
|
|
|
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ RabbitMQ │
|
|
|
|
|
|
│ ┌─────────┐ ┌──────────┐ ┌────────┐ │
|
|
|
|
|
|
│ │ topup │ │ withdraw │ │ pay │ 请求队列 │
|
|
|
|
|
|
│ └─────────┘ └──────────┘ └────────┘ │
|
|
|
|
|
|
│ ┌─────────┐ ┌──────────┐ ┌────────┐ │
|
|
|
|
|
|
│ │topup_ │ │withdraw_ │ │ pay_ │ 响应队列 │
|
|
|
|
|
|
│ │ resp │ │ resp │ │ resp │ │
|
|
|
|
|
|
│ └─────────┘ └──────────┘ └────────┘ │
|
|
|
|
|
|
└────────────┬────────────────────────────┬───────────────────┘
|
|
|
|
|
|
│ │
|
|
|
|
|
|
↓ ↑
|
|
|
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ M2Pool Payment System v2 │
|
|
|
|
|
|
│ │
|
|
|
|
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
|
|
|
|
|
│ │ RabbitMQ │ │ Blockchain │ │ Database │ │
|
|
|
|
|
|
│ │ Consumer │─>│ Manager │─>│ (MySQL) │ │
|
|
|
|
|
|
│ └──────────────┘ └──────┬───────┘ └──────────────┘ │
|
|
|
|
|
|
│ │ │
|
|
|
|
|
|
│ │ WebSocket + RPC │
|
|
|
|
|
|
└────────────────────────────┼─────────────────────────────────┘
|
|
|
|
|
|
│
|
|
|
|
|
|
↓
|
|
|
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
|
|
|
│ 以太坊区块链网络 │
|
|
|
|
|
|
│ │
|
|
|
|
|
|
│ ┌──────────────┐ ┌──────────────┐ │
|
|
|
|
|
|
│ │ 新区块 │ │ USDT Transfer │ │
|
|
|
|
|
|
│ │ (NewHead) │ │ 事件 │ │
|
|
|
|
|
|
│ └──────────────┘ └──────────────┘ │
|
|
|
|
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 核心模块
|
|
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
#### 1. Blockchain Manager (`internal/blockchain/`)
|
|
|
|
|
|
- **blockchain.go**:统一的区块链接口定义
|
|
|
|
|
|
- **eth/eth.go**:以太坊节点实现
|
|
|
|
|
|
- 监听 USDT Transfer 事件(实时检测充值)
|
|
|
|
|
|
- 监听新区块产生(触发交易确认)
|
|
|
|
|
|
- 管理待确认交易池(UnConfirmTxs)
|
|
|
|
|
|
- 执行 ERC20 转账(提现/支付)
|
2025-10-16 18:54:27 +08:00
|
|
|
|
- 自动重连机制
|
2025-10-21 10:58:58 +08:00
|
|
|
|
- 地址统一小写处理
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. Message Queue (`internal/queue/`)
|
|
|
|
|
|
- **rabbitmq.go**:RabbitMQ 消息队列服务
|
|
|
|
|
|
- 消费 3 个请求队列(充值/提现/支付)
|
|
|
|
|
|
- 发布 3 个响应队列(交易确认结果)
|
|
|
|
|
|
- 自动重连和错误重试
|
|
|
|
|
|
- 消息持久化
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
#### 3. Database (`internal/db/`)
|
|
|
|
|
|
- **db.go**:MySQL 数据库连接池
|
2025-10-16 18:54:27 +08:00
|
|
|
|
- 存储钱包私钥(加密)
|
2025-10-21 10:58:58 +08:00
|
|
|
|
- 连接池管理
|
|
|
|
|
|
- 事务支持
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
#### 4. Message (`internal/msg/`)
|
2025-10-16 18:54:27 +08:00
|
|
|
|
- **msg.go**:消息结构定义
|
2025-10-21 10:58:58 +08:00
|
|
|
|
- 请求消息(TopupMsg_req, WithdrawMsg_req, PayMsg_req)
|
|
|
|
|
|
- 响应消息(TopupMsg_resp, WithdrawMsg_resp, PayMsg_resp)
|
|
|
|
|
|
- 配置结构(Config, RMQConfig, ETHConfig)
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
#### 5. Utils (`internal/utils/`)
|
2025-10-16 18:54:27 +08:00
|
|
|
|
- **utils.go**:工具函数
|
2025-10-21 10:58:58 +08:00
|
|
|
|
- 数值转换(BigInt ↔ Float64)
|
|
|
|
|
|
- 哈希计算
|
2025-10-16 18:54:27 +08:00
|
|
|
|
- 加密解密
|
|
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
#### 6. Crypto (`internal/crypto/`)
|
|
|
|
|
|
- **crypto.go**:加密工具
|
|
|
|
|
|
- SHA256 哈希
|
|
|
|
|
|
- 签名验证
|
|
|
|
|
|
|
|
|
|
|
|
#### 7. Server (`internal/server.go`)
|
|
|
|
|
|
- 服务启动和管理
|
|
|
|
|
|
- 消息路由和处理
|
|
|
|
|
|
- 优雅关闭
|
|
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### 项目结构
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
m2pool-payment-v2/
|
|
|
|
|
|
├── cmd/ # 主程序入口
|
|
|
|
|
|
│ └── main.go # 程序入口,解析命令行参数
|
|
|
|
|
|
├── internal/ # 内部包(不对外暴露)
|
|
|
|
|
|
│ ├── server.go # 服务启动和管理
|
|
|
|
|
|
│ ├── blockchain/ # 区块链交互模块
|
|
|
|
|
|
│ │ ├── blockchain.go # 统一的区块链接口定义
|
|
|
|
|
|
│ │ ├── eth/ # 以太坊实现
|
|
|
|
|
|
│ │ │ └── eth.go # USDT 监听、转账、确认
|
|
|
|
|
|
│ │ └── tron/ # TRON 实现(待开发)
|
|
|
|
|
|
│ ├── crypto/ # 加密工具
|
|
|
|
|
|
│ │ └── crypto.go # SHA256、签名验证
|
|
|
|
|
|
│ ├── db/ # 数据库
|
|
|
|
|
|
│ │ ├── db.go # MySQL 连接池管理
|
|
|
|
|
|
│ │ └── sqlite.go # SQLite 本地存储
|
|
|
|
|
|
│ ├── msg/ # 消息定义
|
|
|
|
|
|
│ │ └── msg.go # 请求/响应结构体定义
|
|
|
|
|
|
│ ├── queue/ # 消息队列
|
|
|
|
|
|
│ │ ├── rabbitmq.go # RabbitMQ 客户端封装
|
|
|
|
|
|
│ │ └── README.md # RabbitMQ 使用文档
|
|
|
|
|
|
│ ├── logger/ # 日志记录
|
|
|
|
|
|
│ │ └── transaction_logger.go # 交易日志
|
|
|
|
|
|
│ └── utils/ # 工具函数
|
|
|
|
|
|
│ └── utils.go # 类型转换、格式化
|
|
|
|
|
|
├── public/ # 公共资源
|
|
|
|
|
|
│ ├── SQLite3.sql # SQLite 表结构
|
|
|
|
|
|
│ └── migration.sql # 数据库迁移脚本
|
|
|
|
|
|
├── test/ # 测试和示例
|
|
|
|
|
|
│ ├── test.go # 测试程序(独立运行)
|
|
|
|
|
|
│ └── config.json # 配置文件
|
|
|
|
|
|
├── go.mod # Go 模块定义
|
|
|
|
|
|
├── go.sum # 依赖版本锁定
|
|
|
|
|
|
└── README.md # 项目文档(本文件)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 核心特性详解
|
|
|
|
|
|
|
|
|
|
|
|
#### 1. 双重监听机制 🎯
|
|
|
|
|
|
|
|
|
|
|
|
系统同时监听两种链上事件:
|
|
|
|
|
|
|
|
|
|
|
|
**① USDT Transfer 事件监听**
|
|
|
|
|
|
```go
|
|
|
|
|
|
// 检测 USDT 转账,用于充值检测和交易确认触发
|
|
|
|
|
|
e.WsClient.SubscribeFilterLogs(query, e.USDT.LogsChan)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**② 新区块头监听**
|
|
|
|
|
|
```go
|
|
|
|
|
|
// 每个新区块触发交易确认检查,确保及时确认
|
|
|
|
|
|
e.WsClient.SubscribeNewHead(e.Ctx, headers)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 智能交易确认 ⚡
|
|
|
|
|
|
|
|
|
|
|
|
**事件驱动 + 区块驱动**:
|
|
|
|
|
|
- Transfer 事件到达时立即检查
|
|
|
|
|
|
- 每个新区块产生时也检查
|
|
|
|
|
|
- **确保交易在第 20 个区块后立即确认**
|
|
|
|
|
|
|
|
|
|
|
|
#### 3. 地址统一规范 🔡
|
|
|
|
|
|
|
|
|
|
|
|
所有以太坊地址**统一转换为小写**:
|
|
|
|
|
|
- 存储时转换
|
|
|
|
|
|
- 比较时转换
|
|
|
|
|
|
- 查询时转换
|
|
|
|
|
|
|
|
|
|
|
|
避免大小写不一致导致的匹配失败。
|
|
|
|
|
|
|
|
|
|
|
|
#### 4. 并发安全设计 🔒
|
|
|
|
|
|
|
|
|
|
|
|
- `sync.Map` 用于高并发地址监听
|
|
|
|
|
|
- `sync.Mutex` 保护共享数据结构
|
|
|
|
|
|
- Channel 缓冲区防止阻塞
|
|
|
|
|
|
- Goroutine panic 恢复机制
|
|
|
|
|
|
|
|
|
|
|
|
#### 5. 余额智能管理 💰
|
|
|
|
|
|
|
|
|
|
|
|
**自动归集钱包切换:**
|
|
|
|
|
|
```
|
|
|
|
|
|
用户钱包余额 < 转账金额
|
|
|
|
|
|
↓
|
|
|
|
|
|
自动使用归集钱包
|
|
|
|
|
|
↓
|
|
|
|
|
|
确保交易成功
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 6. Gas 费用检查 ⛽
|
|
|
|
|
|
|
|
|
|
|
|
转账前自动检查:
|
|
|
|
|
|
- USDT 余额是否足够
|
|
|
|
|
|
- ETH 余额是否足够支付 Gas
|
|
|
|
|
|
- 预估 Gas 价格
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 功能特性
|
|
|
|
|
|
|
|
|
|
|
|
### 1. 充值功能 💰
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
用户转账 → 实时检测 → 待确认通知 → 区块确认 → 最终通知
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**特点:**
|
|
|
|
|
|
- ✅ 实时检测到账
|
|
|
|
|
|
- ✅ 发送**两次**通知:待确认 + 最终确认
|
|
|
|
|
|
- ✅ 支持多币种(当前支持 USDT)
|
|
|
|
|
|
- ✅ 自动地址监听管理
|
|
|
|
|
|
|
|
|
|
|
|
**消息流:**
|
|
|
|
|
|
1. 业务系统发送充值请求 → RabbitMQ
|
|
|
|
|
|
2. 系统添加地址监听
|
|
|
|
|
|
3. 用户转账 → 立即通知(status=2 待确认)
|
|
|
|
|
|
4. 等待 20 个区块 → 最终通知(status=1 成功 / 0 失败)
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 提现功能 💸
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
提现请求 → 验证余额 → 发送交易 → 等待确认 → 返回结果
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**特点:**
|
|
|
|
|
|
- ✅ 自动余额检查
|
|
|
|
|
|
- ✅ 余额不足时使用归集钱包
|
|
|
|
|
|
- ✅ 发送**一次**通知:最终确认
|
|
|
|
|
|
- ✅ Gas 费用检查
|
|
|
|
|
|
|
|
|
|
|
|
**消息流:**
|
|
|
|
|
|
1. 业务系统发送提现请求 → RabbitMQ
|
|
|
|
|
|
2. 系统验证余额并发送交易
|
|
|
|
|
|
3. 等待 20 个区块确认
|
|
|
|
|
|
4. 返回结果(status=1 成功 / 0 失败)
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 支付功能 💳
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
支付请求 → 验证余额 → 发送交易 → 等待确认 → 返回结果
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**特点:**
|
|
|
|
|
|
- ✅ 订单关联
|
|
|
|
|
|
- ✅ 自动余额检查
|
|
|
|
|
|
- ✅ 发送**一次**通知:最终确认
|
|
|
|
|
|
- ✅ 支持商户收款
|
|
|
|
|
|
|
|
|
|
|
|
**消息流:**
|
|
|
|
|
|
1. 业务系统发送支付请求(含订单ID)→ RabbitMQ
|
|
|
|
|
|
2. 系统验证余额并发送交易
|
|
|
|
|
|
3. 等待 20 个区块确认
|
|
|
|
|
|
4. 返回结果(status=1 成功 / 0 失败)
|
|
|
|
|
|
|
2025-10-16 18:54:27 +08:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 快速开始
|
|
|
|
|
|
|
|
|
|
|
|
### 前置条件
|
|
|
|
|
|
|
|
|
|
|
|
- ✅ Go 1.24 或更高版本
|
|
|
|
|
|
- ✅ MySQL 8.0+
|
|
|
|
|
|
- ✅ RabbitMQ 3.x+
|
|
|
|
|
|
- ✅ 以太坊节点(支持 WebSocket 和 RPC)
|
|
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
### 安装步骤
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 1. 克隆项目
|
|
|
|
|
|
git clone <repository-url>
|
|
|
|
|
|
cd m2pool-payment-v2
|
|
|
|
|
|
|
|
|
|
|
|
# 2. 安装依赖
|
|
|
|
|
|
go mod download
|
|
|
|
|
|
|
|
|
|
|
|
# 3. 创建数据库
|
2025-10-21 10:58:58 +08:00
|
|
|
|
mysql -u root -p
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```sql
|
|
|
|
|
|
CREATE DATABASE payment CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
|
|
|
|
USE payment;
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
-- 创建钱包余额表
|
|
|
|
|
|
CREATE TABLE `eth_balance` (
|
|
|
|
|
|
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
|
|
|
|
|
`address` VARCHAR(42) NOT NULL UNIQUE,
|
|
|
|
|
|
`private_key` VARCHAR(255) NOT NULL COMMENT '加密后的私钥',
|
|
|
|
|
|
`balance` DECIMAL(20, 8) DEFAULT 0,
|
|
|
|
|
|
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
|
|
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
|
|
|
INDEX `idx_address` (`address`)
|
|
|
|
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='ETH钱包表';
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
2025-10-16 18:54:27 +08:00
|
|
|
|
# 4. 配置文件
|
2025-10-21 10:58:58 +08:00
|
|
|
|
cd test
|
|
|
|
|
|
cp config.json config.json.backup
|
2025-10-16 18:54:27 +08:00
|
|
|
|
# 编辑 config.json,填入实际配置
|
|
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
# 5. 编译主程序
|
|
|
|
|
|
cd ..
|
2025-10-16 18:54:27 +08:00
|
|
|
|
go build -o m2pool-payment cmd/main.go
|
|
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
# 6. 运行(指定通信密钥)
|
|
|
|
|
|
./m2pool-payment -key=your_secret_key
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
# 或者运行测试程序
|
2025-10-16 18:54:27 +08:00
|
|
|
|
cd test
|
|
|
|
|
|
go run test.go
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-10-21 10:58:58 +08:00
|
|
|
|
### 配置文件示例
|
|
|
|
|
|
|
|
|
|
|
|
创建 `test/config.json`:
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"rmq_config": {
|
2025-10-27 16:27:33 +08:00
|
|
|
|
"sub_addr": "amqp://m2pool:m2pool@localhost:5672",
|
2025-10-16 18:54:27 +08:00
|
|
|
|
"pay": {
|
|
|
|
|
|
"queue": "pay.auto.queue",
|
|
|
|
|
|
"exchange": "pay.exchange",
|
|
|
|
|
|
"routing": ["pay.auto.routing.key"]
|
|
|
|
|
|
},
|
|
|
|
|
|
"topup": {
|
|
|
|
|
|
"queue": "pay.recharge.queue",
|
|
|
|
|
|
"exchange": "pay.exchange",
|
|
|
|
|
|
"routing": ["pay.recharge.routing.key"]
|
|
|
|
|
|
},
|
|
|
|
|
|
"withdraw": {
|
|
|
|
|
|
"queue": "pay.withdraw.queue",
|
|
|
|
|
|
"exchange": "pay.exchange",
|
|
|
|
|
|
"routing": ["pay.withdraw.routing.key"]
|
|
|
|
|
|
},
|
|
|
|
|
|
"pay_resp": {
|
|
|
|
|
|
"queue": "pay.auto.return.queue",
|
|
|
|
|
|
"exchange": "pay.exchange",
|
|
|
|
|
|
"routing": ["pay.auto.return.routing.key"]
|
|
|
|
|
|
},
|
|
|
|
|
|
"topup_resp": {
|
|
|
|
|
|
"queue": "pay.recharge.return.queue",
|
|
|
|
|
|
"exchange": "pay.exchange",
|
|
|
|
|
|
"routing": ["pay.recharge.return.routing.key"]
|
|
|
|
|
|
},
|
|
|
|
|
|
"withdraw_resp": {
|
|
|
|
|
|
"queue": "pay.withdraw.return.queue",
|
|
|
|
|
|
"exchange": "pay.exchange",
|
|
|
|
|
|
"routing": ["pay.withdraw.return.routing.key"]
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
"eth_config": {
|
|
|
|
|
|
"rpcUrl": "http://localhost:8545",
|
|
|
|
|
|
"wsUrl": "ws://localhost:8546",
|
|
|
|
|
|
"confirmHeight": 20,
|
|
|
|
|
|
"dbConfig": {
|
|
|
|
|
|
"user": "root",
|
|
|
|
|
|
"password": "your_password",
|
|
|
|
|
|
"host": "127.0.0.1",
|
|
|
|
|
|
"port": 3306,
|
|
|
|
|
|
"database": "payment",
|
|
|
|
|
|
"maxOpenConns": 20,
|
|
|
|
|
|
"maxIdleCoons": 20,
|
|
|
|
|
|
"connMaxLife": 120
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 配置说明
|
|
|
|
|
|
|
2025-10-16 18:54:27 +08:00
|
|
|
|
### 配置项说明
|
|
|
|
|
|
|
|
|
|
|
|
| 配置项 | 说明 | 默认值 | 必填 |
|
|
|
|
|
|
|--------|------|--------|------|
|
|
|
|
|
|
| `rmq_config.sub_addr` | RabbitMQ 连接地址 | - | ✅ |
|
|
|
|
|
|
| `eth_config.rpcUrl` | 以太坊 RPC 地址 | - | ✅ |
|
|
|
|
|
|
| `eth_config.wsUrl` | 以太坊 WebSocket 地址 | - | ✅ |
|
|
|
|
|
|
| `eth_config.confirmHeight` | 确认区块数 | 20 | ✅ |
|
|
|
|
|
|
| `dbConfig.user` | 数据库用户名 | root | ✅ |
|
|
|
|
|
|
| `dbConfig.password` | 数据库密码 | - | ✅ |
|
|
|
|
|
|
| `dbConfig.database` | 数据库名称 | payment | ✅ |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 使用示例
|
|
|
|
|
|
|
|
|
|
|
|
### 1. 充值流程
|
|
|
|
|
|
|
|
|
|
|
|
**步骤 1:业务系统发送充值请求**
|
|
|
|
|
|
|
|
|
|
|
|
发送到 RabbitMQ 队列:`pay.recharge.queue`
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"chain": "ETH",
|
|
|
|
|
|
"symbol": "USDT",
|
|
|
|
|
|
"address": "0x4e5b2e1dc63f6b91cb6cd759936495434c7e972f",
|
|
|
|
|
|
"timestamp": 1758610297,
|
|
|
|
|
|
"sign": "signature_hash"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**步骤 2:用户转账**
|
|
|
|
|
|
|
|
|
|
|
|
用户向指定地址转账 USDT
|
|
|
|
|
|
|
|
|
|
|
|
**步骤 3:接收通知**
|
|
|
|
|
|
|
|
|
|
|
|
从 RabbitMQ 队列:`pay.recharge.return.queue` 接收**两次**消息:
|
|
|
|
|
|
|
|
|
|
|
|
第一次(待确认):
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"address": "0x4e5b2e1dc63f6b91cb6cd759936495434c7e972f",
|
|
|
|
|
|
"status": 2,
|
|
|
|
|
|
"chain": "ETH",
|
|
|
|
|
|
"symbol": "USDT",
|
|
|
|
|
|
"amount": 100.5,
|
|
|
|
|
|
"tx_hash": "0xabc..."
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
第二次(最终确认):
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"address": "0x4e5b2e1dc63f6b91cb6cd759936495434c7e972f",
|
|
|
|
|
|
"status": 1,
|
|
|
|
|
|
"chain": "ETH",
|
|
|
|
|
|
"symbol": "USDT",
|
|
|
|
|
|
"amount": 100.5,
|
|
|
|
|
|
"tx_hash": "0xabc..."
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 提现流程
|
|
|
|
|
|
|
|
|
|
|
|
**步骤 1:业务系统发送提现请求**
|
|
|
|
|
|
|
|
|
|
|
|
发送到 RabbitMQ 队列:`pay.withdraw.queue`
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"queue_id": "withdraw_123",
|
|
|
|
|
|
"from_address": "0x1111...",
|
|
|
|
|
|
"to_address": "0x2222...",
|
|
|
|
|
|
"amount": 50.0,
|
|
|
|
|
|
"chain": "ETH",
|
|
|
|
|
|
"symbol": "USDT",
|
|
|
|
|
|
"timestamp": 1758610297,
|
|
|
|
|
|
"sign": "signature_hash"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**步骤 2:系统处理**
|
|
|
|
|
|
|
|
|
|
|
|
- 验证签名
|
|
|
|
|
|
- 检查余额
|
|
|
|
|
|
- 发送链上交易
|
|
|
|
|
|
- 等待确认
|
|
|
|
|
|
|
|
|
|
|
|
**步骤 3:接收通知**
|
|
|
|
|
|
|
|
|
|
|
|
从 RabbitMQ 队列:`pay.withdraw.return.queue` 接收**一次**消息:
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"queue_id": "withdraw_123",
|
|
|
|
|
|
"status": 1,
|
|
|
|
|
|
"amount": 50.0,
|
|
|
|
|
|
"chain": "ETH",
|
|
|
|
|
|
"symbol": "USDT",
|
|
|
|
|
|
"tx_hash": "0xdef..."
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 支付流程
|
|
|
|
|
|
|
|
|
|
|
|
**步骤 1:业务系统发送支付请求**
|
|
|
|
|
|
|
|
|
|
|
|
发送到 RabbitMQ 队列:`pay.auto.queue`
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"queue_id": "pay_456",
|
|
|
|
|
|
"from_address": "0x1111...",
|
|
|
|
|
|
"to_address": "0x3333...",
|
|
|
|
|
|
"amount": 200.0,
|
|
|
|
|
|
"chain": "ETH",
|
|
|
|
|
|
"symbol": "USDT",
|
|
|
|
|
|
"order_id": "order_789",
|
|
|
|
|
|
"timestamp": 1758610297,
|
|
|
|
|
|
"sign": "signature_hash"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**步骤 2:系统处理**
|
|
|
|
|
|
|
|
|
|
|
|
- 验证签名
|
|
|
|
|
|
- 检查余额
|
|
|
|
|
|
- 发送链上交易
|
|
|
|
|
|
- 等待确认
|
|
|
|
|
|
|
|
|
|
|
|
**步骤 3:接收通知**
|
|
|
|
|
|
|
|
|
|
|
|
从 RabbitMQ 队列:`pay.auto.return.queue` 接收**一次**消息:
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"queue_id": "pay_456",
|
|
|
|
|
|
"status": 1,
|
|
|
|
|
|
"amount": 200.0,
|
|
|
|
|
|
"chain": "ETH",
|
|
|
|
|
|
"symbol": "USDT",
|
|
|
|
|
|
"order_id": "order_789",
|
|
|
|
|
|
"tx_hash": "0xghi..."
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
## 常见问题
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### Q1: 为什么充值会收到两次通知?
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**A:** 这是设计特性!
|
|
|
|
|
|
- **第一次**(status=2):检测到交易,提醒用户"正在确认"
|
|
|
|
|
|
- **第二次**(status=1/0):交易确认,通知最终结果
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
业务系统应该:
|
|
|
|
|
|
- status=2:显示进度,**不增加余额**
|
|
|
|
|
|
- status=1:增加余额
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### Q2: 提现/支付为什么只有一次通知?
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**A:** 因为是系统主动发起的交易,用户已经知道在处理中,不需要额外的待确认通知。
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### Q3: 如何处理交易失败?
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**A:** 系统会返回 status=0 的消息,业务系统应该:
|
|
|
|
|
|
- 充值失败:不增加余额,提示用户联系客服
|
|
|
|
|
|
- 提现失败:退回用户余额
|
|
|
|
|
|
- 支付失败:恢复订单状态,退回余额
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### Q4: 确认需要多长时间?
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**A:** 配置为 20 个区块确认,以太坊约 12 秒/块:
|
|
|
|
|
|
- 理论时间:20 × 12 = 240 秒(4 分钟)
|
|
|
|
|
|
- 实际时间:4-5 分钟(包括网络延迟)
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### Q5: 如何保证私钥安全?
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**A:**
|
|
|
|
|
|
1. **私钥加密存储**:数据库中存储加密后的私钥
|
|
|
|
|
|
2. **临时解密**:仅在转账时临时解密,用完立即释放
|
|
|
|
|
|
3. **访问控制**:数据库限制访问权限
|
|
|
|
|
|
4. **建议方案**:
|
|
|
|
|
|
- 使用 AES-256 加密私钥
|
|
|
|
|
|
- 使用 HSM(硬件安全模块)
|
|
|
|
|
|
- 使用云服务商的 KMS(密钥管理服务)
|
|
|
|
|
|
- 使用环境变量传递解密密钥
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
⚠️ **重要**:当前代码中的解密逻辑是**占位代码**,生产环境必须替换为真实的加密算法!
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### Q6: 余额不足时如何处理?
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**A:** 系统会自动使用**归集钱包**转账。归集钱包应该:
|
|
|
|
|
|
- 保持足够的余额
|
|
|
|
|
|
- 定期从各个钱包归集资金
|
|
|
|
|
|
- 设置余额告警
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### Q7: 支持哪些网络?
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**A:**
|
|
|
|
|
|
- ✅ 以太坊主网(Mainnet)
|
|
|
|
|
|
- ✅ 以太坊测试网(Goerli, Sepolia)
|
|
|
|
|
|
- ✅ 私有链
|
|
|
|
|
|
- ⚠️ 需要修改 USDT 合约地址
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### Q8: Gas 费用谁承担?
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**A:**
|
|
|
|
|
|
- **充值**:用户承担(用户自己发送交易)
|
|
|
|
|
|
- **提现**:平台承担(系统发送交易)
|
|
|
|
|
|
- **支付**:平台承担(系统发送交易)
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
建议:提现/支付时从用户金额中扣除 Gas 费
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-16 18:54:27 +08:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 部署指南
|
|
|
|
|
|
|
|
|
|
|
|
### Docker 部署(推荐)
|
|
|
|
|
|
|
|
|
|
|
|
```dockerfile
|
|
|
|
|
|
# Dockerfile
|
|
|
|
|
|
FROM golang:1.24-alpine AS builder
|
|
|
|
|
|
|
|
|
|
|
|
WORKDIR /app
|
|
|
|
|
|
COPY . .
|
|
|
|
|
|
RUN go mod download
|
|
|
|
|
|
RUN CGO_ENABLED=0 GOOS=linux go build -o m2pool-payment cmd/main.go
|
|
|
|
|
|
|
|
|
|
|
|
FROM alpine:latest
|
|
|
|
|
|
RUN apk --no-cache add ca-certificates
|
|
|
|
|
|
WORKDIR /root/
|
|
|
|
|
|
|
|
|
|
|
|
COPY --from=builder /app/m2pool-payment .
|
|
|
|
|
|
COPY --from=builder /app/test/config.json .
|
|
|
|
|
|
|
|
|
|
|
|
CMD ["./m2pool-payment"]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
|
# docker-compose.yml
|
|
|
|
|
|
version: '3.8'
|
|
|
|
|
|
|
|
|
|
|
|
services:
|
|
|
|
|
|
payment:
|
|
|
|
|
|
build: .
|
|
|
|
|
|
depends_on:
|
|
|
|
|
|
- mysql
|
|
|
|
|
|
- rabbitmq
|
|
|
|
|
|
environment:
|
|
|
|
|
|
- CONFIG_PATH=/root/config.json
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ./config.json:/root/config.json
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
|
|
|
|
|
|
mysql:
|
|
|
|
|
|
image: mysql:8.0
|
|
|
|
|
|
environment:
|
|
|
|
|
|
MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD}
|
|
|
|
|
|
MYSQL_DATABASE: payment
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "3306:3306"
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- mysql_data:/var/lib/mysql
|
|
|
|
|
|
|
|
|
|
|
|
rabbitmq:
|
|
|
|
|
|
image: rabbitmq:3-management
|
|
|
|
|
|
environment:
|
|
|
|
|
|
RABBITMQ_DEFAULT_USER: m2pool
|
|
|
|
|
|
RABBITMQ_DEFAULT_PASS: m2pool
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "5672:5672"
|
|
|
|
|
|
- "15672:15672"
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- rabbitmq_data:/var/lib/rabbitmq
|
|
|
|
|
|
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
mysql_data:
|
|
|
|
|
|
rabbitmq_data:
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 启动
|
|
|
|
|
|
docker-compose up -d
|
|
|
|
|
|
|
|
|
|
|
|
# 查看日志
|
|
|
|
|
|
docker-compose logs -f payment
|
|
|
|
|
|
|
|
|
|
|
|
# 停止
|
|
|
|
|
|
docker-compose down
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 系统服务部署
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 1. 创建系统用户
|
|
|
|
|
|
sudo useradd -r -s /bin/false m2pool
|
|
|
|
|
|
|
|
|
|
|
|
# 2. 创建服务文件
|
|
|
|
|
|
sudo nano /etc/systemd/system/m2pool-payment.service
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```ini
|
|
|
|
|
|
[Unit]
|
|
|
|
|
|
Description=M2Pool Payment System
|
|
|
|
|
|
After=network.target mysql.service rabbitmq-server.service
|
|
|
|
|
|
|
|
|
|
|
|
[Service]
|
|
|
|
|
|
Type=simple
|
|
|
|
|
|
User=m2pool
|
|
|
|
|
|
WorkingDirectory=/opt/m2pool-payment
|
|
|
|
|
|
ExecStart=/opt/m2pool-payment/m2pool-payment
|
|
|
|
|
|
Restart=on-failure
|
|
|
|
|
|
RestartSec=10
|
|
|
|
|
|
|
|
|
|
|
|
[Install]
|
|
|
|
|
|
WantedBy=multi-user.target
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 3. 启动服务
|
|
|
|
|
|
sudo systemctl daemon-reload
|
|
|
|
|
|
sudo systemctl enable m2pool-payment
|
|
|
|
|
|
sudo systemctl start m2pool-payment
|
|
|
|
|
|
|
|
|
|
|
|
# 4. 查看状态
|
|
|
|
|
|
sudo systemctl status m2pool-payment
|
|
|
|
|
|
|
|
|
|
|
|
# 5. 查看日志
|
|
|
|
|
|
sudo journalctl -u m2pool-payment -f
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
## 性能测试
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### 压测环境配置
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
| 配置项 | 规格 | 说明 |
|
|
|
|
|
|
|--------|------|------|
|
|
|
|
|
|
| **CPU** | 4核 2.4GHz | Intel/AMD x64 |
|
|
|
|
|
|
| **内存** | 8GB DDR4 | 系统 + 缓存 |
|
|
|
|
|
|
| **网络** | 100Mbps | 公网带宽 |
|
|
|
|
|
|
| **数据库** | MySQL 8.0 | 本地部署 |
|
|
|
|
|
|
| **消息队列** | RabbitMQ 3.x | 本地部署 |
|
|
|
|
|
|
| **区块链节点** | Infura/Alchemy | 云端服务 |
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### 预估压测结果
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 1. 充值功能压测
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
| 并发用户数 | TPS | 响应时间 | 成功率 | 说明 |
|
|
|
|
|
|
|-----------|-----|---------|--------|------|
|
|
|
|
|
|
| **10** | 50-80 | < 2秒 | 99.9% | 轻量负载,性能优秀 |
|
|
|
|
|
|
| **50** | 200-300 | 2-5秒 | 99.5% | 中等负载,性能良好 |
|
|
|
|
|
|
| **100** | 300-500 | 5-10秒 | 99.0% | 高负载,性能稳定 |
|
|
|
|
|
|
| **200** | 400-600 | 10-20秒 | 98.5% | 极限负载,性能下降 |
|
|
|
|
|
|
| **500+** | 500-800 | > 20秒 | < 98% | 超负载,不建议 |
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**特点:**
|
|
|
|
|
|
- ✅ 充值检测性能优秀(纯监听,无链上操作)
|
|
|
|
|
|
- ✅ 内存占用低(仅地址监听)
|
|
|
|
|
|
- ✅ 网络带宽消耗小
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 2. 提现功能压测
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
| 并发用户数 | TPS | 响应时间 | 成功率 | 说明 |
|
|
|
|
|
|
|-----------|-----|---------|--------|------|
|
|
|
|
|
|
| **5** | 20-30 | 3-8秒 | 99.8% | 轻量负载,性能优秀 |
|
|
|
|
|
|
| **20** | 50-80 | 8-15秒 | 99.0% | 中等负载,性能良好 |
|
|
|
|
|
|
| **50** | 80-120 | 15-30秒 | 98.5% | 高负载,性能稳定 |
|
|
|
|
|
|
| **100** | 100-150 | 30-60秒 | 97.0% | 极限负载,性能下降 |
|
|
|
|
|
|
| **200+** | 120-200 | > 60秒 | < 95% | 超负载,不建议 |
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**特点:**
|
|
|
|
|
|
- ⚠️ 受链上交易确认时间影响(4-5分钟)
|
|
|
|
|
|
- ⚠️ 数据库查询和私钥解密开销
|
|
|
|
|
|
- ⚠️ Gas费用波动影响成功率
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 3. 支付功能压测
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
| 并发用户数 | TPS | 响应时间 | 成功率 | 说明 |
|
|
|
|
|
|
|-----------|-----|---------|--------|------|
|
|
|
|
|
|
| **5** | 20-30 | 3-8秒 | 99.8% | 轻量负载,性能优秀 |
|
|
|
|
|
|
| **20** | 50-80 | 8-15秒 | 99.0% | 中等负载,性能良好 |
|
|
|
|
|
|
| **50** | 80-120 | 15-30秒 | 98.5% | 高负载,性能稳定 |
|
|
|
|
|
|
| **100** | 100-150 | 30-60秒 | 97.0% | 极限负载,性能下降 |
|
|
|
|
|
|
| **200+** | 120-200 | > 60秒 | < 95% | 超负载,不建议 |
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**特点:**
|
|
|
|
|
|
- ⚠️ 与提现功能性能相近
|
|
|
|
|
|
- ⚠️ 订单ID处理增加少量开销
|
|
|
|
|
|
- ⚠️ 商户地址验证开销
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### 系统资源占用
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 内存使用情况
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
| 并发数 | 基础内存 | 峰值内存 | 说明 |
|
|
|
|
|
|
|--------|----------|----------|------|
|
|
|
|
|
|
| **10** | 100MB | 150MB | 轻量运行 |
|
|
|
|
|
|
| **50** | 200MB | 350MB | 中等负载 |
|
|
|
|
|
|
| **100** | 300MB | 500MB | 高负载 |
|
|
|
|
|
|
| **200** | 500MB | 800MB | 极限负载 |
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### CPU使用情况
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
| 并发数 | 基础CPU | 峰值CPU | 说明 |
|
|
|
|
|
|
|--------|---------|---------|------|
|
|
|
|
|
|
| **10** | 5% | 15% | 轻量运行 |
|
|
|
|
|
|
| **50** | 15% | 35% | 中等负载 |
|
|
|
|
|
|
| **100** | 25% | 50% | 高负载 |
|
|
|
|
|
|
| **200** | 40% | 70% | 极限负载 |
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 网络带宽使用
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
| 并发数 | 上行带宽 | 下行带宽 | 说明 |
|
|
|
|
|
|
|--------|----------|----------|------|
|
|
|
|
|
|
| **10** | 1Mbps | 2Mbps | 轻量运行 |
|
|
|
|
|
|
| **50** | 3Mbps | 5Mbps | 中等负载 |
|
|
|
|
|
|
| **100** | 5Mbps | 8Mbps | 高负载 |
|
|
|
|
|
|
| **200** | 8Mbps | 12Mbps | 极限负载 |
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### 性能瓶颈分析
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 1. 主要瓶颈
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
| 瓶颈类型 | 影响程度 | 解决方案 |
|
|
|
|
|
|
|----------|----------|----------|
|
|
|
|
|
|
| **区块链确认时间** | 🔴 高 | 使用Layer2或侧链 |
|
|
|
|
|
|
| **数据库查询** | 🟡 中 | 添加索引,使用缓存 |
|
|
|
|
|
|
| **私钥解密** | 🟡 中 | 优化加密算法 |
|
|
|
|
|
|
| **网络延迟** | 🟡 中 | 使用CDN,就近部署 |
|
|
|
|
|
|
| **Gas费用波动** | 🟡 中 | 动态Gas价格调整 |
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 2. 优化建议
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**短期优化(1-2周):**
|
|
|
|
|
|
- ✅ 添加数据库索引
|
|
|
|
|
|
- ✅ 优化SQL查询语句
|
|
|
|
|
|
- ✅ 增加Channel缓冲区大小
|
|
|
|
|
|
- ✅ 使用连接池复用
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**中期优化(1-2月):**
|
|
|
|
|
|
- 🔄 实现Redis缓存
|
|
|
|
|
|
- 🔄 优化私钥加密算法
|
|
|
|
|
|
- 🔄 添加负载均衡
|
|
|
|
|
|
- 🔄 实现读写分离
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**长期优化(3-6月):**
|
|
|
|
|
|
- 🚀 支持Layer2网络
|
|
|
|
|
|
- 🚀 实现微服务架构
|
|
|
|
|
|
- 🚀 添加水平扩展
|
|
|
|
|
|
- 🚀 使用分布式数据库
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### 压测工具推荐
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 1. 消息队列压测
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
|
|
|
|
|
```bash
|
2025-10-27 16:27:33 +08:00
|
|
|
|
# 使用 RabbitMQ 压测工具
|
|
|
|
|
|
docker run --rm -it \
|
|
|
|
|
|
-e RABBITMQ_HOST=localhost \
|
|
|
|
|
|
-e RABBITMQ_PORT=5672 \
|
|
|
|
|
|
-e RABBITMQ_USER=m2pool \
|
|
|
|
|
|
-e RABBITMQ_PASS=m2pool \
|
|
|
|
|
|
rabbitmq-perf-test:latest \
|
|
|
|
|
|
--rate 100 --time 60 --queue pay.withdraw.queue
|
2025-10-16 18:54:27 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 2. 数据库压测
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
|
|
|
|
|
```bash
|
2025-10-27 16:27:33 +08:00
|
|
|
|
# 使用 sysbench 压测 MySQL
|
|
|
|
|
|
sysbench mysql \
|
|
|
|
|
|
--mysql-host=localhost \
|
|
|
|
|
|
--mysql-port=3306 \
|
|
|
|
|
|
--mysql-user=root \
|
|
|
|
|
|
--mysql-password=password \
|
|
|
|
|
|
--mysql-db=payment \
|
|
|
|
|
|
--tables=1 \
|
|
|
|
|
|
--table-size=10000 \
|
|
|
|
|
|
--threads=10 \
|
|
|
|
|
|
--time=60 \
|
|
|
|
|
|
run
|
2025-10-16 18:54:27 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 3. 系统监控
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
|
|
|
|
|
```bash
|
2025-10-27 16:27:33 +08:00
|
|
|
|
# 监控系统资源
|
|
|
|
|
|
htop # CPU和内存监控
|
|
|
|
|
|
iotop # 磁盘IO监控
|
|
|
|
|
|
nethogs # 网络带宽监控
|
2025-10-16 18:54:27 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### 生产环境建议
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 1. 推荐配置
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
| 环境 | CPU | 内存 | 并发数 | 说明 |
|
|
|
|
|
|
|------|-----|------|--------|------|
|
|
|
|
|
|
| **开发环境** | 2核 | 4GB | < 10 | 功能测试 |
|
|
|
|
|
|
| **测试环境** | 4核 | 8GB | < 50 | 压力测试 |
|
|
|
|
|
|
| **生产环境** | 8核 | 16GB | < 100 | 稳定运行 |
|
|
|
|
|
|
| **高可用环境** | 16核 | 32GB | < 200 | 负载均衡 |
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 2. 监控指标
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
|
|
|
|
|
```go
|
2025-10-27 16:27:33 +08:00
|
|
|
|
// 关键监控指标
|
|
|
|
|
|
type Metrics struct {
|
|
|
|
|
|
TotalTransactions int64 // 总交易数
|
|
|
|
|
|
PendingTransactions int // 待确认交易数
|
|
|
|
|
|
FailedTransactions int64 // 失败交易数
|
|
|
|
|
|
ChannelUsage int // Channel使用率
|
|
|
|
|
|
LastBlockHeight uint64 // 最新区块高度
|
|
|
|
|
|
MemoryUsage int64 // 内存使用量
|
|
|
|
|
|
CPUUsage float64 // CPU使用率
|
2025-10-21 10:58:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 3. 告警阈值
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
| 指标 | 警告阈值 | 严重阈值 | 说明 |
|
|
|
|
|
|
|------|----------|----------|------|
|
|
|
|
|
|
| **待确认交易数** | > 100 | > 500 | 交易积压 |
|
|
|
|
|
|
| **Channel使用率** | > 80% | > 95% | 消息积压 |
|
|
|
|
|
|
| **交易失败率** | > 5% | > 10% | 系统异常 |
|
|
|
|
|
|
| **内存使用率** | > 80% | > 95% | 内存不足 |
|
|
|
|
|
|
| **CPU使用率** | > 70% | > 90% | CPU过载 |
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
## 重要修复说明
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### 🔧 已修复的问题
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 1. QueueId 重复问题
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**问题**:两笔不同的交易出现相同的 QueueId
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**原因**:数据库表主键设计错误,使用 `(from_addr, to_addr)` 作为主键
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**修复**:
|
|
|
|
|
|
- 修改数据库表结构,将主键改为 `queueId`
|
|
|
|
|
|
- 创建数据库迁移脚本 `public/migration.sql`
|
|
|
|
|
|
- 修复 SQL 插入语句的参数数量不匹配问题
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
#### 2. 重复发送响应问题
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**问题**:提现和支付会发送两次响应
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**原因**:转账失败时,先发送失败响应,然后仍然进入链上确认流程
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
**修复**:
|
|
|
|
|
|
- 在转账失败时添加 `return` 语句
|
|
|
|
|
|
- 确保转账失败时不进入链上确认流程
|
|
|
|
|
|
- 只有转账成功才会进入链上监听和确认
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
### 📊 修复后的消息发送次数
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
| 场景 | 消息处理阶段 | 链上确认阶段 | 总发送次数 |
|
|
|
|
|
|
|------|-------------|-------------|-----------|
|
|
|
|
|
|
| **转账失败** | 发送失败响应 | 不进入(已return) | **1次** |
|
|
|
|
|
|
| **转账成功** | 不发送响应 | 发送成功响应 | **1次** |
|
2025-10-21 10:58:58 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 贡献指南
|
|
|
|
|
|
|
|
|
|
|
|
欢迎贡献代码!请遵循以下步骤:
|
|
|
|
|
|
|
|
|
|
|
|
### 提交流程
|
|
|
|
|
|
|
|
|
|
|
|
1. Fork 本项目
|
|
|
|
|
|
2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
|
|
|
|
|
|
3. 提交更改 (`git commit -m 'feat: Add some AmazingFeature'`)
|
|
|
|
|
|
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
|
|
|
|
|
5. 开启 Pull Request
|
|
|
|
|
|
|
|
|
|
|
|
### 代码规范
|
|
|
|
|
|
|
|
|
|
|
|
- ✅ 使用 `gofmt` 格式化代码
|
|
|
|
|
|
- ✅ 遵循 Go 命名规范
|
|
|
|
|
|
- ✅ 添加必要的注释
|
|
|
|
|
|
- ✅ 所有地址统一小写处理
|
|
|
|
|
|
- ✅ 使用状态码常量(不要硬编码数字)
|
|
|
|
|
|
- ✅ 添加错误处理和日志
|
|
|
|
|
|
- ✅ 更新相关文档
|
|
|
|
|
|
|
|
|
|
|
|
### Commit 规范
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 新功能
|
|
|
|
|
|
feat: 添加 BTC 网络支持
|
|
|
|
|
|
|
|
|
|
|
|
# Bug 修复
|
|
|
|
|
|
fix: 修复充值消息重复发送问题
|
|
|
|
|
|
|
|
|
|
|
|
# 文档更新
|
|
|
|
|
|
docs: 更新 API 文档
|
|
|
|
|
|
|
|
|
|
|
|
# 性能优化
|
|
|
|
|
|
perf: 优化交易确认性能
|
|
|
|
|
|
|
|
|
|
|
|
# 代码重构
|
|
|
|
|
|
refactor: 重构数据库连接池
|
|
|
|
|
|
|
|
|
|
|
|
# 测试
|
|
|
|
|
|
test: 添加单元测试
|
|
|
|
|
|
```
|
2025-10-16 18:54:27 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 许可证
|
|
|
|
|
|
|
|
|
|
|
|
MIT License
|
|
|
|
|
|
|
|
|
|
|
|
Copyright (c) 2025 M2Pool Team
|
|
|
|
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
|
|
|
|
copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
|
|
SOFTWARE.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
<div align="center">
|
|
|
|
|
|
|
|
|
|
|
|
**⭐ 如果这个项目对你有帮助,请给一个 Star!⭐**
|
|
|
|
|
|
|
|
|
|
|
|
Made with ❤️ by M2Pool Team
|
|
|
|
|
|
|
2025-10-27 16:27:33 +08:00
|
|
|
|
</div>
|