SpringBoot开发案例从0到1构建分布式秒杀系统
前言
最近,被推送了不少秒杀架构的文章,忙里偷闲自己也总结了一下互联网平台秒杀架构设计,当然也借鉴了不少同学的思路。俗话说,脱离案例讲架构都是耍流氓,最终使用SpringBoot模拟实现了部分秒杀场景,同时跟大家分享交流一下。
秒杀场景
秒杀场景无非就是多个用户在同时抢购一件或者多件商品,专用词汇就是所谓的高并发。现实中经常被大家喜闻乐见的场景,一群大妈抢购打折鸡蛋的画面一定不会陌生,如此场面让服务员大姐很无奈,赶上不要钱了。
业务特点
- 瞬间高并发、电脑旁边的小哥哥、小姐姐们如超市哄抢的大妈一般,疯狂的点着鼠标
- 库存少、便宜、稀缺限量,值得大家去抢购,如苹果肾,小米粉,锤子粉(理解万岁)
用户规模
用户规模可大可小,几百或者上千人的活动单体架构足以可以应付,简单的加锁、进程内队列就可以轻松搞定。一旦上升到百万、千万级别的规模就要考虑分布式集群来应对瞬时高并发。
秒杀架构
架构层级
- 一般商家在做活动的时候,经常会遇到各种不怀好意的DDOS攻击(利用无辜的吃瓜群众夺取资源),导致真正的我们无法获得服务!所以说高防IP还是很有必要的。
- 搞活动就意味着人多,接入SLB,对多台云服务器进行流量分发,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。
- 基于SLB价格以及灵活性考虑后面我们接入Nginx做限流分发,来保障后端服务的正常运行。
- 后端秒杀业务逻辑,基于Redis 或者 Zookeeper 分布式锁,Kafka 或者 Redis 做消息队列,DRDS数据库中间件实现数据的读写分离。
优化思路
- 分流、分流、分流,重要的事情说三遍,再牛逼的机器也抵挡不住高级别的并发。
- 限流、限流、限流,毕竟秒杀商品有限,防刷的前提下没有绝对的公平,根据每个服务的负载能力,设定流量极限。
- 缓存、缓存、缓存、尽量不要让大量请求穿透到DB层,活动开始前商品信息可以推送至分布式缓存。
- 异步、异步、异步,分析并识别出可以异步处理的逻辑,比如日志,缩短系统响应时间。
- 主备、主备、主备,如果有条件做好主备容灾方案也是非常有必要的(参考某年锤子的活动被攻击)。
- 最后,为了支撑更高的并发,追求更好的性能,可以对服务器的部署模型进行优化,部分请求走正常的秒杀流程,部分请求直接返回秒杀失败,缺点是开发部署时需要维护两套逻辑。
分层优化
- 前端优化:活动开始前生成静态商品页面推送缓存和CDN,静态文件(JS/CSS)请求推送至文件服务器和CDN。
- 网络优化:如果是全国用户,最好是BGP多线机房,减少网络延迟。
- 应用服务优化:Nginx最佳配置、Tomcat连接池优化、数据库配置优化、数据库连接池优化。
全链路压测
- 分析需压测业务场景涉及系统
- 协调各个压测系统资源并搭建压测环境
- 压测数据隔离以及监控(响应时间、吞吐量、错误率等数据以图表形式实时显示)
- 压测结果统计(平均响应时间、平均吞吐量等数据以图表形式在测试结束后显示)
- 优化单个系统性能、关联流程以及整个业务流程
整个压测优化过程就是一个不断优化不断改进的过程,事先通过测试不断发现问题,优化系统,避免问题,指定应急方案,才能让系统的稳定性和性能都得到质的提升。
代码案例
可能秒杀架构原理大家都懂,网上也有不少实现方式,但大多都是文字的描述,告诉你如何如何,什么加锁、缓存、队列之类。但很少全面有的案例告诉你如何去做,既然是从0到1,希望以下代码案例可以帮助到你。当然最终落实到生产,还有很长的路要走,要根据自己的业务进行编码,实施并部署。
你将会在代码案例中学到以下知识(不定期补充):
- 如何大家SpringBoot微服务
- ThreadPoolExecutor线程池的使用
- ReentrantLock和Synchronized的使用场景
- 数据库锁机制(悲观锁、乐观锁)
- 分布式锁(RedissLock、Zookeeper)
- 进程内消息队列(LinkedBlockingQueue、ArrayBlockingQueue、ConcurrentLinkedQueue)
- 分布式消息队列(Redis、Kafka)
代码结构:
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─itstyle
│ │ │ └─seckill
│ │ │ │ Application.java
│ │ │ │
│ │ │ ├─common
│ │ │ │ ├─api
│ │ │ │ │ SwaggerConfig.java
│ │ │ │ │
│ │ │ │ ├─config
│ │ │ │ │ IndexController.java
│ │ │ │ │
│ │ │ │ ├─dynamicquery
│ │ │ │ │ DynamicQuery.java
│ │ │ │ │ DynamicQueryImpl.java
│ │ │ │ │ NativeQueryResultEntity.java
│ │ │ │ │
│ │ │ │ ├─entity
│ │ │ │ │ Result.java
│ │ │ │ │ Seckill.java
│ │ │ │ │ SuccessKilled.java
│ │ │ │ │
│ │ │ │ ├─enums
│ │ │ │ │ SeckillStatEnum.java
│ │ │ │ │
│ │ │ │ ├─interceptor
│ │ │ │ │ MyAdapter.java
│ │ │ │ │
│ │ │ │ └─redis
│ │ │ │ RedisConfig.java
│ │ │ │ RedisUtil.java
│ │ │ │
│ │ │ ├─distributedlock
│ │ │ │ ├─redis
│ │ │ │ │ RedissLockDemo.java
│ │ │ │ │ RedissLockUtil.java
│ │ │ │ │ RedissonAutoConfiguration.java
│ │ │ │ │ RedissonProperties.java
│ │ │ │ │
│ │ │ │ └─zookeeper
│ │ │ │ ZkLockUtil.java
│ │ │ │
│ │ │ ├─queue
│ │ │ │ ├─jvm
│ │ │ │ │ SeckillQueue.java
│ │ │ │ │ TaskRunner.java
│ │ │ │ │
│ │ │ │ ├─kafka
│ │ │ │ │ KafkaConsumer.java
│ │ │ │ │ KafkaSender.java
│ │ │ │ │
│ │ │ │ └─redis
│ │ │ │ RedisConsumer.java
│ │ │ │ RedisSender.java
│ │ │ │ RedisSubListenerConfig.java
│ │ │ │
│ │ │ ├─repository
│ │ │ │ SeckillRepository.java
│ │ │ │
│ │ │ ├─service
│ │ │ │ │ ISeckillDistributedService.java
│ │ │ │ │ ISeckillService.java
│ │ │ │ │
│ │ │ │ └─impl
│ │ │ │ SeckillDistributedServiceImpl.java
│ │ │ │ SeckillServiceImpl.java
│ │ │ │
│ │ │ └─web
│ │ │ SeckillController.java
│ │ │ SeckillDistributedController.java
│ │ │
│ │ ├─resources
│ │ │ │ application.properties
│ │ │ │ logback-spring.xml
│ │ │ │
│ │ │ ├─sql
│ │ │ │ seckill.sql
│ │ │ │
│ │ │ ├─static
│ │ │ └─templates
│ │ └─webapp
思考改进
- 如何防止单个用户重复秒杀下单?
- 如何防止恶意调用秒杀接口?
- 如果用户秒杀成功,一直不支付该怎么办?
- 消息队列处理完成后,如果异步通知给用户秒杀成功?
- 如何保障 Redis、Zookeeper 、Kafka 服务的正常运行(高可用)?
- 高并发下秒杀业务如何做到不影响其他业务(隔离性)?
码云下载:从0到1构建分布式秒杀系统
可供参考
作者: 小柒2012

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
自适应网站与响应式网站的区别
自适应网站与响应式网站的区别 网站建设是对于一个新手来讲是一件繁琐累人的事情,首先你要考虑自己的网站用途是什么?如果自己做建设,你需要的知识是很多的,如C++、java、php、dreamweaver、photoshop、firework等等,一个网站不单单做出来,还是需要后期维护的。网站建设初期,对于无网页设计经验的小白们还需要网站模版。所以说制作一个网站不是轻而易举的事情,需要耐心和坚持,才能制作出一个完美的网站。 对于自适应网站与响应式网站的区别,我想很多人都会有所误解。误以为两者是无区别的。一开始小编在网站制作建设这一块还是小白的时候,也是这样误以为的。但是在接触过后,才明白自适应网站与响应式网站是有实质上的区别的,这两者在外人看来大致是相同。但是在网站的体验过程中,你会发现有许多细微的分别。从网站建设的角度来讲自适应网站建设也是响应式网站建设,响应式网站建设也是自适应网站建设。但是真正的细分起来,自适应网站只是响应式网站的一个子集。在这里小编简单化给大家解释一下,要分出一个网站他是响应式还是自适应。你要先了解什么是响应式布局与自适应布局。 响应式布局简而言之就是一个网站能够兼...
-
下一篇
go-ethereum源码搭建环境
阅读源码对深入理解以太坊和区块链的原理是非常有用的,通过阅读源码可以知道交易、区块等核心数据结构的组成,可以对区块链的底层实现原理和运行过程有一个更清晰的认识,很多不明确的问题都可以从源码中找到答案。 网上以太坊的技术资料很多,但多数是关于智能合约和应用开发的,真正涉及底层实现和源码的很少。本文介绍以太坊go-ethereum源码的阅读环境配置,之后会陆续介绍一些源码阅读心得体会。以太坊有8种语言的实现,选择go-ethereum是因为它是以太坊的官方实现版本,包含了以太坊的所有特性,比较权威和全面,它是用go语言编写的,go语言学习起来比较容易,而且可读性也比较好。 阅读源码有一个代码编辑器就够了,但是为了更好的体验和更高的效率,还需要做一些配置,比如代码高亮、代码跳转等。 安装go语言 为了能支持代码跳转,需要安装go语言,安装教程参考这篇文章,其中最重要的是要保证正确设置了GOPATH,这样才能进行代码跳转。如果想学习go语言,可以看一下在线教程A Tour of Go,或者去看《The Go Programming Language》这本书。 配置编辑器 看代码可以选择你喜欢的...
相关文章
文章评论
共有0条评论来说两句吧...