Python asyncio 异步实现比特币 BTC 实时行情监听 高并发版

摘要

比特币 BTC 作为市值最大的加密货币,7×24 小时不间断交易,对行情采集程序的稳定性要求极高。传统同步 WebSocket 客户端单连接性能有限,本文基于 Python asyncio 异步框架实现高并发行情监听,支持多币种批量订阅,内置心跳、自动重连、协程级异常捕获,数据源采用脉动行情数据 API。

关键词:Python;asyncio;比特币;BTC;WebSocket

一、为什么用 asyncio 替代同步写法

之前很多教程用同步 websocket-client 库写行情监听,问题在于:

  1. 接收和心跳在不同线程,共享状态需要加锁;
  2. 多币种订阅时单线程阻塞,消息处理慢;
  3. 异步生态下,和 FastAPI/Starlette 业务集成不友好。

asyncio 单线程事件循环,无锁、高并发,天然适合 I/O 密集的行情推送场景。

示例币种编码:btcusdt(比特币)、ethusdt(以太坊)、solusdt(Solana)

二、依赖安装

复制代码
pip install websockets

三、完整异步客户端代码

复制代码
import asyncio
import json
import time
import logging
import websockets

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(message)s")
logger = logging.getLogger()

# WebSocket真实地址,仅代码内配置
WS_URL = "ws://39.107.99.235/ws"
# 批量订阅
SYMBOL_LIST = "btcusdt,ethusdt,solusdt"
HEARTBEAT_INTERVAL = 10
RECONNECT_DELAY = 3


async def heartbeat(ws):
    """异步心跳协程"""
    while True:
        try:
            ping = json.dumps({"ping": int(time.time())})
            await ws.send(ping)
            await asyncio.sleep(HEARTBEAT_INTERVAL)
        except Exception as e:
            logger.error("心跳异常: %s", e)
            return


async def receive_loop(ws):
    """异步接收循环"""
    async for raw_msg in ws:
        try:
            data = json.loads(raw_msg)
            body = data.get("body")
            if not body:
                continue
            print(
                f"[{body.get('Time')}] "
                f"{body.get('StockCode')} "
                f"价格:{body.get('Price')} "
                f"24h高:{body.get('High')} "
                f"24h低:{body.get('Low')}"
            )
        except Exception as e:
            logger.error("行情解析异常: %s", e)


async def client():
    while True:
        try:
            async with websockets.connect(WS_URL, ping_interval=None) as ws:
                logger.info("WebSocket连接成功,批量订阅: %s", SYMBOL_LIST)
                await ws.send(json.dumps({"Key": SYMBOL_LIST}))
                # 并发跑心跳和接收
                await asyncio.gather(
                    heartbeat(ws),
                    receive_loop(ws),
                )
        except Exception as e:
            logger.warning("连接断开: %s,%d秒后重连", e, RECONNECT_DELAY)
            await asyncio.sleep(RECONNECT_DELAY)


if __name__ == "__main__":
    try:
        asyncio.run(client())
    except KeyboardInterrupt:
        logger.info("服务退出")

四、HTTP 快照异步获取示例

复制代码
import aiohttp
import asyncio

async def fetch_quote():
    url = "http://39.107.99.235:1008/getQuote.php?code=btcusdt,ethusdt"
    headers = {"Accept-Encoding": "gzip"}
    async with aiohttp.ClientSession() as session:
        async with session.get(url, headers=headers, timeout=8) as resp:
            data = await resp.text()
            print(data)

if __name__ == "__main__":
    asyncio.run(fetch_quote())

五、核心字段说明

表格

字段 说明
StockCode 币种编码
Price 最新成交价
Open 24h 开盘价
High 24h 最高价
Low 24h 最低价
BP1 买一价
SP1 卖一价
TotalVol 24h 成交量
Time 更新时间

六、生产环境优化

  1. 加密货币 7×24 小时交易,无休市概念,心跳必须持续发送;
  2. asyncio 单线程事件循环,不要在消息处理里写 CPU 密集任务,阻塞会拖慢整条链路;
  3. 高频行情建议直接 gjson 流式解析,避免完整 json.loads 性能损耗;
  4. 生产环境用 uvicorn 或 gunicorn 部署,配合 systemd 守护;
  5. 行情数据建议落 ClickHouse 或 InfluxDB,方便回测查询。

七、总结

asyncio 异步方案在加密货币行情采集场景下,单线程即可轻松处理多币种高频推送,和 Python 后端生态无缝集成。修改订阅币种列表,即可扩展到更多加密货币对,适合量化交易、行情监控类项目。

相关推荐
爱吃奥利奥_wen40 分钟前
排序算法通关手册:从 O(n²) 到 O(n log n),用一篇文章打通算法内功心法
开发语言·经验分享
ClickHouseDB41 分钟前
ClickHouse Terraform Provider 正式支持 ClickStack 资源管理
网络·数据库·python
外收内放44 分钟前
Python基础语法练习题(55-56)
开发语言·python
yi0111 小时前
DAY23: LeetCode 27 → 283:从移除元素到移动零,理解快慢指针的两种思路
人工智能·笔记·python·算法·leetcode·排序算法·双指针
Do_It_Today1 小时前
php 可变函数使用小结
开发语言·php
Python图像识别1 小时前
30-【2027毕设】YOLO11管道缺陷检测识别系统 - Python完整源码+PyQt5界面+训练模型+数据集
python·qt·课程设计
GPU实战笔记1 小时前
云端写 Python:JupyterLab 和 VS Code Remote-SSH,按工作方式选
python·vs code·jupyterlab·remote-ssh·远程开发·云端开发
Do_It_Today1 小时前
PHP 实现数组分页
开发语言·php
weishuangyun11 小时前
小程序制作平台怎么选?三大平台对比!
大数据·开发语言·javascript