当前位置:网站首页>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 )
边栏推荐
- openresty ngx_lua请求响应
- 一文搞定class的微觀結構和指令
- From the perspective of quantitative genetics, why do you get the bride price when you get married
- Realize reverse proxy client IP transparent transmission
- ORB_ SLAM2/3
- LeetCode145. Post order traversal of binary tree (three methods of recursion and iteration)
- Starting from 1.5, build a micro Service Framework -- log tracking traceid
- [screen recording] how to record in the OBS area
- Leetcode buys and sells stocks
- Thoroughly understand JVM class loading subsystem
猜你喜欢
February 13, 2022-4-symmetric binary tree
Masked Autoencoders Are Scalable Vision Learners (MAE)
Spectrum analysis of ADC sampling sequence based on stm32
实现反向代理客户端IP透传
Initial experience | purchase and activate typora software
两数之和、三数之和(排序+双指针)
如何快速理解复杂业务,系统思考问题?
Three.JS VR看房
Three. Js-01 getting started
Three.js-01 入门
随机推荐
Masked Autoencoders Are Scalable Vision Learners (MAE)
Debian 10 installation configuration
Judge whether the binary tree is a complete binary tree
Week 17 homework
透彻理解JVM类加载子系统
一文搞定垃圾回收器
Use the rewrite rule to rewrite all accesses to the a domain name to the B domain name
Déterminer si un arbre binaire est un arbre binaire complet
Idea rundashboard window configuration
利用LNMP实现wordpress站点搭建
openresty ngx_lua请求响应
LabVIEW打开PNG 图像正常而 Photoshop打开得到全黑的图像
[speech processing] speech signal denoising and denoising based on Matlab GUI low-pass filter [including Matlab source code 1708]
Global and Chinese markets for children's amusement facilities 2022-2028: Research Report on technology, participants, trends, market size and share
Use of metadata in golang grpc
Three.JS VR看房
第十七周作业
Arduino 测量交流电流
Openresty ngx Lua regular expression
SPSS analysis of employment problems of college graduates