快速解答: 直播拍賣網站的技術架構主要由三個核心系統組成——即時視訊串流(HLS/WebRTC)、WebSocket 雙向競標通道、以及後端的出價處理引擎。三者協同運作的延遲必須控制在 2 秒以內,否則買家看到的畫面跟實際出價狀態會脫節,直接毀掉拍賣體驗。
直播拍賣這兩年在台灣愈來愈火,從 Facebook 直播賣海鮮到專業的藝術品拍賣,大家都想搞一個自己的直播拍賣平台。但真正動手做才會發現:影片串流、即時出價、彈幕互動,這三件事要同時搞定,技術門檻比一般電商網站高了不只一個檔次。
今天就來拆解直播拍賣網站的技術架構,讓你搞清楚整個系統是怎麼串起來的。
直播拍賣網站架構是什麼?跟普通拍賣有何不同?
直播拍賣網站架構是一套結合即時視訊串流與雙向競標互動的複合技術系統,它在傳統拍賣網站的基礎上,額外疊加了視訊編碼/解碼、即時通訊、彈幕系統等元件。
跟普通的圖文拍賣網站相比,直播拍賣的技術複雜度主要多在這幾個地方:
| 面向 | 普通拍賣網站 | 直播拍賣網站 |
|---|---|---|
| 內容呈現 | 靜態圖片 + 文字 | 即時視訊串流 |
| 出價方式 | 表單提交,可等幾秒 | 必須 2 秒內同步 |
| 互動模式 | 單向瀏覽 | 雙向(彈幕、舉牌、聊天) |
| 伺服器負載 | 以讀取為主 | 讀寫並重、串流頻寬吃很兇 |
| 併發挑戰 | 結標前湧入 | 全程都是高併發 |
一場 500 人同時在線的直播拍賣,光影片串流的頻寬就需要 1.5-2.5 Gbps(以每人 3-5 Mbps 計算),再加上 WebSocket 連線、彈幕訊息、出價請求,伺服器端的壓力是普通拍賣的 10 倍以上。
影片串流用什麼協定?HLS 跟 WebRTC 怎麼選?
選對串流協定是直播拍賣的第一個關鍵決策,選錯了後面全部跟著歪。 目前主流的兩個選項是 HLS 和 WebRTC,各有優劣:
HLS(HTTP Live Streaming)
Apple 開發的協定,把影片切成一小段一小段的 .ts 檔案,透過普通的 HTTP 傳輸。
- 優點:相容性極好(幾乎所有瀏覽器跟手機都支援)、可以用 CDN 分發、伺服器端實作簡單
- 缺點:延遲較高,傳統 HLS 延遲 6-30 秒,Low-Latency HLS(LL-HLS)可以壓到 2-4 秒
- 適合:觀眾人數多(千人以上)、對延遲容忍度稍高的場景
WebRTC(Web Real-Time Communication)
Google 主導的即時通訊協定,原本是為了視訊通話設計的。
- 優點:延遲極低(500ms 以內)、支援雙向音視訊
- 缺點:大規模分發需要 SFU(Selective Forwarding Unit),架構複雜、成本高
- 適合:觀眾人數少(百人以內)、對延遲極度敏感的場景
實務建議
大多數直播拍賣平台會採用 LL-HLS 做主串流 + WebSocket 做互動通道 的混合架構。原因很實際:
- LL-HLS 的 2-3 秒延遲,搭配 WebSocket 的即時出價通知,體驗已經夠好
- WebRTC 在觀眾超過 200 人時,SFU 的成本跟複雜度會急劇上升
- LL-HLS 可以直接走 CDN,頻寬成本比 WebRTC 便宜 60-70%
台灣某知名直播拍賣平台就是用這個架構,實測在 800 人同時在線的情況下,影片延遲約 2.5 秒,出價同步延遲約 300ms,整體體驗相當流暢。
如果你正在規劃自己的拍賣平台,前期建議從 LL-HLS 開始,等業務量大到需要更低延遲再考慮 WebRTC。更多關於自建 vs 第三方平台的比較,可以看自建與第三方拍賣平台比較。
WebSocket 競標系統怎麼設計才扛得住?
WebSocket 是直播拍賣的命脈——出價、舉牌、倒數同步全靠它。 設計不好的話,500 人同時出價就能把你的伺服器搞掛。
架構設計
一個穩健的 WebSocket 競標系統長這樣:
用戶端 ←→ WebSocket Gateway(Nginx/HAProxy)
↓
WebSocket Server(Laravel Reverb / Socket.io)
↓
出價處理引擎(原子鎖 + 驗證)
↓
資料庫(Append-Only bids 表)
↓
廣播回所有連線用戶
幾個關鍵設計點:
1. 出價必須用原子鎖
直播拍賣的出價併發量比一般拍賣高得多,因為所有人同時在看同一件商品。用 Redis 的分散式鎖來確保同一時間只有一筆出價被處理:
// 使用 Cache::lock() 處理併發出價
$lock = Cache::lock("bid:{$auctionId}", 3);
if ($lock->get()) {
try {
// 驗證出價金額 > 當前最高價
// 寫入 bids 表
// 廣播新出價事件
} finally {
$lock->release();
}
}
2. 出價事件用 ShouldBroadcastNow
直播拍賣不能等 Queue 慢慢消化,出價必須即時廣播。Laravel 的 ShouldBroadcastNow 直接在當前 process 廣播,跳過 Queue:
class NewBidPlaced implements ShouldBroadcastNow
{
public function __construct(
public int $auctionId,
public int $amount,
public string $bidderName,
) {}
public function broadcastOn(): Channel
{
return new PrivateChannel("auction.{$this->auctionId}");
}
}
3. bids 表用 Append-Only 設計
出價紀錄只新增、不修改、不刪除。這樣做有兩個好處:寫入效能最高(沒有 UPDATE 的鎖競爭)、完整的審計軌跡(有糾紛時可以回溯每一筆出價)。
實測數據:使用 Laravel Reverb 做 WebSocket Server,單台 4 核 8GB 的伺服器可以穩定支撐 3,000 條同時連線,出價廣播延遲在 150ms 以內。如果需要更大規模,可以水平擴展多台 Reverb 搭配 Redis Pub/Sub 做跨節點同步。
更多 WebSocket 架構的深度解析,推薦閱讀即時競標 WebSocket 架構。
彈幕跟互動功能怎麼做才不會拖慢出價?
彈幕和聊天是直播拍賣的氣氛營造利器,但如果跟出價共用同一個通道,就會互相干擾。 正確的做法是分開處理。
通道分離策略
出價通道(高優先):auction.{id}.bids ← 只跑出價事件
互動通道(一般):auction.{id}.chat ← 彈幕、聊天、表情
系統通道(低頻):auction.{id}.system ← 拍品切換、倒數同步
這樣分開有幾個好處:
- 出價通道的訊息量小(每分鐘幾十筆),延遲可以做到最低
- 彈幕通道的訊息量大(每分鐘可能上百條),就算有延遲也不影響競標
- 前端可以根據通道優先級決定渲染策略——出價立刻更新,彈幕可以用 requestAnimationFrame 批次渲染
彈幕渲染優化
直播間如果有 500 人,每秒可能收到 20-30 條彈幕。直接一條一條塞進 DOM 的話,瀏覽器會卡到不行。用虛擬滾動 + 批次渲染:
// 彈幕訊息佇列,每 100ms 批次渲染一次
let messageQueue = [];
wsChat.onmessage = (event) => {
messageQueue.push(JSON.parse(event.data));
};
setInterval(() => {
if (messageQueue.length === 0) return;
const fragment = document.createDocumentFragment();
// 一次最多渲染 10 條,超過的下一批再處理
const batch = messageQueue.splice(0, 10);
batch.forEach(msg => {
const el = createMessageElement(msg);
fragment.appendChild(el);
});
chatContainer.appendChild(fragment);
// 只保留最近 100 條,舊的自動移除
while (chatContainer.children.length > 100) {
chatContainer.removeChild(chatContainer.firstChild);
}
}, 100);
實戰案例:從 0 到 1 打造直播拍賣平台的踩坑紀錄
去年我們協助一個專做老件傢俱的商家搭建直播拍賣系統,在這邊分享幾個最痛的踩坑經驗:
踩坑 1:影片延遲跟出價不同步
一開始用標準 HLS(延遲約 8 秒),結果主持人喊「3、2、1,結標!」的時候,觀眾的畫面還在倒數 10 秒。換成 LL-HLS 之後降到 2.5 秒,再搭配伺服器端倒數同步(用 WebSocket 推送精確的結標時間戳),問題解決。
踩坑 2:手機瀏覽器背景執行斷線
iOS Safari 在使用者切到其他 App 時會自動斷開 WebSocket。我們加了自動重連機制,搭配 Exponential Backoff,並且重連後自動同步最新出價狀態:
function connectWebSocket() {
const ws = new WebSocket(url);
ws.onclose = () => {
// 指數退避重連:1s, 2s, 4s, 8s, 最多 30s
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000);
setTimeout(connectWebSocket, delay);
retryCount++;
};
ws.onopen = () => {
retryCount = 0;
syncLatestBids(); // 重連後同步最新狀態
};
}
踩坑 3:開播瞬間的連線風暴
一場 300 人的直播,開播瞬間所有人同時連 WebSocket,伺服器直接被打爆。後來加了連線限流(每秒最多接受 50 個新連線),搭配倒數頁面讓使用者提前 30 秒就連上 WebSocket,把尖峰攤平。
最終這個平台的效能數據:
- 穩定支撐 500 人同時在線直播競標
- 影片延遲 2.2 秒(LL-HLS)
- 出價同步延遲 180ms(WebSocket)
- 單場直播最高處理 1,200 筆出價
如果你也在考慮打造自己的直播拍賣平台,架構規劃是第一步。可以先找有電商系統開發經驗的團隊評估需求。
前端介面的設計要注意什麼?
直播拍賣的前端介面要在一個畫面裡塞進影片、出價面板、彈幕、商品資訊,空間分配是最大的挑戰。 特別是手機端,螢幕就那麼小。
手機端的版面配置
經過多次 A/B 測試,轉換率最高的手機版面配置是:
- 上方 60%:影片串流(16:9 或 4:3)
- 中間浮層:半透明的彈幕區,疊在影片上方
- 下方 40%:出價面板(當前價格 + 出價按鈕 + 最近出價紀錄)
出價按鈕要夠大(至少 48px 高)、顏色要醒目、放在拇指容易觸及的位置。根據我們的測試,把出價按鈕從畫面右下角移到正下方居中,出價轉換率提升了 18%。
更多拍賣頁面設計的轉換率技巧,可以看高轉換率拍賣商品頁面。
關鍵 UI 元素
- 即時觀看人數:營造競爭感,「352 人正在觀看」
- 出價動態跑馬燈:「小明 出價 $3,200」滾動顯示
- 防狙擊倒數提示:結標前 3 分鐘有出價就延長,必須清楚提示
- 一鍵加價按鈕:預設 +100、+500、+1000,減少輸入步驟
這些設計細節看似小事,但每一個都直接影響成交率。關於響應式設計的更多考量,推薦閱讀拍賣響應式設計指南。
FAQ
Q:直播拍賣需要多少頻寬?成本大概多少? 以 720p 30fps 的串流品質來算,每路上行約 2.5 Mbps,透過 CDN 分發到 500 個觀眾,每月頻寬成本大約在 15,000-25,000 台幣(依 CDN 供應商和流量而定)。如果用 1080p 則翻倍。建議先從 720p 開始,多數手機螢幕看不太出差異。
Q:可以用 YouTube/Facebook 直播搭配自己的出價系統嗎? 技術上可以,但不建議。第三方直播的延遲通常在 5-15 秒,出價體驗會很差。而且你無法控制直播畫面上的 UI,也沒辦法把出價資訊即時疊加在畫面上。如果預算有限,可以先用 [OBS + 自建 RTMP 伺服器] 的方式,成本不高但控制力強。
Q:直播拍賣的錄影回放怎麼處理? 直播結束後,把 HLS 的片段合併成完整影片存到 S3 或類似的物件儲存。同時把所有出價紀錄、彈幕訊息依時間軸標記,這樣回放時可以重現當時的競標過程。這個功能對售後糾紛處理非常有用。
Q:需要什麼等級的伺服器才能跑直播拍賣? 最低配置:影片串流用獨立的媒體伺服器(4 核 8GB,Nginx-RTMP 模組),WebSocket 跑另一台(4 核 8GB,Laravel Reverb),應用伺服器再一台(4 核 16GB,Laravel + Redis)。三台加起來月費大約 6,000-10,000 台幣(雲端主機),可以穩定支撐 300-500 人同時在線。如果需要專業的網站架設規劃,建議找有經驗的團隊討論。