IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 秒杀的设计与实践 -> 正文阅读

[大数据]秒杀的设计与实践

秒杀在电商中是一个很常见的场景。所谓“秒杀”,就是网络卖家发布一些超低价格的商品,所有买家在同一时间网上抢购的一种销售方式
从技术角度出发,秒杀是指在短时间内,大量用户并发请求去争夺有限数量的产品。

一.考虑的问题

对于秒杀,设计时要考虑哪些问题呢?

1. 超卖

何谓超卖?即指卖出的商品超出了设定的库存。秒杀场景下,商品的价格一般是特别低的,本身就是亏本,吸引客户。一旦出现超卖,会造成大量经济损失。所以超卖可谓第一个要注意点。

2.高并发

秒杀都是数秒内出现大量请求,如果这些请求都到数据库,很容易造成奔溃。故而如何设计避免出现这种状态很重要。

3.接口防刷

接口防刷主要指有大量恶意请求秒杀接口,导致服务器反应不过来。这里包括脚本去抢秒杀商品或者进行本身恶意的攻击。

4. 数据库设计

数据库设计指发生秒杀业务时,影响到了其他正常的数据库业务。

二.秒杀设计

对于秒杀请求,类似于漏斗处理,层层过滤,最终实现少量数据入库的过程。
在这里插入图片描述

1. 首先是分流

在现实中,硬件设备是有限的,单个服务器所能处理的请求也是有限的,故而分流是首先要做的。这里的分流采用冷热分离的思想,主要包括如下几点:

  1. 页面数据缓存:
  • 参与秒杀商品信息是固定的,可以预加载数据到缓存中
  • 对于静态的页面资源例如html,图片等可通过CDN进行加速
    这部分操作主要是为了是加快’冷’数据的响应,减少客户等待时间
  1. 动态化秒杀地址
    这部分操作是为了避免提前暴露秒杀地址。如果是一个固定的地址,只要稍微懂些技术的人员就可以找到地址,提前进行发起请求。当然在点击秒杀按钮之后,要对按钮进行置灰操作,避免客户频繁点击,这个很简单但很实用。

示例代码如下:

  public String getSkillUrl(Long activityId) {
       ValueOperations ops = redisTemplate.opsForValue();
       String raw = (String) ops.get(String.format(ACTIVITY_KEY, activityId));
       if (!StringUtils.hasText(raw)) {
           return "";
       }
       ActivityDO activityDO = JSON.parseObject(raw, ActivityDO.class);
       LocalDateTime now = LocalDateTime.now();
       // 做些校验,这里简单做个时间校验
       if (now.isBefore(activityDO.getStartTime()) || now.isAfter(activityDO.getEndTime())) {
           log.info("活动还未开始");
           return "";
       }
       // 获取加密秘钥
       String url = SecretUtil.md5Encode(String.valueOf(activityDO.getGoodsId()), SKILL_SALT);
       ops.set(String.format(STOCK_URL_KEY,url),"1",60, TimeUnit.SECONDS);
       return url;
   }

虽然动态秒杀地址避免了直接泄露,但是这个还是无法避免脚本的攻击
3. nginx进行分流
这层不仅仅进行请求的分流,也可以对一些ip进行限制,一定程度减少攻击。
4. 服务单一化
单独分离处秒杀服务进行部署,避免因为秒杀导致其他服务访问出现问题。

2. 接着是限流

限流操作时为了保证流量始终在服务器能接受的合理范围,超出可以执行一些熔断,风控策略。当然这一层是处理接口防刷最关键的地方。

  1. 网关
    网关这层既可以做到流量的分发,限制,还可以进行服务降级保护的操作。
  2. 限流中间件
    限流中间件分布式场景下,Sentinel还是很好用的,基本能满足常见场景。对于单机场景可以使用Guava工具包RateLimiter工具类。

3. 然后是秒杀校验

一般到这一步,并发数已处于一个合理的范围了主要做一些基础校验,然后把秒杀到的信息发给MQ。这里处理缓存库存时,要获取全局锁,这一步主要是防止超卖。
大致需要的校验如下:

  • 校验动态地址获取的凭证
  • 活动时间是否结束
  • 库存数是否足够
  • 其他额外的业务校验

示例代码如下:

    public Boolean skill(String url,Long goodsId) {
       // 校验动态地址
       if (!redisTemplate.hasKey(String.format(STOCK_URL_KEY, url))) {
           return Boolean.FALSE;
       }

       // 获取全局锁
       RLock lock = redissonClient.getLock(String.format("skill:lock:%d", goodsId));
       // 执行其他基础校验,例如身份等
       ValueOperations ops = redisTemplate.opsForValue();
       String key = String.format(STOCK_KEY, goodsId);
       if (!lock.tryLock()) {
           return Boolean.FALSE;
       }
       try {
           // 校验库存,扣减库存
           Integer num = (Integer) ops.get(key);
           if (num <= 0) {
               return false;
           }
           ops.decrement(key);
       }finally {
           lock.unlock();
       }
       // 这里随机生成用户id,正常为获取登录的用户
       Long userId = (long) new Random().nextInt(1000);
       // 发送消息队列,生成预订单,扣减库存等操作
       messageService.sendSkillInfo(new MsgDTO(goodsId,userId));
       return Boolean.TRUE;
   }

4. 最后是MQ以及数据落库

  • MQ方面
    要注意消息的持久化避免消息丢失,另外要考虑消费者的处理能力,避免消息积压过多。通常MQ都采用的推模式,有消息就会推给消费者,如果消息过多,消费者的压力会很大,那时可以考虑采用拉模式,定量获取MQ的数据。采用拉模式就得靠考虑时效问题了,每次拉多少,隔多久拉一次。
  • 消费者
    到这里具体处理消息,生成预订单,扣减库存。这里要考虑超时之后库存的恢复。

三.总结

本文主要对秒杀进行回顾,设计核心还是超卖和高并发,动静分离处理是关键思想。
后续有新思路继续补充。示例demo地址

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-09-12 13:14:07  更:2021-09-12 13:16:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:39:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码