Simplified Seckill Project: Architecture, Core Implementations, and Code Overview
This article introduces a simplified Seckill (flash‑sale) system built with SpringBoot, detailing its overall architecture, key backend techniques such as distributed sessions, Redis caching, RabbitMQ asynchronous ordering, security measures, oversell prevention, rate limiting, and provides essential code snippets and deployment screenshots.
The project is a reference‑based implementation of a Seckill system using the SpringBoot framework, offering functionalities like login, product list, product details, flash‑sale ordering, and order details. It incorporates asynchronous ordering, hotspot data caching, and anti‑oversell techniques.
Development Technologies
Backend: SpringBoot, MyBatis, MySQL, RabbitMQ, Redis
Frontend: HTML, jQuery, Thymeleaf
Implementation Details
1. Double MD5 Password Encryption
First MD5 protects the password during transmission; the second MD5 protects stored passwords against database theft.
2. Distributed Session Management
After successful authentication, a UUID token is generated, stored in Redis as token → userObject , and also placed in a cookie to maintain session state across requests.
3. Unified Exception Handling
Custom interceptors combined with @ControllerAdvice and @ExceptionHandler capture all exceptions and return standardized error responses.
4. Page and Object Caching
Rendered HTML pages are cached in Redis for fast retrieval, while hot objects such as users, products, and orders are also cached to reduce database load.
5. Page Staticization
AJAX is used for asynchronous data fetching; the first request caches both page and data in the browser, enabling subsequent loads from the client cache.
6. Memory Flag + Redis Pre‑decrement + RabbitMQ Asynchronous Processing
A local in‑memory map tracks product stock status, Redis pre‑decrements stock to avoid DB hits, and RabbitMQ queues orders for asynchronous processing, dramatically increasing throughput.
private Map
localOverMap = new HashMap<>();
boolean over = localOverMap.get(goodsId);
if (over) {
return Result.error(CodeMsg.MIAO_SHA_OVER);
}
long stock = redisService.decr(GoodsKey.getSeckillGoodsStock, "" + goodsId);
if (stock < 0) {
localOverMap.put(goodsId, true);
return Result.error(CodeMsg.MIAO_SHA_OVER);
}
SeckillOrder order = orderService.getOrderByUserIdGoodsId(user.getId(), goodsId);
if (order != null) {
return Result.error(CodeMsg.REPEATE_MIAOSHA);
}
SeckillMessage sm = new SeckillMessage();
sm.setUser(user);
sm.setGoodsId(goodsId);
sender.sendSeckillMessage(sm);7. Solving Oversell
Only update stock when it is greater than zero, enforce a unique index on (user_id, goods_id) , and apply optimistic locking with a version field.
update seckill_goods set stock_count = stock_count-1
where goods_id = #{goodsId} and stock_count > 08. Interface Rate Limiting
A custom @AccessLimit annotation limits the number of requests per user within a time window.
/**
* Get seckill path
* Custom rate limit: max 5 requests per 5 seconds, login required
*/
@AccessLimit(seconds=5, maxCount=5, needLogin=true)
@RequestMapping(value="/path", method=RequestMethod.GET)
@ResponseBody
public Result
getSeckillPath(User user, @RequestParam("goodsId") long goodsId) {
if (user == null) {
return Result.error(CodeMsg.USER_NO_LOGIN);
}
String path = seckillService.createPath(user, goodsId);
return Result.success(path);
}Demo Screenshots
Images illustrate the project structure, login page, product list, product details, and order confirmation after a successful flash sale.
Source Code
The complete source code is available at https://gitee.com/jike11231/sec-kill-product .
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
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.