当前位置:网站首页>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 )
边栏推荐
- 【Note17】PECI(Platform Environment Control Interface)
- Paddy serving v0.9.0 heavy release multi machine multi card distributed reasoning framework
- 派对的最大快乐值
- Overview of Fourier analysis
- Basic knowledge of database (interview)
- Global and Chinese markets of tantalum heat exchangers 2022-2028: Research Report on technology, participants, trends, market size and share
- Non rigid / flexible point cloud ICP registration
- Leetcode weekly The 280 game of the week is still difficult for the special game of the week's beauty team ~ simple simulation + hash parity count + sorting simulation traversal
- Use the rewrite rule to rewrite all accesses to the a domain name to the B domain name
- Judge whether the binary tree is a complete binary tree
猜你喜欢
Three. JS VR house viewing
[digital signal denoising] improved wavelet modulus maxima digital signal denoising based on MATLAB [including Matlab source code 1710]
Using LNMP to build WordPress sites
Un article traite de la microstructure et des instructions de la classe
One article deals with the microstructure and instructions of class
实现反向代理客户端IP透传
Tensor attribute statistics
Simple and beautiful method of PPT color matching
Debian 10 installation configuration
Paddy serving v0.9.0 heavy release multi machine multi card distributed reasoning framework
随机推荐
[screen recording] how to record in the OBS area
Methods modified by static
Paddy serving v0.9.0 heavy release multi machine multi card distributed reasoning framework
Multi sensor fusion of imu/ optical mouse / wheel encoder (nonlinear Kalman filter)
Spectrum analysis of ADC sampling sequence based on stm32
Initial experience | purchase and activate typora software
Overview of Fourier analysis
Global and Chinese markets of tantalum heat exchangers 2022-2028: Research Report on technology, participants, trends, market size and share
Hj16 shopping list
第十七周作业
Use the rewrite rule to rewrite all accesses to the a domain name to the B domain name
Common model making instructions
Selenium+Pytest自动化测试框架实战
两数之和、三数之和(排序+双指针)
Global and Chinese market of water treatment technology 2022-2028: Research Report on technology, participants, trends, market size and share
Global and Chinese market of diesel fire pump 2022-2028: Research Report on technology, participants, trends, market size and share
Leetcode weekly The 280 game of the week is still difficult for the special game of the week's beauty team ~ simple simulation + hash parity count + sorting simulation traversal
regular expression
Roman numeral to integer
3:第一章:认识JVM规范2:JVM规范,简介;