10萬QPS高并發請求,如何防止重復下單

1. 前端攔截?

首先因為是10萬QPS的高并發請求,我們要保護好系統,那就是盡可能減少用戶無效請求。

1.1 按鈕置灰

很多用戶搶票、搶購、搶紅包等時候,為了提高搶中的概率,都是瘋狂點擊按鈕。會觸發多次請求,導致重復下單。

因此,在用戶點擊過搶購按鈕后,我們可以給按鈕置灰,不讓用戶重復點擊。

const submitButton = document.getElementById('submit-order');
submitButton.disabled =?true; ?// 禁用按鈕
// 提交訂單的異步操作
submitOrder().then(response => {submitButton.disabled =?false; ?// 請求完成后恢復按鈕
}).catch(error => {submitButton.disabled =?false; ?// 請求失敗也恢復按鈕
});

如果你的系統希望設計得友好一點,可以前端提示個文案,比如:已經收到你的請求,請耐心等待搶購結果。

1.2 Token機制

  • 前端加載頁面的時候,獲取一個全局唯一標記的token,如UUID。

  • 在表單提交時,用該Token來標識該請求。每次請求都附帶該Token,后端驗證Token是否唯一。如果已提交過該Token的請求,則直接返回錯誤或無效響應,防止重復提交。

2.后端設計?

2.1 NGINX 限流

請求從前端到后端,首先是先到nginx ,我們可以在nginx做一下限流

因為有些用戶不懷好意,通過腳本繞過前端,瘋狂請求。這類用戶的IP和用戶ID,我們都可以做一下限流的限制的。

一個Nginx限流配置:

http {# 核心配置:IP+用戶ID雙因子限流 (按業務需求二選一)## 選項1:基礎版(純IP限制)limit_req_zone?$binary_remote_addr?zone=order_base:10m rate=3r/m; ?# 每IP每分鐘3次## 選項2:增強版(IP+用戶ID,需前端傳遞UserID)limit_req_zone?$binary_remote_addr$http_user_id?zone=order_enhanced:20m rate=5r/m;server {listen 80;server_name tianluoboy.com;# 訂單提交接口location = /v1/order/create {# 啟用限流(示例用增強版)limit_req zone=order_enhanced burst=3 nodelay; ?# 返回429時強制JSON響應error_page 429 @toofast;location @toofast {default_type application/json;return?200?'{"code":429,"msg":"操作過于頻繁,請稍后再試"}';}# 反向代理到業務服務器proxy_pass http://order_backend;}# 其他接口不限流location / {proxy_pass http://default_backend;}}
}

2.2 網關(Spring Cloud Gateway)

網關層可以做的事情很多,比如

Token 校驗:在網關層攔截請求,驗證 Token 是否在 Redis 中存在.

// 偽代碼示例:網關過濾器校驗 Token
if?(redis.get(token) != null) {return?error("重復請求");
}?else?{redis.setex(token, 60,?"1"); // Token 有效期 60 秒//請求到后臺passToBackend();
}

當然,網關也可以做限流的:

  • 令牌桶算法:通過Redis + Lua 實現集群級限流(如 redis-cell 模塊)。

  • 用戶維度限流:基于用戶 ID或設備指紋限制并發請求數。

網關層可以做一下請求排隊

  • 對高并發請求放到消息隊列,削峰填谷(如 Kafka/RabbitMQ)

    圖片

2.3 冪等設計

下單業務接口,我們一般要做冪等的。

一般用唯一索引做冪等設計。

唯一索引:比如使用用戶ID + 商品ID + 時間戳組合生成唯一訂單號。

一般的冪等處理就是這樣啦,如下:

圖片

2.4 分庫分表

分庫分表:按用戶 ID 分片,分散寫壓力,避免單表成為瓶頸。

當業務量暴增的話,MySQL單機磁盤容量會撐爆。并且,我們知道數據庫連接數是有限的。在高并發的場景下,大量請求訪問數據庫,MySQL單機是扛不住的!高并發場景下,會出現too many connections報錯。

所以高并發的系統,需要考慮拆分為多個數據庫,來抗住高并發的毒打。而假如你的單表數據量非常大,存儲和查詢的性能就會遇到瓶頸了,如果你做了很多優化之后還是無法提升效率的時候,就需要考慮做分表了。一般千萬級別數據量,就需要分表,每個表的數據量少一點,提升SQL查詢性能。

