「50个边缘函数就是天花板,但我的赛马预测系统有4个核心接口——这个硬约束怎么破?」

一位开发者在搭建日本赛马数据流水线时,遇到了所有边缘计算玩家都会撞上的墙。他的解法不是扩容,而是把架构揉碎了重组。这背后藏着一套值得所有中小团队抄作业的设计哲学。

打开网易新闻 查看精彩图片

从编码陷阱到流水线骨架

日本赛马数据的第一个坑,藏在字符编码里。

JRA(日本中央竞马会)和NAR(地方竞马,覆盖15个地区赛场)的官网都用EUC-JP编码。但Python在Windows默认走CP932,直接解码会吐出乱码。开发者的防御性写法是显式指定errors='replace'——遇到无法识别的字节就替换,而不是崩溃。

这套Python抓取脚本fetch_horse_racing.py跑在两条轨道上:本地Windows开发机,和GitHub Actions的Ubuntu容器。编码一致性是跨平台的第一道门槛。

数据流明确分层:抓取层→边缘函数层→数据库层→调度层→展示层。每一层只干一件事,这是流水线能自动运转的前提。

边缘函数的「瑞士军刀」模式

Supabase的边缘函数有硬上限:50个。开发者已经部署了16个,赛马系统需要4个独立接口(今日赛事/批量预测/预测查询/准确率统计)。

他的解法是把4个接口塞进1个边缘函数,用action参数路由:

tools-hub这个边缘函数内部有个switch语句,horseracing.today走今日赛事,horseracing.predict_all走批量预测,horseracing.predictions查历史预测,horseracing.accuracy看统计。」

这叫hub模式:一个部署单元,多种行为形态。代价是代码内聚度升高,收益是名额大幅节省。对于卡在50上限的团队,这是必选项而非可选项。

权限设计也做了切割。GitHub Actions调用边缘函数时没有用户JWT(JSON网络令牌,一种身份验证凭证),所以todaypredictions被划入免认证区。最初放在认证区,流水线直接报401错误——这是自动化系统和用户系统的权限模型冲突。

数据库查询的性能悬崖

Supabase的Postgres连接在批量查询时会超时。开发者最初用SELECT * FROM horse_results拉全表,数据量一大直接挂掉。

修复方案是并行单条查询:把赛事ID列表拆开,每个ID单独查,再用Promise.all并发执行。从「一次大查询」变成「多次小查询并行」,延迟从超时降到可接受范围。

这是无服务器数据库的典型陷阱:连接池和超时限制逼你改变查询模式,而不是加机器。

定时调度的最后一公里

GitHub Actions承担定时触发,每小时跑一次完整流水线:fetch_horse_racing.py抓数据→调边缘函数→写数据库。YAML配置文件里藏着编码处理、超时设置、错误重试的细节。

Flutter前端用三栏布局展示:今日赛事列表、预测结果、历史准确率。数据层完全托管,UI层只负责消费。

这套架构的隐藏成本在于:边缘函数的名额焦虑、数据库查询的模式迁移、编码问题的跨平台防御——都不是业务代码,却是系统能跑起来的基础设施。

赛马数据每天更新,流水线每小时运转,预测结果实时可查。全自动化的背后,是一连串被硬约束逼出来的设计选择。