Files
m2pool_payment/internal/queue/README.md
2025-10-16 18:54:27 +08:00

364 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# RabbitMQ 服务使用说明
## 功能概述
这个 RabbitMQ 服务实现了区块链支付系统的消息队列功能,包括:
### 消费队列(监听)
1. **充值队列 (topup)** - 监听用户充值请求
2. **提现队列 (withdraw)** - 监听用户提现请求
3. **支付队列 (pay)** - 监听用户支付请求
### 发布队列(响应)
1. **充值响应队列 (topup_resp)** - 发送充值确认结果
2. **提现响应队列 (withdraw_resp)** - 发送提现确认结果
3. **支付响应队列 (pay_resp)** - 发送支付确认结果
---
## 快速开始
### 1. 安装依赖
```bash
go get github.com/rabbitmq/amqp091-go
```
### 2. 配置文件示例 (config.json)
```json
{
"rmq_config": {
"sub_addr": "amqp://username:password@localhost:5672",
"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"]
}
}
}
```
### 3. 使用示例
```go
package main
import (
"log"
message "m2pool-payment/internal/msg"
rmq "m2pool-payment/internal/queue"
)
func main() {
// 加载配置
config := loadConfig() // 你的配置加载逻辑
// 创建 RabbitMQ 服务
rmqServer, err := rmq.NewRabbitMQServer(config.RMQConfig)
if err != nil {
log.Fatalf("创建 RabbitMQ 服务失败: %v", err)
}
defer rmqServer.Close()
// 设置消息处理回调
rmqServer.OnTopupMsg = func(msg message.TopupMsg_req) {
log.Printf("收到充值请求: %+v", msg)
// 处理充值逻辑...
// 添加地址监听等
}
rmqServer.OnWithdrawMsg = func(msg message.WithdrawMsg_req) {
log.Printf("收到提现请求: %+v", msg)
// 处理提现逻辑...
// 调用区块链转账
}
rmqServer.OnPayMsg = func(msg message.PayMsg_req) {
log.Printf("收到支付请求: %+v", msg)
// 处理支付逻辑...
// 调用区块链转账
}
// 启动监听
if err := rmqServer.Start(); err != nil {
log.Fatalf("启动监听失败: %v", err)
}
// 发送响应消息示例
rmqServer.PublishTopupResp(message.TopupMsg_resp{
Address: "0x123...",
Status: 1,
Chain: "ETH",
Symbol: "USDT",
Amount: 100.0,
TxHash: "0xabc...",
})
// 保持运行
select {}
}
```
---
## API 说明
### 创建服务
```go
func NewRabbitMQServer(config message.RMQConfig) (*RabbitMQServer, error)
```
创建一个新的 RabbitMQ 服务实例。
**参数:**
- `config`: RabbitMQ 配置
**返回:**
- `*RabbitMQServer`: 服务实例
- `error`: 错误信息
---
### 启动监听
```go
func (r *RabbitMQServer) Start() error
```
启动所有队列的监听topup, withdraw, pay
---
### 消息回调设置
```go
// 充值请求回调
rmqServer.OnTopupMsg = func(msg message.TopupMsg_req) {
// 处理逻辑
}
// 提现请求回调
rmqServer.OnWithdrawMsg = func(msg message.WithdrawMsg_req) {
// 处理逻辑
}
// 支付请求回调
rmqServer.OnPayMsg = func(msg message.PayMsg_req) {
// 处理逻辑
}
```
---
### 发布响应消息
```go
// 发布充值响应
func (r *RabbitMQServer) PublishTopupResp(resp message.TopupMsg_resp) error
// 发布提现响应
func (r *RabbitMQServer) PublishWithdrawResp(resp message.WithdrawMsg_resp) error
// 发布支付响应
func (r *RabbitMQServer) PublishPayResp(resp message.PayMsg_resp) error
```
---
### 关闭服务
```go
func (r *RabbitMQServer) Close() error
```
优雅关闭 RabbitMQ 连接和所有监听。
---
## 消息格式
### 充值请求 (TopupMsg_req)
```json
{
"chain": "ETH",
"symbol": "USDT",
"address": "0x123...",
"timestamp": 1234567890,
"sign": "signature_string"
}
```
### 充值响应 (TopupMsg_resp)
```json
{
"address": "0x123...",
"status": 1,
"chain": "ETH",
"symbol": "USDT",
"amount": 100.5,
"tx_hash": "0xabc..."
}
```
### 提现请求 (WithdrawMsg_req)
```json
{
"queue_id": "queue_123",
"from_address": "0x123...",
"to_address": "0x456...",
"amount": 50.0,
"chain": "ETH",
"symbol": "USDT",
"timestamp": 1234567890,
"sign": "signature_string"
}
```
### 提现响应 (WithdrawMsg_resp)
```json
{
"queue_id": "queue_123",
"status": 1,
"amount": 50.0,
"chain": "ETH",
"symbol": "USDT",
"tx_hash": "0xdef..."
}
```
### 支付请求 (PayMsg_req)
```json
{
"queue_id": "queue_456",
"from_address": "0x123...",
"to_address": "0x789...",
"amount": 200.0,
"chain": "ETH",
"symbol": "USDT",
"order_id": "order_789",
"timestamp": 1234567890,
"sign": "signature_string"
}
```
### 支付响应 (PayMsg_resp)
```json
{
"queue_id": "queue_456",
"status": 1,
"amount": 200.0,
"chain": "ETH",
"symbol": "USDT",
"order_id": "order_789",
"tx_hash": "0xghi..."
}
```
---
## 状态码说明
- `status = 0` - 失败
- `status = 1` - 成功
- `status = 2` - 待确认(仅用于链上交易)
---
## 特性
**自动重连** - 连接断开时自动重连
**消息持久化** - 消息不会丢失
**手动确认** - 处理成功后才确认消息
**并发安全** - 支持多 goroutine 并发发布
**优雅关闭** - 支持优雅关闭所有连接
**错误处理** - 完善的错误日志和重试机制
---
## 注意事项
1. **连接地址格式**: `amqp://username:password@host:port/`
2. **消息确认**: 只有处理成功的消息才会被确认,失败的消息会重新入队
3. **并发安全**: 发布消息时使用了互斥锁,可以安全地从多个 goroutine 调用
4. **重连机制**: 连接断开时会自动重连,间隔 3 秒
5. **消息持久化**: 消息和队列都是持久化的,重启后不会丢失
---
## 工作流程
```
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ 业务系统 │ ------> │ RabbitMQ │ ------> │ 支付系统 │
│ │ 充值/ │ (消息队列) │ 消费 │ (本系统) │
│ │ 提现/ │ │ │ │
│ │ 支付 │ │ │ │
└─────────────┘ └──────────────┘ └─────────────┘
|
| 监听链上
v
┌─────────────┐
│ 区块链节点 │
│ (ETH) │
└─────────────┘
|
| 交易确认
v
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ 业务系统 │ <------ │ RabbitMQ │ <------ │ 支付系统 │
│ │ 响应 │ (响应队列) │ 发布 │ (本系统) │
└─────────────┘ └──────────────┘ └─────────────┘
```
---
## 故障排查
### 连接失败
- 检查 RabbitMQ 服务是否运行
- 检查用户名密码是否正确
- 检查网络连接和端口(默认 5672
### 消息未被消费
- 检查队列绑定是否正确
- 检查 routing key 是否匹配
- 查看 RabbitMQ 管理界面的队列状态
### 消息重复消费
- 确保消息处理成功后调用了 Ack
- 检查是否有多个消费者实例
---
## 许可证
MIT License