2.5 分布式鎖

既然是防止重復下單,一般都需要加Redis分布式鎖的。

// 偽代碼:Redisson 分布式鎖
RLock lock = redisson.getLock("order:lock:"?+ userId);
if?(lock.tryLock(0, 30, TimeUnit.SECONDS)) {try {createOrder();} finally {lock.unlock();}
}

使用Redis分布式鎖一般需要知道存在哪些坑,有需要的伙伴可以購買我的踩坑專欄哈:血與淚的教訓,盤點我工作七年所踩的坑(更新到90篇啦~)

2.6 樂觀鎖兜底

如果分布式鎖失效了呢?怎么辦呢?

我們可以加數據庫樂觀鎖兜底。比如

  • 在數據訂單表中添加 version 字段,每次更新都version+1,更新時校驗版本號

  • 通過原子操作?UPDATE ... SET version=version+1 WHERE order_id=xx AND version=old_version實現

2.7 日志與監控

要打印好日志,和做好監控指標,如果發現日志或者監控異常,可以快速介入排查~

2.8 核對數據

我們要做好核對數據,比如做個定時任務,核對訂單數據和交易金額是否對得上,如果發現數據異常,就人工快速介入排查和修復。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/84017.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/84017.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/84017.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于單片機的病房呼叫系統(源碼+仿真)

該系統由以 STM32F4 為平臺的監控終端以及以 CC2530 為平臺的無線傳感網組成。系統上電后自動完成 ZigBee 網絡的組建、終端節點的加入,病人可利用便攜式的病人終端發出呼叫求助請求信息、節點在線信息以及對護士的服務評價信息等,這些信息通過路由節點發…

使用WebSocket實時獲取印度股票數據源(無調用次數限制)實戰

使用WebSocket實時獲取印度股票數據源(無調用次數限制)實戰 一、前置準備 1. 獲取API密鑰 登錄 StockTV開發者平臺 → 聯系客服獲取測試Key(格式MY4b781f618e3f43c4b055f25fa61941ad),該密鑰無調用次數限制且支持實時…

kafka消息積壓排查

kafka監控搭建:https://insights.blog.csdn.net/article/details/139129552?spm1001.2101.3001.6650.1&utm_mediumdistribute.pc_relevant.none-task-blog-2%7Edefault%7Ebaidujs_baidulandingword%7EPaidSort-1-139129552-blog-132216491.235%5Ev43%5Econtrol…

Matlab回歸預測大合集又更新啦!新增2種高斯過程回歸預測模型,已更新41個模型!性價比拉滿!

Matlab回歸預測大合集又更新啦!新增2種高斯過程回歸預測模型,已更新41個模型!性價比拉滿! 目錄 Matlab回歸預測大合集又更新啦!新增2種高斯過程回歸預測模型,已更新41個模型!性價比拉滿&#xf…

6套bootstrap后臺管理界面源碼

后端管理系統是指一種用于管理和監控網站、應用程序或系統的后臺管理界面。它通常由一組后端代碼和數據庫組成,用于處理和存儲數據,提供給前端用戶界面展示和操作數據。 后端管理系統的功能和特點可以包括: 用戶權限管理:可以設…

JavaScript性能優化實戰:從核心原理到工程實踐的全流程解析

下面我給出一個較為系統和深入的解析,幫助你理解和實踐“JavaScript 性能優化實戰:從核心原理到工程實踐的全流程解析”。下面的內容不僅解釋了底層原理,也結合實際工程中的最佳模式和工具,幫助你在項目中貫徹性能優化理念&#x…

ELK日志管理框架介紹

在小鈴鐺的畢業設計中涉及到了ELK日志管理框架,在調研期間發現在中文中沒有很好的對ELK框架進行介紹的文章,因此擬在本文中進行較為詳細的實現的介紹。 理論知識 ELK 框架介紹 ELK 是一個流行的開源日志管理解決方案堆棧,由三個核心組件組…

2025.6.4總結

