为什么需要支付中转服务?

在国内的源码交易和转卡码业务中,支付通道的稳定性直接决定了业务的命脉。然而,由于国内支付接口的风控规则日趋严格,单一直连通道经常面临限流、风控拦截甚至被封禁的风险。在 香港服务器 搭建支付中转服务,可以利用香港国际带宽优势,将支付流量平滑分发到多个备用通道,实现高可用架构。

本文将以 阿里云香港 ECS 为例,手把手教你用 Docker Compose 一键部署完整的支付中转服务。整套方案包含 Nginx 反向代理、多通道健康检查、自动故障转移、Prometheus + Grafana 监控告警,适合有一定 Linux 基础的开发者。

整体架构设计

我们的支付中转系统采用微服务架构,所有组件运行在 Docker 容器中,通过 docker-compose 统一编排:

┌─────────────────────────────────────────────┐
│          Nginx (负载均衡 + 反向代理)           │
│        端口 443 (HTTPS) / 端口 80 (HTTP)      │
└──────────┬──────────────────────┬────────────┘
           │                      │
    ┌──────▼──────┐       ┌──────▼──────┐
    │ 通道 A      │       │ 通道 B      │
    │ (支付宝)    │       │ (微信支付)  │
    └──────┬──────┘       └──────┬──────┘
           │                      │
    ┌──────▼──────────────────────▼──────┐
    │     健康检查服务 (Python)            │
    │  每 10 秒探测各通道可用性             │
    │  自动摘除故障节点                     │
    └──────────────┬──────────────────────┘
                   │
    ┌──────────────▼──────────────────────┐
    │     Prometheus + Node Exporter      │
    │     Grafana 可视化仪表盘              │
    └─────────────────────────────────────┘

这套架构的核心优势在于:

  • 容器化部署:环境一致,迁移方便,扩容只需修改配置文件
  • 健康检查自动恢复:故障通道被自动摘除,恢复后重新加入
  • 可视化监控:实时掌握支付流量和通道健康状态
  • 零停机更新:Nginx upstream 动态 reload,不影响线上交易

第一步:服务器基础环境配置

推荐配置:阿里云香港 ECS 2C4G(CentOS 7.9 或 Ubuntu 22.04),带宽 5Mbps 以上。登录服务器后,首先安装 Docker 和 Docker Compose:

# 更新系统并安装依赖
sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg lsb-release

# 安装 Docker(阿里云镜像加速)
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
  https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io

# 安装 Docker Compose v2
sudo curl -L "https://github.com/docker/compose/releases/download/v2.29.0/docker-compose-$(uname -s)-$(uname -m)" \
  -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# 验证安装
docker --version && docker-compose --version
💡 提示:如果服务器位于国内无法访问 Docker Hub,可以在 /etc/docker/daemon.json 中配置阿里云镜像加速器 https://xxxxxxxx.mirror.aliyuncs.com,然后重启 Docker。

第二步:项目目录结构与 docker-compose.yml

创建一个统一的项目目录,用来存放所有配置文件:

mkdir -p ~/payment-relay && cd ~/payment-relay
mkdir -p nginx/conf.d nginx/ssl scripts prometheus grafana/dashboards

下面是完整的 docker-compose.yml 文件,它定义了 Nginx、健康检查服务、Prometheus 和 Grafana 四个服务:

version: '3.8'

services:
  nginx:
    image: nginx:1.27-alpine
    container_name: relay-nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/ssl:/etc/nginx/ssl
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
    networks:
      - relay-net
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "nginx", "-t"]
      interval: 30s
      timeout: 5s
      retries: 3

  health-checker:
    build: ./scripts
    container_name: relay-health
    volumes:
      - ./scripts/upstream.conf:/app/upstream.conf:ro
      - ./nginx/conf.d:/etc/nginx/conf.d
    environment:
      - CHECK_INTERVAL=10
      - UNHEALTHY_THRESHOLD=3
    networks:
      - relay-net
    restart: unless-stopped
    depends_on:
      - nginx

  prometheus:
    image: prom/prometheus:v2.54.0
    container_name: relay-prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus
    networks:
      - relay-net
    restart: unless-stopped

  grafana:
    image: grafana/grafana:11.1.0
    container_name: relay-grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
      - ./grafana/dashboards:/etc/grafana/provisioning/dashboards
    networks:
      - relay-net
    restart: unless-stopped
    depends_on:
      - prometheus

