Design and Technical Solutions for a High-Concurrency Flash Sale System
This article examines the challenges of building a flash‑sale (秒杀) system—such as overselling, high concurrency, request flooding, URL security, and database strain—and presents a comprehensive backend design using separate databases, Redis clustering, dynamic URLs, static pages, Nginx, rate‑limiting, asynchronous order processing, and service degradation strategies.
Flash‑sale (秒杀) systems like those on JD.com or Taobao attract massive traffic in a very short time, creating problems such as overselling, high concurrency, request flooding, URL exposure, and database overload.
Problems to consider
Overselling: limited stock must not be sold beyond availability.
High concurrency: millions of requests within minutes.
Interface abuse: bots generate hundreds of requests per second.
Dynamic URL protection: prevent users from guessing the sale URL.
Database isolation: avoid contaminating other services.
Massive request handling: cache and DB must sustain extreme QPS.
Design and technical solutions
2.1 Database design – Use a dedicated flash‑sale database with two core tables (order and product) and auxiliary tables for goods and users.
Additional tables may store product details and user information.
2.2 Dynamic URL – Generate the sale URL by MD5‑hashing a random string; the front‑end fetches the URL from the back‑end after validation.
2.3 Page staticization – Render product details into a static HTML page (e.g., using FreeMarker) so that user requests bypass the application server and database.
2.4 Redis cluster – Deploy Redis in a Sentinel‑based cluster to avoid cache breakdown and improve availability.
2.5 Nginx – Use Nginx as a reverse proxy to distribute traffic to a Tomcat cluster, leveraging its high concurrent connection capacity.
2.6 SQL simplification – Reduce inventory deduction to a single statement with optimistic locking:
update miaosha_goods set stock = stock-1 where goos_id = #{goods_id} and version = #{version} and stock > 0;2.7 Redis pre‑decrement – Pre‑set stock in Redis (e.g., redis.set(goodsId, 100)) and atomically decrement on each order, using Lua scripts to ensure consistency.
2.8 Interface rate limiting
Frontend limit: disable the purchase button for a few seconds after click.
Repeat request block: reject the same user’s request within a configurable interval (e.g., 10 s) using Redis key expiration.
Token‑bucket algorithm: employ Guava’s RateLimiter to allow only a certain number of tokens per second.
2.9 Asynchronous order processing – After passing rate limiting and stock check, push the order request to a message queue (e.g., RabbitMQ) for asynchronous handling, achieving peak‑shaving, decoupling, and reliability.
2.10 Service degradation – Use circuit‑breaker tools such as Hystrix to provide fallback responses when a node fails, ensuring a graceful user experience.
Conclusion
The following flowchart illustrates the end‑to‑end flash‑sale process capable of handling hundreds of thousands of concurrent requests. For larger scales (tens of millions), further techniques like database sharding, Kafka queues, and larger Redis clusters would be required.
By thoughtfully addressing each of these challenges, developers can build robust flash‑sale systems that maintain performance and data integrity under extreme load.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Laravel Tech Community
Specializing in Laravel development, we continuously publish fresh content and grow alongside the elegant, stable Laravel framework.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
