当前位置:网站首页>Design and implementation of secsha system
Design and implementation of secsha system
2022-07-05 23:12:00 【Bald and weak.】
List of articles
Write it at the front
Second kill is no stranger to everyone , And it is a necessary skill point for e-commerce projects .
But the real secsha service is very complicated , Second kill has the characteristics of instant high concurrency , So solve the problem of instant high concurrency , Can solve the problem of second kill .
Today, we will decompose the complete implementation of secsha system , Let's study it together .
( Please correct any questions )
Precautions for seckill system
Single responsibility for service + Independent deployment
There are great risks in seckill service , Carelessness will cause service downtime or occupy a lot of server resources in an instant , therefore Seckill service must be deployed independently , And seckill service only does seckill function .
Seckill link encryption
Prevent malicious attacks , Prevent someone from simulating the seckill request, causing greater pressure on the server ;
Prevent link exposure , Prevent staff from killing goods in advance .
Stock preheating + Quick deduction
Second kill system reads more and writes less , We can preheat the total inventory first , Deposit in redis in , Use semaphores to control the number of seckill requests .
Dynamic and static separation
Use nginx Do a good job of separating the static from the dynamic , Ensure that static resources can directly request , Avoid consuming backend resources .( Now they are basically front and back-end separation projects , It's negligible here )
Malicious request interception
Identify the request of illegal attack and intercept , It can be intercepted from the gateway layer , Determine whether the user is logged in .
Flow peak shifting
By all means , Sharing traffic to a wider range of time points . For example, verification code 、 Add to cart , Add a few more steps .
Current limiting & Fuse & Downgrade
Front end current limiting + Back end current limiting .
Limit one click per second ; Limit the total amount ;
Back end fast failure 、 Degraded operation 、 Circuit breaker mechanism prevents avalanche .
Queue clipping
Second kill all successful products , Put it in the message queue , Then the consumer slowly creates orders and other logic .
Concrete realization
Current limiting fuse
Use sentinel Carry out current limiting
Detailed explanation sentinel: Traffic guard of distributed system
Queue clipping
Use rockerMQ perhaps rabbitMQ Peak clipping .
Stock preheating
Using scheduled tasks , Send the product information in advance 、 Commodity random code ( Prevent malicious attacks )、 Information such as commodity inventory is stored redis.
Pseudo code :
/** * Cache the product information associated with the second kill activity */
private void saveProductInfo(List<Product> products) {
products.stream().forEach(products-> {
// Get ready hash operation , binding hash
BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(SECKILL_CHARE_PREFIX);
products.getRelationSkus().stream().forEach(seckillSkuVo -> {
// Generate random code
String token = UUID.randomUUID().toString().replace("-", "");
String redisKey = seckillSkuVo.getPromotionSessionId().toString() + "-" + seckillSkuVo.getSkuId().toString();
if (!operations.hasKey(redisKey)) {
// Prevent duplicate addition
// Cache our product information
SeckillSkuRedisTo redisTo = new SeckillSkuRedisTo();
Long skuId = seckillSkuVo.getSkuId();
//1、 First, check the basic information of the goods , Call remote service
R info = productFeignService.getSkuInfo(skuId);
if (info.getCode() == 0) {
SkuInfoVo skuInfo = info.getData("skuInfo",new TypeReference<SkuInfoVo>(){
});
redisTo.setSkuInfo(skuInfo);
}
//2、sku Second kill information
BeanUtils.copyProperties(seckillSkuVo,redisTo);
//3、 Set the second kill time information of the current product
redisTo.setStartTime(session.getStartTime().getTime());
redisTo.setEndTime(session.getEndTime().getTime());
//4、 Set random code of goods ( Prevent malicious attacks )
redisTo.setRandomCode(token);
// serialize json Format deposit Redis in
String seckillValue = JSON.toJSONString(redisTo);
operations.put(seckillSkuVo.getPromotionSessionId().toString() + "-" + seckillSkuVo.getSkuId().toString(),seckillValue);
// If the commodity inventory information of the current session has been put on the shelf, it does not need to be put on the shelf
//5、 Use inventory as distributed Redisson Semaphore ( Current limiting )
// Use inventory as a distributed semaphore
RSemaphore semaphore = redissonClient.getSemaphore(SKU_STOCK_SEMAPHORE + token);
// The number of goods can be killed in seconds as a semaphore
semaphore.trySetPermits(seckillSkuVo.getSeckillCount());
}
});
});
}
Second kill
/** * Second kill of goods ( The second kill begins ) * @param killId * @param key * @param num * @return */
@GetMapping(value = "/kill")
public String seckill(@RequestParam("killId") String killId,
@RequestParam("key") String key,
@RequestParam("num") Integer num,
Model model) {
String orderSn = null;
try {
//1、 Determine whether to log in
orderSn = seckillService.kill(killId,key,num);
model.addAttribute("orderSn",orderSn);
} catch (Exception e) {
e.printStackTrace();
}
return "success";
}
/** * Second kill the current product ( The second kill begins ) * @param killId * @param key * @param num * @return */
@Override
public String kill(String killId, String key, Integer num) throws InterruptedException {
long s1 = System.currentTimeMillis();
// Get current user information
MemberResponseVo user = LoginUserInterceptor.loginUser.get();
//1、 Get the details of the current second kill product from Redis In order to get
BoundHashOperations<String, String, String> hashOps = redisTemplate.boundHashOps(SECKILL_CHARE_PREFIX);
String skuInfoValue = hashOps.get(killId);
if (StringUtils.isEmpty(skuInfoValue)) {
return null;
}
//( Validity test )
SeckillSkuRedisTo redisTo = JSON.parseObject(skuInfoValue, SeckillSkuRedisTo.class);
Long startTime = redisTo.getStartTime();
Long endTime = redisTo.getEndTime();
long currentTime = System.currentTimeMillis();
// Judge whether the current second kill request is within the active time interval ( Validity of time )
if (currentTime >= startTime && currentTime <= endTime) {
//2、 Verify random codes and Commodities id
String randomCode = redisTo.getRandomCode();
String skuId = redisTo.getPromotionSessionId() + "-" +redisTo.getSkuId();
if (randomCode.equals(key) && killId.equals(skuId)) {
//3、 Verify whether the shopping quantity is reasonable and whether the inventory is sufficient
Integer seckillLimit = redisTo.getSeckillLimit();
// Acquisition semaphore
String seckillCount = redisTemplate.opsForValue().get(SKU_STOCK_SEMAPHORE + randomCode);
Integer count = Integer.valueOf(seckillCount);
// Judge whether the semaphore is greater than 0, And you can't buy more than you have in stock
if (count > 0 && num <= seckillLimit && count > num ) {
//4、 Verify that this person has bought ( Idempotent treatment ), If the second kill succeeds , Just take a seat .userId-sessionId-skuId
//SETNX Atomic treatment
String redisKey = user.getId() + "-" + skuId;
// Set auto expiration ( End time - current time )
Long ttl = endTime - currentTime;
Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(redisKey, num.toString(), ttl, TimeUnit.MILLISECONDS);
if (aBoolean) {
// A successful space occupation means that you have never bought , Distributed lock ( Acquisition semaphore -1)
RSemaphore semaphore = redissonClient.getSemaphore(SKU_STOCK_SEMAPHORE + randomCode);
//TODO Seckill success , Order quickly
boolean semaphoreCount = semaphore.tryAcquire(num, 100, TimeUnit.MILLISECONDS);
// Guarantee Redis There is also a stock of goods
if (semaphoreCount) {
// Create an order number and send the order information to MQ
// Seckill success Order quickly Send a message to MQ The whole operation time is 10ms about
String timeId = IdWorker.getTimeId();
SeckillOrderTo orderTo = new SeckillOrderTo();
orderTo.setOrderSn(timeId);
orderTo.setMemberId(user.getId());
orderTo.setNum(num);
orderTo.setPromotionSessionId(redisTo.getPromotionSessionId());
orderTo.setSkuId(redisTo.getSkuId());
orderTo.setSeckillPrice(redisTo.getSeckillPrice());
rabbitTemplate.convertAndSend("order-event-exchange","order.seckill.order",orderTo);
long s2 = System.currentTimeMillis();
log.info(" Time consuming ..." + (s2 - s1));
return timeId;
}
}
}
}
}
long s3 = System.currentTimeMillis();
log.info(" Time consuming ..." + (s3 - s1));
return null;
}
redisson Semaphore
redisson Use the total solution ——redisson Official documents + notes ( medium-length )
边栏推荐
- Realize reverse proxy client IP transparent transmission
- Codeforces Global Round 19
- 两数之和、三数之和(排序+双指针)
- 14种神笔记方法,只需选择1招,让你的学习和工作效率提高100倍!
- Finally understand what dynamic planning is
- Nacos 的安装与服务的注册
- CJ mccullem autograph: to dear Portland
- fibonacci search
- LabVIEW打开PNG 图像正常而 Photoshop打开得到全黑的图像
- TypeError: this. getOptions is not a function
猜你喜欢

February 13, 2022-4-symmetric binary tree

Element operation and element waiting in Web Automation

一文搞定class的微观结构和指令

VOT Toolkit环境配置与使用

Alibaba Tianchi SQL training camp task4 learning notes

Error when LabVIEW opens Ni instance finder

2022 G3 boiler water treatment simulation examination and G3 boiler water treatment simulation examination question bank

Negative sampling

一文搞定垃圾回收器

东南亚电商指南,卖家如何布局东南亚市场?
随机推荐
Codeforces Global Round 19
Leetcode daily question 1189 The maximum number of "balloons" simple simulation questions~
Krypton Factor-紫书第七章暴力求解
利用LNMP实现wordpress站点搭建
Summary of binary tree recursive routines
Composition of interface
Expectation, variance and covariance
The difference between MVVM and MVC
VOT toolkit environment configuration and use
Data type, variable declaration, global variable and i/o mapping of PLC programming basis (CoDeSys)
14种神笔记方法,只需选择1招,让你的学习和工作效率提高100倍!
二叉树递归套路总结
[speech processing] speech signal denoising and denoising based on MATLAB low-pass filter [including Matlab source code 1709]
Nacos installation and service registration
Arduino 测量交流电流
Global and Chinese markets of industrial pH meters 2022-2028: Research Report on technology, participants, trends, market size and share
并查集实践
Global and Chinese markets for reciprocating seal compressors 2022-2028: Research Report on technology, participants, trends, market size and share
Hj16 shopping list
CorelDRAW plug-in -- GMS plug-in development -- new project -- macro recording -- VBA editing -- debugging skills -- CDR plug-in (2)