networks:
  relay-net:
    driver: bridge

volumes:
  prometheus-data:
  grafana-data:

Nginx 反向代理配置

接下来配置 Nginx 的主文件 nginx/nginx.conf

user  nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
    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"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*.conf;
}

创建支付中转的核心代理配置 nginx/conf.d/payment-relay.conf

upstream payment_backend {
    # 由健康检查脚本动态维护 upstream 列表
    include /etc/nginx/conf.d/upstream.conf;
}

server {
    listen 80;
    server_name pay.your-domain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name pay.your-domain.com;

    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    # IP 限流配置(防止恶意刷单)
    limit_req_zone $binary_remote_addr zone=pay_limit:10m rate=10r/s;
    limit_req zone=pay_limit burst=20 nodelay;

    location /api/pay/ {
        proxy_pass http://payment_backend;
        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_connect_timeout 5s;
        proxy_read_timeout 30s;
        proxy_send_timeout 10s;

        # 失败重试策略
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        proxy_next_upstream_tries 2;
        proxy_next_upstream_timeout 10s;

        # 健康检查端点暴露给 Prometheus
        location = /health {
            access_log off;
            return 200 "OK\n";
            add_header Content-Type text/plain;
        }
    }

    location /api/query/ {
        proxy_pass http://payment_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_read_timeout 15s;
    }
}

第三步:Python 健康检查与自动故障转移

健康检查是整个系统的核心。我们用 Python 3 编写一个轻量级检查服务,每隔 10 秒探测每个支付通道的健康状态,一旦连续 3 次探测失败,自动将该通道从 upstream 中摘除:

创建 scripts/Dockerfile

FROM python:3.12-alpine
WORKDIR /app
COPY health_checker.py /app/
RUN pip install requests pyyaml
CMD ["python", "health_checker.py"]

创建核心健康检查脚本 scripts/health_checker.py

#!/usr/bin/env python3
"""
支付通道健康检查与自动故障转移服务
探测各通道 /health 端点,故障时自动摘除,恢复后重新加入
"""
import os
import time
import requests
import json
from pathlib import Path

CHECK_INTERVAL = int(os.getenv('CHECK_INTERVAL', '10'))
UNHEALTHY_THRESHOLD = int(os.getenv('UNHEALTHY_THRESHOLD', '3'))

# 支付通道配置:名称 → 检测 URL
CHANNELS = {
    'alipay_channel_01': 'http://10.0.0.10:8080/health',
    'wechat_channel_01': 'http://10.0.0.11:8080/health',
    'unionpay_channel':  'http://10.0.0.12:8080/health',
}

# 每个通道的连续失败计数
fail_count = {name: 0 for name in CHANNELS}

UPSTREAM_FILE = Path('/etc/nginx/conf.d/upstream.conf')

def generate_upstream(healthy_channels):
    """生成 Nginx upstream 配置"""
    lines = []
    for name, url in CHANNELS.items():
        if name in healthy_channels:
            host = url.split('://')[1].split(':')[0]
            port = url.split(':')[2].split('/')[0] if ':' in url.split('://')[1] else '80'
            lines.append(f'    server {host}:{port} weight=10 max_fails=3 fail_timeout=30s;')
    if not lines:
        # 所有通道都挂了,保留最后可用通道防止完全不可用
        lines.append(f'    server 10.0.0.10:8080 backup;')
    return 'upstream payment_backend {\n' + '\n'.join(lines) + '\n}\n'

def check_channel(name, url):
    """探测单个通道的健康状态"""
    try:
        r = requests.get(url, timeout=5)
        if r.status_code == 200:
            return True
    except requests.RequestException:
        pass
    return False

def main():
    print("[health-checker] 启动支付通道健康检查服务")
    while True:
        healthy = []
        for name, url in CHANNELS.items():
            if check_channel(name, url):
                fail_count[name] = 0
                healthy.append(name)
                print(f"[OK] {name} — 通道正常")
            else:
                fail_count[name] += 1
                print(f"[WARN] {name} — 第 {fail_count[name]} 次连续失败")
                if fail_count[name] < UNHEALTHY_THRESHOLD:
                    # 未达到摘除阈值,暂时保留
                    healthy.append(name)

        # 写入 upstream 配置并 reload Nginx
        config = generate_upstream(healthy)
        UPSTREAM_FILE.write_text(config)
        os.system('nginx -s reload 2>/dev/null || true')

        time.sleep(CHECK_INTERVAL)

