回到2021年,一位客户找到我,提出了看似直截了当的需求:"我们需要一个拍卖网站。像eBay一样,但是利基市场——经典摩托车零件。"三个月、两个被放弃的原型和一次真正令人尴尬的生产故障之后,我有了意见。强烈的意见。最后我们成功了,但现在我不会用同样的方式构建它。一点都不会。
拍卖平台出乎意料地困难。表面上只是列表、竞价和计时器。但一旦两个用户在毫秒内竞价,或者你的WebSocket连接在倒计时到零时断掉,或者你的支付处理器在捕获中途超时——突然你就得向一个非常生气的卖家解释为什么他们的1967年BSA闪电摩托车以12英镑成交了。所以让我逐个工具、逐项决定地走你过我2026年实际会构建什么。
---
核心架构决策:单体还是服务?
不要让任何人为第一版本向你兜售微服务。我是认真的。
我多次看到这个错误——创始人雇佣顾问,顾问在白板上画出八个独立服务,所有人都点头同意,六个月后什么都没发布,因为团队在调试一个只有40个用户的平台上的服务间延迟。对于拍卖MVP,甚至中等规模的产品(比如月活用户少于50,000),模块化单体架构是正确的选择。modular monolithis the right call.
我会选择:前端和API层用Next.js,Node.js后端。不是因为它很流行。而是因为Next.js 14+中的服务器组件模型确实降低了拍卖列表页面的复杂性——那种SEO真正重要的页面——你希望那些拍品描述被索引。API路由处理轻量级任务;重度实时任务放在其他地方(稍后会详细讲)。Next.json the frontend and API layer, with a Node.js backend. Not because it's trendy. Because the server components model in Next.js 14+ genuinely reduces the complexity of auction listing pages where SEO actually matters — you want those lot descriptions indexed. The API routes handle lighter lifting; the heavy real-time stuff lives elsewhere (more on that in a moment).
数据库?PostgreSQL。任何事务性应用都选PostgreSQL。拍卖是深度关系型的——用户、拍品、出价、底价、发票——你希望外键约束真正发挥作用,而不是凭直觉编写应用逻辑。2026年我会在Supabase上运行它,因为你可以得到Postgres、行级安全性和内置的实时订阅层,这把过去需要三个独立基础设施关注点的东西合并成一份账单。Supabasein 2026 because you get Postgres, row-level security, and a real-time subscription layer baked in, which collapses what used to be three separate infrastructure concerns into one bill.
---
实时竞拍:会让你崩溃的部分
这是大多数拍卖平台失败的地方。或至少是跛行的地方。
根本问题:竞价必须感觉是即时的,必须保持一致,必须正确处理竞态条件。如果两个用户在同一毫秒提交出价,其中一个赢了。数据库决定谁赢。不是前端,不是负载均衡器——是数据库,通过一个正确编写的带SELECT FOR UPDATE的事务。SELECT FOR UPDATE.
对于实时层本身,2026年我会用Ably而不是自己实现原生WebSockets。我在2022年于Seahawk的一个房产拍卖项目上试过原生方式——自托管socket.io、Redis pub/sub,样样齐全。它一开始很好,直到某个时刻不好为止。Ably给你保证的消息顺序、连接状态恢复(所以如果竞拍者的手机在拍卖进行中从WiFi切换到4G,他们不会默默错过成功的出价),还有一个合理的仪表板。规模化的定价是真实的成本,但对大多数拍卖运营商来说,与基础设施复杂性相比不值一提。Ablyin 2026 rather than rolling raw WebSockets. I tried the raw approach on a property auction project at Seahawk back in 2022 — self-hosted socket.io, Redis pub/sub, the works. It was fine until it wasn't. Ably gives you guaranteed message ordering, connection state recovery (so if a bidder's phone switches from WiFi to 4G mid-auction, they don't silently miss the winning bid), and a sensible dashboard. The pricing at scale is real, but for most auction operators it's noise compared to infrastructure complexity.
处理"秒杀"问题
拍卖秒杀——在最后几秒下单——取决于你的客户是把它当功能还是bug。eBay出名的做法是允许它。许多专业拍卖行在最后一分钟内有出价时会延长计时器30-60秒。这被称为"软关闭"或"反秒杀"逻辑。从第一天起就构建它。规则很简单:
- 竞价在剩余少于 N 秒时到达
- 交易确认竞价有效且为最高出价
- 拍卖结束时间延长 N 秒
- 新的结束时间通过 Ably 广播给所有连接的客户端
这大概是 40 行服务器逻辑。跳过它并在后期拼凑上去会很麻烦。
---
支付:别想太复杂
我见过人们在拍卖网站上采用复杂的支付方案,因为拍卖有奇特的需求——你提前捕获支付详情,只在拍品成交时收费,可能需要持有定金,如果被超价可能需要立即退款。这些都是真的。这些都可以用 Stripe 解决,无需离开 Stripe 文档。
2026 年的 Stripe 对绝大多数拍卖运营者来说仍然是正确的选择。具体来说:in 2026 is still the right answer for the vast majority of auction operators. Specifically:
- Stripe Payment Intents 用于标准竞价到收费的流程for the standard bid-to-charge flow
capture_method: 手动授权卡片而不扣款(对押金冻结至关重要)to authorise a card without charging it (essential for deposit holds)- 如果你正在构建一个多个卖家收到付款的市场,可以使用 Stripe Connect
我要指出的一点:除非你有法律建议说必须这样做,否则不要预先授权全部拍品价值的卡片。授权押金金额(在拍卖行业中 10–25% 很常见),然后在拍品结束后进行扣款或撤销。你的卡片拒绝率会因此下降。
对于较高价值的拍卖行——古董车、美术品等——你需要支持银行转账。Stripe 现在通过其支付链接和发票产品处理得相当不错,但你仍需要人工参与对账。为此构建一个简单的管理队列;别把不需要自动化的东西自动化了。
---
搜索和筛选:用 Typesense,不是 Elasticsearch
说实话,拍卖平台上的搜索问题被低估了。用户需要按类别、当前价格、剩余时间、状况、地点进行筛选。而且要快。
对大多数拍卖网站来说 Elasticsearch 显得过度设计,而且运维很烦人。我会用 Typesense。它是开源的,你可以自托管在 6 美元的 DigitalOcean droplet 上,或者用 Typesense Cloud,搜索质量对目录式数据来说非常好。通过简单的变更数据捕获钩子或每 30 秒的 cron 任务把你的 PostgreSQL 拍品表同步到 Typesense(拍品价格的实时同步很好看,但搜索用途中很少必需)。Typesenseis what I'd use. It's open source, you can self-host on a $6 DigitalOcean droplet or use Typesense Cloud, and the search quality is excellent for catalogue-style data. Sync your PostgreSQL lots table to Typesense via a simple change-data-capture hook or a cron job every 30 seconds (real-time sync of auction lot prices is nice but rarely necessary for search).
Typesense 有一个开箱即用处理不好的地方:仅限自提物品的地理搜索。它确实有地理筛选功能,但如果你的拍卖网站有大量"仅限本地取货"的库存,早期花半天时间配置这个。我没有,在 2023 年的一个园艺机械拍卖网站上,后来我们事后改造时花了两倍的功夫。
---
基础设施和托管
这是我 2026 年的默认配置:
- Vercel 用于 Next.js 前端和 API 路由——零配置部署、每个分支都有预览 URL、必要时使用边缘函数for the Next.js frontend and API routes — zero config deployments, preview URLs per branch, edge functions where needed
- Supabase 用于 PostgreSQL 和身份认证for PostgreSQL and auth
- Ably 用于 WebSocketfor WebSockets
- Typesense Cloud 用于搜索for search
- Cloudflare 作为所有服务的前置——免费层可以处理 DDoS、图像优化和缓存,无需额外配置in front of everything — free tier handles DDoS, image optimisation, and caching without fuss
- Uploadcare 或 Cloudinary 用于卖家上传的拍品图片(2026 年请不要再把用户上传的文件存储在自己的服务器上)orCloudinaryfor seller-uploaded lot images (never store user uploads on your own server in 2026, please)
这个技术栈不需要 Kubernetes、不需要自管理的 Redis 集群、不需要聘请 DevOps 工程师。一个独立开发者或小团队就能运营它。更重要的是——它可以无需重新架构就扩展。当你的网站被行业刊物报道、一小时内涌入 8,000 人时,Vercel 和 Supabase 会搞定流量激增。
一个我经常看到的基础设施错误
人们容易忽视后台任务。拍卖结束事件不是由用户触发的——它们在特定的时间戳、服务器端发生。你需要一个可靠的任务调度器。我在2026年会用Inngest来做这件事。它处理基于时间的触发、重试,并给你一个真正有用的事件日志,当你调试"为什么第447件拍品关闭了但没有发送赢家邮件"的时候很有帮助。不要用你服务器上的简单cron。当你的服务器重启时,你的cron状态就消失了。Inngestfor this in 2026. It handles time-based triggers, retries, and gives you an event log that's actually useful when you're debugging "why did lot 447 close without sending the winner email". Don't use a simplecronon your server. When your server restarts, your cron state is gone.
---
管理员和卖家工具
卖家需要创建列表、上传图片、设置底价和查看出价历史。买家需要关注列表、出价提醒和发票下载。这些不是光彩的功能。但这些是客户在周四晚上9点打电话给你时会投诉的功能。
对于管理面板,根据预算,我会在Retool或自定义的Next.js仪表板之上轻量级构建。Retool真的能很快搭建起来,并处理拍卖管理工作的80%——批准列表、管理用户、作废出价——不需要写太多代码。对于任何面向客户端的东西,我会在Next.js中正确构建,因为Retool嵌入在iframe中不是好的用户体验。Retoolor a custom Next.js dashboard depending on budget. Retool is genuinely fast to stand up and handles the 80% of auction admin tasks — approving listings, managing users, voiding bids — without writing much code. For anything client-facing I'd build properly in Next.js, because Retool embedded in an iframe is not a good user experience.
电子邮件通知——被超价警告、拍品即将结束、发票已就绪——在2026年通过Resend发送。大约18个月前它在我的技术栈中替代了SendGrid,我再也没有回头看过。开发者体验明显更好,投递率也很稳定。Resendin 2026. It replaced SendGrid in my stack about 18 months ago and I haven't looked back. The developer experience is notably better and the deliverability has been solid.
---
拍卖特定的安全考虑
拍卖平台会吸引出价操纵尝试。刷单(卖家用虚假账户抬高自己拍品价格)、账户接管来进行欺诈性赢价出价,以及支付欺诈都是真实存在的,相比典型的电商来说不成比例地常见。
有几件事我会从一开始就设计进去:
- 投标提交速率限制——每个用户每分钟每件拍卖品的最大投标数量,在API层强制执行。Upstash Redis很适合这个需求;它有专门的速率限制库。— max N bids per user per minute per lot, enforced at the API layer. Upstash Redis is good for this; it has a purpose-built rate limiting library.
- 投标前需要邮箱验证——听起来很基础,但能防止意外多的滥用情况— sounds obvious, stops a surprising amount of abuse
- 通过Stripe Radar进行欺诈评分——已经包含在Stripe中,直接使用就可以— already included in Stripe, just use it
- 为可疑账户群集进行IP和设备指纹识别——如果你运营的规模足够大,FingerprintJS Pro值得花钱—FingerprintJS Prois worth the cost if you're operating at any meaningful scale
老实说,最重要的是日志。记录每次投标尝试、每次失败的支付、每个账户操作。当出问题时——肯定会出问题——你需要完整的审计日志。Supabase的内置日志加上Axiom的轻量级设置可以轻松满足需求。Axiomcovers this without much effort.
---
常见问题
小型本地拍卖网站的最小可行堆栈是什么?
如果你为一个本地拍卖行构建网站,可能有200个用户和每周销售,你不需要Ably或Typesense。用WordPress搭配Auctions for WooCommerce这样的插件效果出乎意料地好。我为三个地区拍卖行设置过这种网站——古董、农业设备,那种类型的。一旦你需要在高负载下进行实时竞争投标,它就会很快过时。Auctions for WooCommercegets you surprisingly far. I've set up three of these for regional auction houses — antiques, farm equipment, that sort of thing. The moment you need real-time competitive bidding under load, outgrow it fast.
我可以用Firebase代替Supabase吗?
可以。Firebase 的 Firestore 实际上对于实时竞价状态来说是合理的选择。我之所以在 2026 年更倾向于 Supabase,是因为 SQL——拍卖数据有很多关系结构(地段属于销售,竞价属于地段和用户,发票引用竞价),用文档数据库查询这些会很混乱。但如果你的团队已经深入了解 Firebase,就不要为了改而改。
我应该如何处理拍卖结束时间的时区问题?
将所有内容存储在 UTC 中。永远如此。通过浏览器以用户的本地时区显示。这听起来很明显,但我仍然看到大约五个项目中有一个做错了。现代浏览器中的 Intl.DateTimeFormat API 无需任何库就能处理显示端。Intl.DateTimeFormatAPI in modern browsers handles the display side without any library.
我需要一个移动应用吗?
MVP 不需要。一个设计精良的渐进式网络应用加上推送通知(通过 Web Push API)可以满足竞价者在移动设备上实际需要的 90% 功能。如果业务需要的话,原生应用以后再考虑。到那时我会使用 Expo 和 React Native——iOS 和 Android 共享代码库,团队已经了解 React。ExpoandReact Nativewhen that day arrives — shared codebase across iOS and Android, and the team already knows React.
---
在线运营拍卖是一项合法的工程挑战,却被伪装成一个欺骗性的简单 UI。竞价界面就是三个按钮和一个数字。其下面的一切——一致性、公平性、实时状态、欺诈防止——才是真正的工作所在。从一开始就选对技术栈,其余的就只是功能。选错了,你就是那个向卖家解释他们的地段为什么以 £12 成交的人。
构建无趣的基础设施。在其之上构建有趣的产品。