工作:今天效率比較高,早上回歸4個問題,下午找了3個bug,晚上二刷了科目一(貪吃蛇系統),寫了四個點,唯一沒達標的就是兩自動化沒完成。美中不足的是電腦上下載不了PC版的番茄工作軟件。…

【vue3學習】vue3入門

目錄 1、vue2選項式API 2、Vue3 組合式 API (1)setup 函數? 基本實現?編輯 補充方法 setup語法糖 (2)響應式數據? ref reactive: 大家好啊,我是jstart千語。好久沒更新咯,因為最近一…

【Linux基礎知識系列】第八篇-基本網絡配置

網絡配置是Linux系統維護中重要的一部分,正確配置網絡能夠確保系統與其他設備的有效連接。在本篇文章中,我們將探討Linux系統中的基本網絡配置,包括網絡接口的管理、IP地址的設置,以及使用ping和traceroute命令進行網絡診斷。通過…

React從基礎入門到高級實戰:React 高級主題 - React設計模式:提升代碼架構的藝術

React設計模式:提升代碼架構的藝術 引言 在React開發中,設計模式是構建可維護、可擴展和高性能應用的關鍵。隨著應用復雜性的增加,掌握高級設計模式不僅是技術上的挑戰,更是打造優雅架構的藝術。對于有經驗的開發者而言&#xf…

Chrome書簽的導出與導入:步驟圖

Chrome書簽的導出與導入:步驟圖 步驟一:打開 Chrome。點擊右上角的“更多”圖標。依次選擇書簽 接著 書簽管理器。 步驟二:在管理器中,點擊“整理”菜單。 步驟三:選擇導出書簽。 步驟四:Chrome 會將您的…

PPO和GRPO算法

verl 是現在非常火的 rl 框架,而且已經支持了多個 rl 算法(ppo、grpo 等等)。 過去對 rl 的理解很粗淺(只知道有好多個角色,有的更新權重,有的不更新),也曾硬著頭皮看了一些論文和知…

PyTorch——優化器(9)

優化器根據梯度調整參數,以達到降低誤差 import torch.optim import torchvision from torch import nn from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear from torch.utils.data import DataLoader# 加載CIFAR10測試數據集,設置tr…

c++學習-this指針

1.基本概念 非靜態成員函數都會默認傳遞this指針(靜態成員函數屬于類本身,不屬于某個實例對象),方便訪問對象對類成員變量和 成員函數。 2.基本使用 編譯器實際處理類成員函數,this是第一個隱藏的參數,類…

【Oracle】數據倉庫

個人主頁:Guiat 歸屬專欄:Oracle 文章目錄 1. 數據倉庫概述1.1 為什么需要數據倉庫1.2 Oracle數據倉庫架構1.3 Oracle數據倉庫關鍵技術 2. 數據倉庫建模2.1 維度建模基礎2.2 星形模式設計2.3 雪花模式設計2.4 緩慢變化維度(SCD)處…

css-塞貝爾曲線

文章目錄 1、定義2、使用和解釋 1、定義 cubic-bezier() 函數定義了一個貝塞爾曲線(Cubic Bezier)語法:cubic-bezier(x1,y1,x2,y2) 2、使用和解釋 x1,y1,x2,y2,表示兩個點的坐標P1(x1,y1),P2(x2,y2)將以一條直線放在范圍只有 1 的坐標軸中,并…

函數式接口實現分頁查詢

你提供的 PageResult 類是一個非常完整、功能齊全的分頁結果封裝類,它包含了: 當前頁數據(list)總記錄數(totalCount)總頁數(totalPage)當前頁碼(pageNo)每頁…

Global Security Markets 第 10 章衍生品知識點總結?

一、衍生品的定義與本質 衍生品,作為一種金融工具,其價值并非獨立存在,而是緊密依賴于其他資產,如常見的股票、債券、商品,或者市場變量,像利率、匯率、股票指數等。這意味著衍生品的價格波動,…

DJango知識-模型類

一.項目創建 在想要將項目創鍵的目錄下,輸入cmd (進入命令提示符)在cmd中輸入:Django-admin startproject 項目名稱 (創建項目)cd 項目名稱 (進入項目)Django-admin startapp 程序名稱 (創建程序)python manage.py runserver 8080 (運行程序)將彈出的網址復制到瀏覽器中…