首頁 > web前端 > js教程 > 主體

使用 Redis 分散式鎖建立可擴展的插槽預訂系統

Patricia Arquette
發布: 2024-10-22 20:48:28
原創
568 人瀏覽過

Building a Scalable Slot Booking System with Redis Distributed Locks

在當今快節奏的數位世界中,無縫且可擴展的預訂系統至關重要,尤其是當多個用戶嘗試同時預訂同一時段時。本部落格概述了使用Redis進行分散式鎖定的插槽預訂系統的底層設計,這確保用戶可以在不遇到競爭條件的情況下預訂插槽。透過利用 Redis,我們可以管理並發性和可擴展性,確保我們的預訂系統在高需求下有效運作。

系統的關鍵組件

在深入探討技術方面之前,我們先來分解核心組件:

  1. 使用者:代表使用系統預約時段的個人。
  2. Slot:表示使用者可以預約的有時限的單元(例如會議室、活動)。
  3. Redis 分散式鎖定:確保兩個使用者不能同時預約同一個時段的關鍵功能。
  4. MongoDB:儲存使用者和插槽資訊。
  5. Redis:充當鎖定管理器來處理競爭條件。

預訂系統的挑戰

當多個用戶嘗試同時預訂同一時段時,預訂系統很容易陷入重複預訂或競爭條件等問題。如果沒有適當的並發控制,兩個用戶可能會無意中預訂同一個時段,導致沮喪和衝突。

這就是Redis分散式鎖發揮作用的地方。使用鎖定可確保在任何給定時間只有一個用戶可以預訂時段。


1. 模型:定義使用者和插槽

首先,我們需要為使用者設計資料模型。這些模型將儲存在 MongoDB 中,其結構簡單但有效。

一個。 使用者模型

每個使用者都有基本屬性,如姓名、電子郵件和用於驗證的雜湊密碼:

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
    name: { type: String, required: true },
    email: { type: String, required: true, unique: true },
    password: { type: String, required: true },
    createdAt: { type: Date, default: Date.now }
});

module.exports = mongoose.model('User', UserSchema);
登入後複製
登入後複製

b. 老虎機模型

每個時段都有開始和結束時間,並追蹤是否已被預訂以及由誰預訂:

const mongoose = require('mongoose');

const SlotSchema = new mongoose.Schema({
    startTime: { type: Date, required: true },
    endTime: { type: Date, required: true },
    isBooked: { type: Boolean, default: false },
    bookedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User', default: null }
});

module.exports = mongoose.model('Slot', SlotSchema);
登入後複製

2. API端點:使用者如何與系統交互

API是使用者和系統之間的橋樑。以下是所需的關鍵端點:

一個。 用戶註冊

允許新用戶註冊:

  • 端點:POST /api/users/register
  • 請求:使用者詳細資料(姓名、電子郵件、密碼)
  • 回覆:用戶註冊確認

b. 使用者登入

對使用者進行身份驗證並提供 JWT 令牌:

  • 端點:POST /api/users/login
  • 請求:使用者憑證(電子郵件、密碼)
  • 回應:用於身份驗證的 JWT 令牌

c. 建立插槽

允許管理員或授權使用者建立槽:

  • 端點:POST /api/slots/create
  • 請求:時段開始與結束時間
  • 回應:確認插槽建立

d. 書位

允許用戶預訂可用時段:

  • 端點:POST /api/slots/book/:id
  • 請求:標頭中的 JWT 令牌,URL 中的插槽 ID
  • 回應:時段預訂確認或錯誤(例如,如果時段已預訂)

3.Redis分散式鎖的工作原理

併發是預訂系統面臨的最大挑戰。當多個用戶嘗試同時預訂同一個時段時,Redis 會以其分散式鎖定功能來救援。

使用Redis鎖定的預約流程

  1. 鎖定取得:

    • 當使用者嘗試預訂插槽時,系統會嘗試使用 SET lock_key NX EX 10 指令在 Redis 中取得鎖定。
    • NX(如果不存在則設定)確保僅在鎖尚不存在時建立鎖,而 EX 10 確保鎖定在 10 秒後過期(防止死鎖)。
    • 如果已經取得了鎖,系統會返回 423 Locked 狀態,通知用戶該插槽已被其他人預訂。
  2. 插槽可用性檢查

    • 如果成功取得鎖定,則會查詢 MongoDB 以檢查該插槽是否仍然可用(即未預訂)。
    • 如果空位可用,系統會將空位的狀態更新為已預訂,並將 bookingBy 欄位設定為目前使用者的 ID。
  3. 鎖定釋放

    • 一旦預訂程序完成,或發生錯誤,系統會透過使用 DEL lock_key 指令刪除 Redis 金鑰來釋放鎖定。

使用 Redis 鎖預訂插槽的範例程式碼:

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
    name: { type: String, required: true },
    email: { type: String, required: true, unique: true },
    password: { type: String, required: true },
    createdAt: { type: Date, default: Date.now }
});

module.exports = mongoose.model('User', UserSchema);
登入後複製
登入後複製

4. 預訂系統中的錯誤處理

優雅地處理錯誤是任何健壯系統的重要組成部分。以下是系統處理的一些錯誤:

  • 400 Bad Request:當輸入資料無效時。
  • 404 Not Found:當未找到要求的插槽或使用者。
  • 423 已鎖定:當某個時段目前被其他使用者預訂時。
  • 500 內部伺服器錯誤:任何意外錯誤,例如資料庫或 Redis 故障。

5. 保護系統安全

安全至關重要,尤其是當用戶預訂資源時。以下是系統確保安全的方式:

  • JWT 驗證:每個插槽預訂請求都需要有效的 JWT 令牌,確保只有經過驗證的使用者才能存取系統。
  • 資料驗證:每一步都會驗證輸入數據,以防止處理無效或惡意資料。
  • 鎖定過期:Redis 鎖有一個內建的過期時間(10 秒),以防止預訂過程中途失敗時發生死鎖。

6. 可擴展性考量因素

系統在建置時考慮到了可擴展性。隨著需求的增加,以下策略可確保順利營運:

  • 用於並發的 Redis:Redis 鎖定確保即使應用程式的多個實例正在運行,也可以避免競爭條件。
  • Redis Clustering:如果系統顯著成長,可以使用Redis Clustering將負載分佈到多個Redis節點上,從而提高效能。

結論

建立可擴展且可靠的老虎機預訂系統需要仔細考慮並發性、資料完整性和安全性。透過使用Redis分散式鎖定,我們可以確保沒有兩個用戶同時預訂同一個時段,從而消除競爭條件。此外,透過利用MongoDB進行資料持久化和JWT進行身份驗證,該系統是安全、可擴展且高效的。

無論您是為會議室、活動或任何其他有時間限制的資源設計預訂系統,此架構都為在重負載下可靠地管理預訂提供了堅實的基礎。

以上是使用 Redis 分散式鎖建立可擴展的插槽預訂系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!