先看一段能跑的最小代码。假设你手头是一台刚焊好的 ESP32,或者一台装了易语言的工控机,只要能发 HTTP 请求,就能往云递数据里塞一条记录:

curl -X POST http://你的域名/api/push.php \
  -H "Content-Type: application/json" \
  -d '{"api_key":"你的APIKey","dataset":"sensor_temp","data":{"dev":"T-01","temp":26.4,"ts":"2024-06-01 10:00:00"}}'

返回体里会告诉你这条数据有没有真正写进去、是不是被判成了重复。跑通这一条,后面的事基本就是换个数据名、换个字段的体力活。下面我把这套流程从“为什么卡住”讲到“怎么避坑”,按我平时带新人的顺序来。

1. 数据采集终端存数据,为什么总卡在“存哪儿”这一步

做数据采集的人都有个共同经历:传感器、PLC、扫码枪、称重仪这些终端,采数据不难,难的是数据往哪放。放本地文件,机器一重启或者硬盘一坏就没了;放本地数据库,你得给每台终端配环境、建表、写迁移脚本,终端一多维护成本直接起飞;上云买服务器,先不说备案和运维,光一个 MySQL 实例的配置就够折腾半天,最后发现采集频率根本用不上那么重的架构。

更现实的问题是“谁来消费这些数据”。采集终端把数据写进去,通常还有另一端要读走——报表程序、看板、报警服务。传统做法是终端写库、消费端查库,中间要处理并发写、重复读、消费位点,稍微不注意就出现同一条数据被处理两遍,或者某台终端的数据一直没人取。

云递数据这类轻量平台解决的正是这个夹缝需求:不用买服务器和数据库,HTTP/JSON 接口进去,出来就是按写入顺序排队的数据。它不试图替代你的时序数据库,而是把“终端到云端再到消费端”这一段路铺平。理解这一点,后面的接口设计就顺了。

2. 云递数据的实现原理:两个接口、一个数据名

整个产品只有两个核心接口,这是它最容易被低估的地方:

  • 推送接口 POST http://你的域名/api/push.php,请求体是 JSON:{"api_key":"你的APIKey","dataset":"数据名","data":要存的数据}。data 可以是对象、数组,也可以直接是一段文本;api_key 也可以放在 X-Api-Key 请求头里,避免出现在请求体里被日志带出去。
  • 读取接口 POST http://你的域名/api/pull.php,按写入顺序(FIFO)读取,取走即标记已读,不会重复下发;支持分页,也支持按数据名读取。

“数据名”(dataset)是分类的抓手。你可以把它理解成一个个独立队列:sensor_temp 放温度,scan_code 放扫码记录,device_log 放设备日志。写入时平台会自动规范化数据并计算哈希去重,内容完全相同的只保留第一条——这个细节在终端重发场景里非常关键,下面会细说。

还有一个兼容写法值得记一下:?api_key=xxx&dataset=yyy 配合纯文本请求体,可以直接存一段文本。老程序、老设备、甚至某些只能发 GET/POST 表单的脚本,用这个方式接入最省事。

把两个接口放在一起对比,能看清它的定位:

维度push 推送pull 读取
方向终端 → 云端云端 → 消费端
核心参数api_key、dataset、dataapi_key、dataset、分页
顺序语义按写入时间入队FIFO,取走即标记已读
重复处理内容哈希去重,相同内容只留第一条已读数据不会重复下发
典型调用方采集终端、脚本、硬件报表程序、看板、报警服务

3. 分步实现:从注册到跑通第一条数据

第一步是注册拿 APIKey。注册完成后在控制台里就能看到自己的密钥,同时会赠送 3 天会员免费试用,够你把整条链路验证完。正式使用是卡密充值,月卡 19 元、年卡 99 元,卡密以 YK 开头是月卡、NK 开头是年卡,多张可以叠加、到期顺延。

第二步是建数据名。给每类数据起一个语义清晰的名字,比如按设备类型分、按业务分。控制台里可以给数据名加标签备注,终端一多的时候这个备注能救命——半年后你看到 ds_003 这种名字,基本想不起来它是干嘛的。

第三步写推送代码。Python 版本大概长这样:

import requests, time, json

API = "http://你的域名/api/push.php"
KEY = "你的APIKey"

def push_temp(dev_id, temp):
    payload = {
        "api_key": KEY,
        "dataset": "sensor_temp",
        "data": {"dev": dev_id, "temp": temp, "ts": time.strftime("%Y-%m-%d %H:%M:%S")}
    }
    r = requests.post(API, json=payload, timeout=5)
    return r.json()

print(push_temp("T-01", 26.4))

第四步写读取代码。注意 pull 是“消费”语义,读走就标记已读,所以消费端最好把处理逻辑做成幂等——万一你在拿到数据之后、落库之前崩了,这条数据也不会再下发第二次。读取示例:

import requests

API = "http://你的域名/api/pull.php"
KEY = "你的APIKey"

def pull_batch(dataset, page=1):
    payload = {"api_key": KEY, "dataset": dataset, "page": page}
    r = requests.post(API, json=payload, timeout=5)
    return r.json()

