脉动数据行情1头像
关注

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最新成交价
Open24h 开盘价
High24h 最高价
Low24h 最低价
BP1买一价
SP1卖一价
TotalVol24h 成交量
Time更新时间

六、生产环境优化

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

七、总结

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

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/2509_93909211/article/details/167276014

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--