1.为什么学习12306项目
1.1业务复杂
业务复杂度高于淘宝双11,考验个人程序设计能力
动态库存
上海 - 南京 - 北京
上海-北京:1张票
上海-南京;南京-北京 2张票
选座功能
靠窗、过道
*大部分人都会选择靠窗的位置
线上线下
1/4 线下,3/4线上
*总要给线下留一些票
持续高并发业务,需要更综合的高并发设计
不停的刷票
*比如开售前一分钟,怕抢不到票,输入信息后一直刷新,或者现在俗称的黄牛行为
绝不能超卖
*有超卖的情况:
好比这趟车是北京西发往银川途径石家庄,有人买了北京到石家庄的票,却在银川下车
1.2数据量大
1.3并发量高
每秒从几十万到百万级流量不等,且还能保证高并发、高性能、高可用的项目。
*可以使用redis集群
1.4高并发场景有哪些?
商品秒杀,淘宝双11
并发高,业务相对简单
核心:下单、库存-1、不要超卖
*常见双十一时淘宝崩了
微信支付宝平台
微博突发热点
*这个也挺复杂,因为不知道具体突发热点的时间,纯随机,12306还好,比如8点放票,可以在7点完成服务器的扩容,而微博不是,突然这个时间有位流量明星整了一个热点,这段时间里的访问直线上升,根本确定不了什么时候会突发热点
用户操作日志
12306购票平台
2.学习12306后可以得到什么
2.1实现高并发的解决方案
百万人同时抢1万张票,系统如何保证其正常及稳定性?
持续秒杀 高并发 技术
Web 服务器
Web应用服务器
前端
针对静态资源做CDN(内容分发网络)
*CDN的全称是Content Delivery Network,即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输得更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
使用CDN的好处
1. 不用担心自己网站访客,在任何时间,任何地点,任何网络运营商,都能快速打开网站。
2. 各种服务器虚拟主机带宽等采购成本,包括后期运维成本都会大大减少。
3. 给网站直接带来的好处就是:流量,咨询量,客户量,成单量,都会得到大幅度提升。
页面静态化 thymleaf 、freemark
倒计时&Loading
*比如前端实现一个正在‘加载中...’(转圈圈...)
使用验证码削峰
*例如下面的图片验证码,通过验证码登录的方式拦截一部分人,或者说选择的快与慢来拦截一部分人
后端
微服务-服务拆分合理及高效
基本原则: 根据功能模块进行划分
根据模块提供的功能**用户使用率
负载均衡 nginx+keepalive loadbalancer
限流降级 sentinel。。。 MQ
缓存: Redis Mongodb Spring 自身的缓存
令牌 限流降级,安全校验
接口安全怎么处理的?
异步处理 mq 线程池 .....
JVM 调优,代码的调优
......
用到 MQ ,Redis,Mongodb 线程池。。。。
数据库
分库:业务分库、读写分离(热点数据)
分表:横向分表、纵向分表
冗余设计,反范式,空间换时间,选择合适的数据类型
分布式数据库
选择合适的存储引擎
其它
分时段秒杀
弹性扩容
自动扩容有时反应比较慢,不适合突发大量请求,在秒杀之前,需要提前扩容好,之后再自动回收降低成本。
候补+排队
2.2如何解决忙碌问题
一天的请求量大概1500亿,平均170万/秒 ,高峰期300万/秒
平均一年售出40亿 张,高峰期日售票能力达到了2000万张
高峰期1秒可卖出1300张票 (1秒卖出一辆车)
忙碌
- 提高处理能力:QPS(每秒查询率)和TPS(每秒事务处理量)
*QPS:
每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,在因特网上,作为域名系 统服务器的机器的性能经常用每秒查询率来衡量。
对应fetches/sec,即每秒的响应请求数,也即是最大吞吐能力。
TPS:
每秒钟系统能够处理的交易或事务的数量。它是衡量系统处理能力的重要指标。TPS是LoadRunner中重要的性 能参数指标。
堆积硬件
软件:Gemfire(分布式内存数据库)
算法:模型、逻辑
b.削峰
业务:验证码、分时段、排队
技术:限流、异步
1)给10秒倒计时,必须阅读一下用户规则等
2)验证码
2.3.如何保证不超卖、不少卖?
模型设计&逻辑实现
余票查询:记录站站余票
一列火车有5个站,可拆分成4+3+2+1=10条站 站记录
ABCDE
座位购买:记录座位销售详情
一列火车有5个站A-E,1号座位:0111,代表只剩AB可买
2.4.高并发 秒杀 场景常见问题
2.4.1.秒杀还没开始,页面就崩了
前端优化:页面静态化\CDN分流
2.4.2.秒杀刚开始,服务器就崩了
后端优化(限流、令牌等)、数据库优化
2.4.3.秒杀结束后,库存崩了
超卖:加锁
2.4.4.秒杀过程没问题,但服务器响应很慢
异步削峰、排队、缓存等
*比如ATM机存取钱,插入卡后会等几秒,十几秒...
2.5.12306项目的亮点
海量数据分库分表
多种设计模式代码中实战
敏感数据加密存储
保障数据库与缓存一致性
全局唯一分布式 ID 改造
缓存穿透&击穿等问题
售票的业务问题
3.如何学习12306项目
3.1项目概述
12306项目采用前后端分离的分布式架构实现的,前端主要完成会员登陆,注册,购票,订单等功能的展示,其中会员可以使用浏览器通过用户名或邮箱或手机号三者中的任意一个配合密码完成登陆;后端主要以微服务的形式提供数据支持和业务流程处理;4
登陆后的主界面如下:
3.2需求分析
12306的核心业务逻辑有3块,分别是: 车票模块,会员模块,订单模块;
会员模块的核心功能:
1. 会员注册/登陆
2. 个人信息展示/编辑
3. 乘车人/CRUD
票务模块的功能有:
1. 车票查询(带分页和条件)/预订车票
订单模块的核心功能有:
1. 全部车票订单
2. 本人车票订单
3. 订单支付
4. 订单删除
3.3.技术选型
相关技术:
前后端分离架构 + 高并发技术项目实战
Vue3 + Vue CLI5 + Ant Design Vue3
JDK17
Springboot3 (最低JDK17)
SpirngCloudAlibaba 2022:gateway、nacos、sentinel、openfeign
mybatis plus、通用mapper
高并发技术:分布式缓存、分布式锁、分布式事务、限流、异步削峰等
xxl-job
......
版本依赖
3.4.架构设计
业务流程:
技术架构:
3.4.功能模块
4.接下来跑一下前端,还有建数据库,搭建后端微服务
前端
数据库
后端环境搭建(具体搭建过程可以看下主页别的文章)
5.会员模块
5.1会员列表
整体流程:
1. 点击页面的会员列表后,给后端发送异步请求,携带分页相关参数;
2. 后端收到请求后,根据分页参数查询数据库相关信息并封装成统一结果对象;
3. 后端将统一结果对象响应给前端,前端负责渲染数据;
后端实现思路:
1. controller层接收分页相关数据,并调用业务层,根据分页相关数据查询结果;
2. 业务层调用持久层完成数据库查询并将结果封装称分页对象;
3. 业务层将分页对象返回给controller之后,controller将结果统一封装后返回给页面;
后端接口信息:
接口地址:`/member/member`
请求方式:`GET`
响应数据类型:`*/*`
5.2会员删除
*点击yes将已删除状态改为是
整体流程:
1. 点击页面的删除按钮后,会先弹出气泡提示框,再次点击气泡提示框中的yes按钮后给后端发送异步请求,携带用户名参数;
2. 后端收到请求后,根据用户名完成逻辑删除(与之前的逻辑删除不太一样,这里删除了仍然显示出来);
3. 后端将统一结果对象响应给前端,前端负责渲染数据;
后端实现思路:
1. controller层接收用户名,并调用业务层,根据用户名完成逻辑删除;
2. 业务层调用持久层完成数据库修改并将结果返回;
3. controller将根据影响的行数将结果统一封装后返回给页面;
后端接口信息:
接口地址:`/member/member`
请求方式:`DELETE`
响应数据类型:`*/*`
5.2会员恢复
*点击yes将已删除状态改为否
整体流程:
1. 点击页面的删除按钮后,会先弹出气泡提示框,再次点击气泡提示框中的yes按钮后给后端发送异步请求,携带用户名参数;
2. 后端收到请求后,根据用户名完成修改(即为未删除状态)
3. 后端将统一结果对象响应给前端,前端负责渲染数据;
后端实现思路:
1. controller层接收用户名,并调用业务层,根据用户名完成修改;
2. 业务层调用持久层完成数据库修改并将结果返回;
3. controller将根据影响的行数将结果统一封装后返回给页面;
后端接口信息:
接口地址:`/member/member`
请求方式:`PUT`
响应数据类型:`*/*`