Simplified Seckill Project System Overview and Implementation Details
This article presents a concise tutorial on building a flash‑sale (Seckill) system with SpringBoot, MySQL, Redis, RabbitMQ and a basic HTML/JQuery front‑end, covering architecture, key features, code snippets, over‑selling prevention, rate limiting, and deployment screenshots.
This article introduces a simplified Seckill (flash‑sale) project developed with SpringBoot, MyBatis, MySQL, RabbitMQ, Redis, and a lightweight front‑end using HTML, JQuery and Thymeleaf, outlining its overall architecture and core functionalities such as login, product listing, product details, seckill processing, and order details.
The system employs distributed session management via UUID tokens stored in Redis and cookies, Redis pre‑decrement of stock to reduce database pressure, asynchronous order placement through RabbitMQ, client‑side polling for results, and interface rate limiting to prevent abuse.
Implementation details include double MD5 password hashing for transmission and storage security, unified exception handling using @ControllerAdvice and @ExceptionHandler, page and object caching in Redis, page staticization with AJAX, and a memory‑flag combined with Redis pre‑decrement and RabbitMQ async processing; the relevant code is shown below:
private Map<Long,Boolean> 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);To solve over‑selling, the article describes three strategies: (1) an SQL update that only decrements stock when it is greater than zero, (2) a unique index on user‑id and product‑id to prevent duplicate purchases, and (3) optimistic locking with a version field, illustrated by:
update seckill_goods set stock_count = stock_count-1 where goods_id = #{goodsId} and stock_count > 0Interface rate limiting is implemented via a custom @AccessLimit annotation applied to controller methods; an example definition is provided:
@AccessLimit(seconds=5, maxCount=5, needLogin=true)
@RequestMapping(value="/path", method=RequestMethod.GET)
@ResponseBody
public Result<String> 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);
}The article concludes with screenshots of the project’s code structure, login page, product list, product details, order result, and provides a link to the source repository (https://gitee.com/jike11231/sec-kill-product) for readers to explore further.
Finally, the author encourages readers to share the article, join the architecture community, and engage in further learning.
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.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
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.