if __name__ == '__main__':
    main()
⚠️ 注意:上面的脚本是简化版本。在实际生产环境中,建议将通道配置放在 Redis 或 Consul 中,配合 Watch 机制实现热更新,避免每次修改都 reload Nginx。

第四步:Prometheus + Grafana 监控告警

配置 Prometheus 的抓取目标 prometheus/prometheus.yml

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'nginx'
    static_configs:
      - targets: ['nginx:80']
    metrics_path: /metrics

  - job_name: 'node'
    static_configs:
      - targets: ['host.docker.internal:9100']

  - job_name: 'health-checker'
    static_configs:
      - targets: ['health-checker:8000']

在 Grafana 中导入 Nginx 官方仪表盘(ID: 9614),即可实时查看:

  • 当前活跃连接数
  • 各通道请求分发比例
  • HTTP 4xx/5xx 错误率
  • upstream 健康状态
  • 响应时间 P50/P95/P99 分布

同时配置 Alertmanager 告警规则,当某个通道连续故障超过 5 分钟,自动发送企业微信或钉钉通知。

第五步:启动与验证

所有配置文件准备就绪后,一键启动整套系统:

# 构建并启动所有服务
cd ~/payment-relay
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看运行日志
docker-compose logs -f

# 验证 Nginx 健康检查端点
curl -s -o /dev/null -w "%{http_code}" http://localhost/health
# 输出: 200

# 模拟一个通道故障,观察自动切换
curl -X POST http://localhost/api/pay/test
docker-compose logs health-checker --tail 20

启动后效果:

  • Nginx 在 443 端口监听 HTTPS 请求
  • 健康检查每 10 秒探测一次各通道
  • 故障通道 30 秒内自动摘除
  • Prometheus 在 9090 端口提供指标数据
  • Grafana 在 3000 端口提供可视化仪表盘

生产环境注意事项

在将这套方案部署到生产环境之前,还有几个关键点需要注意:

  1. SSL 证书:建议使用 Let's Encrypt 免费证书,配合 acme.sh 实现自动续期。不要使用自签名证书,大部分支付回调接口会拒绝非受信证书。
  2. DNS 解析:使用 Cloudflare 或 AliDNS 做智能解析,国内用户解析到国内 CDN,海外用户解析到香港服务器。
  3. 防火墙规则:只开放 80/443 端口到公网,其他端口只允许内网访问。用 ufwiptables 设置白名单。
  4. 日志轮转:Nginx 访问日志增长很快,配置 logrotate 每日压缩归档,保留 30 天。
  5. 数据备份:Prometheus 数据目录和 Grafana 配置定期备份到 OSS 或 S3。
# 配置日志轮转 /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
    endscript
}

与转卡码系统集成

如果你的业务使用了 转卡码系统(卡密自动发货),支付中转服务可以天然地与转卡码平台对接。支付成功回调经过香港中转转发到转卡码系统的回调地址,实现自动发货逻辑。我们的 源码商城 提供的转卡码系统 V3 版本已经内置了多通道支付中转对接模块,只需在后台配置香港服务器地址和通道权重即可一键启用。

此外,配合 Codex Desktop 的 Linux 版本,你可以在香港服务器上直接运行 AI 编程助手进行二次开发和定制,大幅降低运维复杂度。

总结

本文详细讲解了如何在香港服务器上使用 Docker Compose 搭建一套高可用的支付中转服务。整套方案具有以下优势:

  • ✅ 容器化部署,环境一致,迁移方便
  • ✅ 自动健康检查与故障转移,保障 7x24 可用
  • ✅ Prometheus + Grafana 监控,运营数据一目了然
  • ✅ 15 分钟即可完成部署,适合中小团队快速落地
  • ✅ 可无缝对接转卡码系统和自动发货平台

如果你正在寻找成熟的支付中转或转卡码系统解决方案,欢迎到 源码商城 看看我们的产品,全套源码交付,支持二次开发。