当前位置:网站首页>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 )
边栏推荐
- Finally understand what dynamic planning is
- The method and principle of viewing the last modification time of the web page
- Global and Chinese markets for children's amusement facilities 2022-2028: Research Report on technology, participants, trends, market size and share
- Calculating the number of daffodils in C language
- Arduino 测量交流电流
- Multi sensor fusion of imu/ electronic compass / wheel encoder (Kalman filter)
- Global and Chinese market of water treatment technology 2022-2028: Research Report on technology, participants, trends, market size and share
- Overview of Fourier analysis
- Sum of two numbers, sum of three numbers (sort + double pointer)
- [screen recording] how to record in the OBS area
猜你喜欢

PLC编程基础之数据类型、变量声明、全局变量和I/O映射(CODESYS篇 )

Getting started stm32--gpio (running lantern) (nanny level)
![[screen recording] how to record in the OBS area](/img/34/bd06bd74edcdabaf678c8d7385cae9.jpg)
[screen recording] how to record in the OBS area

LeetCode102. Sequence traversal of binary tree (output by layer and unified output)

Using LNMP to build WordPress sites

基于脉冲神经网络的物体检测

【Note17】PECI(Platform Environment Control Interface)

One article deals with the microstructure and instructions of class

TypeError: this. getOptions is not a function

Go语言实现原理——Map实现原理
随机推荐
并查集实践
派对的最大快乐值
Data type, variable declaration, global variable and i/o mapping of PLC programming basis (CoDeSys)
Shell: operator
Nacos 的安装与服务的注册
Hcip day 11 (BGP agreement)
Methods modified by static
Selenium+pytest automated test framework practice
Common JVM tools and optimization strategies
Three.js-01 入门
LeetCode102. Sequence traversal of binary tree (output by layer and unified output)
【原创】程序员团队管理的核心是什么?
Common model making instructions
Practice of concurrent search
Southeast Asia e-commerce guide, how do sellers layout the Southeast Asia market?
(4)UART应用设计及仿真验证2 —— TX模块设计(无状态机)
14种神笔记方法,只需选择1招,让你的学习和工作效率提高100倍!
Idea rundashboard window configuration
【Note17】PECI(Platform Environment Control Interface)
Arduino measures AC current