result = pull_batch("sensor_temp")
print(result)

第五步,如果你想用最原始的方式验证接口通不通,curl 就够:

curl -X POST "http://你的域名/api/push.php?api_key=你的APIKey&dataset=device_log" \
  -H "Content-Type: text/plain" \
  -d "device T-01 boot ok"

这条走的是兼容写法,纯文本请求体直接存成一条文本数据,适合老程序或者临时排查问题。到这里,注册、建名、推送、读取四步就闭环了。

4. 运行效果:控制台里看清条数、容量与已读状态

代码跑通之后,回到控制台看数据名详情,你会看到三个直观的指标:条数、容量、已读状态。条数是当前队列里积压多少条;容量是占用了多少存储;已读状态则告诉你哪些已经被 pull 走、哪些还在等消费。对采集类业务来说,这三个数字就是你的“水位表”——条数持续上涨说明消费端跟不上,容量异常增长说明有终端在刷数据。

控制台还提供下载、编辑、清空、删除这些操作。我的习惯是:调试阶段用清空重置队列,避免历史数据干扰判断;正式环境慎用删除,先下载备份再动手。下载下来的数据是排查“某条记录到底传没传上来”最直接的证据。

另外说一个实操经验:把终端推送和消费端读取分开两个数据名去观察,比混在一起看更容易定位问题。比如终端侧看到 sensor_temp 条数在涨、消费侧却一直读不到,那问题基本在读取端的鉴权或数据名拼写上,而不是网络。

5. 常见坑与注意事项

坑一:把 pull 当成“查询”。pull 是消费,取走就标记已读,不会重复下发。如果你需要反复查看同一批数据做对账,应该在消费端自己落库,而不是反复调 pull。这是语义问题,不是接口 bug。

坑二:以为重复推送会存两份。平台会对写入内容做规范化并计算哈希去重,内容完全相同只保留第一条。所以终端网络抖动导致的重复推送,不会把队列撑爆。但要注意“完全相同”这个前提——如果你在 data 里带了时间戳,每次时间戳都不同,那在平台看来就是不同内容,自然不会被去重。

坑三:api_key 混进日志。把密钥放 URL 参数或请求体里,很容易被接入层日志、代理日志记录下来。能用 X-Api-Key 请求头的场景尽量用请求头,脚本里也别把密钥硬编码进会提交到代码仓库的文件。

坑四:忽略限流与超时。接口有限流保护,终端侧一定要设超时和重试上限,别在断网时死循环重推,把本地资源耗光。采集频率高的设备建议做本地缓冲,攒批推送。

坑五:会员到期当成数据丢失。会员到期后数据保留不删除,只是暂停推送和读取,续费即恢复。但“不删除”不等于“无限期”——重要数据仍然建议定期下载归档,这是任何云端存储都该有的习惯。

如果你对数据自主可控有硬性要求,云递数据支持私有化部署,技术栈是 Nginx + PHP + MySQL,可以部署到自己的内网或公网服务器。安全层面它做了 API 密钥鉴权、PDO 预处理防注入、CSRF 防护、登录防爆破和接口限流,但这不意味着你可以省掉终端侧的基本防护。

常见问题

数据采集终端用 HTTP 推数据,网络不稳定会不会丢数据?

HTTP 本身是请求-响应模型,网络中断时请求会失败,失败的那一条如果终端不重试就确实没写进去。所以“会不会丢”取决于终端侧的重试策略,而不是接口单方面能保证的。实践做法是:推送失败后本地落盘缓冲,按退避间隔重试;由于平台对相同内容做了哈希去重,重试导致的重复推送不会产生多余数据,这一点可以放心。

push 接口重复推送同一条数据会存两份吗?

不会。写入时平台会自动规范化并计算哈希,内容完全相同的数据只保留第一条。需要注意的是,如果你在 data 里放了每次都变化的时间戳或自增序号,那两次推送的内容就不相同,平台会当作两条不同数据保存——去重针对的是“完全相同的内容”。

pull 取走的数据还能再读一次吗?

不能。pull 是按写入顺序 FIFO 读取,取走即标记已读,不会重复下发。这是队列式消费的设计,目的是让消费端不会重复处理。如果需要保留副本用于对账或回溯,请在拿到数据后自行落库,或者提前在控制台下载备份。

会员到期后,采集终端之前存的数据会被删掉吗?

不会。会员到期后数据保留不删除,只是暂停推送和读取,续费后恢复。建议仍然养成定期下载归档的习惯,尤其是关键业务数据,不要把“保留”当成长期备份方案。

能不能把云递数据部署到自己的内网服务器上?

可以。产品支持私有化部署,运行环境是 Nginx + PHP + MySQL,可以部署到你自己的内网或公网服务器,数据完全自主可控。部署后接口路径与占位域名对应替换即可,终端侧代码不需要改逻辑,只改地址。

开始使用

本文的代码示例都可以直接在云递数据上运行:注册后即可获得专属 APIKey,在 开发文档 中查看推送、读取接口的完整说明;需要长期使用可以在 会员中心 用卡密开通月卡或年卡;更多实战内容可以浏览技术博客的其他文章。