秒杀 系统 解决思路,高并发 Django性能介绍
介绍秒杀
- 正常电子商务流程
1.查询商品;2. 创建订单;3. 扣减库存;4. 更新订单;5. 付款;6. 卖家发货 - 秒杀业务的特性
1.低廉价格;2. 大幅推广;3. 瞬时售空;4. 一般是定时上架;5. 时间短、瞬时并发量高;
秒杀的特点
-
读多写少
缓存 -
高并发
限流、负载均衡、缓存、异步并发(消息队列中间件)、队列 -
资源冲突(超卖)
数据库锁(乐观锁,悲观锁)、 分布式锁(redis、zk)
所谓“秒杀”,就是网络卖家发布一些超低价格的商品,所有买家在同一时间网上抢购的一种销售方式。通俗一点讲就是网络商家为促销等目的组织的网上限时抢购活动。由于商品价格低廉,往往一上架就被抢购一空,有时只用一秒钟。
秒杀商品通常有两种限制:库存限制、时间限制。
各层级常用解决方法
详解 解决办法:
-
应用层 – 浏览器:
浏览器缓存:包括页面html缓存和图片, js,css等资源的缓存。浏览器缓存是基于把页面信息保存到用户本地电脑硬盘里。 -
服务器响应更快:因为请求从缓存服务器(离客户端更近)而不是源服务器被响应,这个过程耗时更少,让服务器看上去响应更快。
-
减少网络带宽消耗:当副本被重用时会减低客户端的带宽消耗;客户可以节省带宽费用,控制带宽的需求的增长并更易于管理。
按钮控制 & 图形验证码 都会减少用户的访问速度,而减轻服务器的压力 -
网络层 – 网络路由:
全称:Content Delivery Network或Content Ddistribute Network,即内容分发网络。CDN是一组分布在多个不同的地理位置的WEB服务器,用于更加有效的向用户发布内容,在优化性能时,会根据距离的远近来选择 。
CDN加速意思就是在用户和我们的服务器之间加一个缓存机制,通过这个缓存机制动态获取IP地址根据地理位置,让用户到最近的服务器访问。
原理图:
CDN是静态资源的缓存(JS,Html、Css、图片、视频)
举例: 玩游戏的朋友可能知道,有个东西就做延迟,向我们经常说延迟460,延迟是什么意思呢?就是你的手机、电脑上面的资料,发送到服务器,一个来回所需要的时间。我们都知道,网络的传输速度接近光速,从深圳到美国硅谷的距离大概为1万公里,光的速度为30万公里每秒,也就是说,如果你在美国上传一张图片,并且服务器也在美国,你在深圳访问,最少也要60毫秒以上才能拿到数据。
事实上,网络环境是非常复杂的,真实从深圳访问美国可能要好几百毫秒。CDN的出现,就是为了解决这个问题。在美国上传的图片,我们也同样保存一份在香港,如果在深圳访问的时候,我们就直接使用香港的数据即可,这样子速度就会快非常多。 -
负载层 – Nginx:
-
Nginx 反向代理缓存 反向代理
-
Nginx 负载均衡 负载均衡
反向代理和负载均衡的区别 ?
负载均衡需要通过反向代理来实现,反向代理就是指nginx作为前端服务器,将请求转发到后端,再将后端服务器的 结果,返回给客户端。它在中间做了一个代理服务器的角色单一的 负载均衡会出现单点故障。
Nginx集群解决:- 一台公网nginx通过upstream功能,轮洵、ip、url多方式分发到内网多台nginx。但公网的nginx如果down机的话,内网全段。 Nginx集群
keepalived 可以最佳完美的解决:
- Keepalived是一个基于VRRP协议来实现的服务高可用方案,可以利用其来避免IP单点故障。但是它一般不会单独出现,而是与其它负载均衡技术(如lvs、haproxy、nginx)一起工作来达到集群的高可用。
- Master(主机),则Master占有vip且nginx运行在Master上
- Master挂了,则backup(备份)抢占vip且在backup上运行nginx服务
是Master一直在定时发送 1/s 自己存活的信息,如果第3s不发了 ↑ - 如果master服务器上的nginx服务挂了,则vip资源转移到backup服务器上
- 检测后端服务器的健康状态
-
动静分离:
动态资源(jsp、ftl、thymeleaf)与静态资源(js、css、img)分开部署。 -
限流
抢购:nginx设置了保护功能,当流量过大自动丢弃(负载层就丢弃了)
同一个设备、账号、出接口ip 一秒钟最多访问次数
-
-
服务层:
- 动态页面静态化:
动态页面静态化是通过动态网站静态化将动态网页以静态的形式进行展现。
静态页面是没有数据库支技的不能通过更新数据库而更新网页内容并非网站上没有动画的就是静态页面。 - 应用缓存:
本地缓存 - 分布式缓存
如Redis缓存 - 异步
Celry - 队列
rabbitMQ - 原子操作保障
原子操作(atomic operation)是不需要synchronized(同步)",所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch;
- 动态页面静态化:
-
数据库层
- 乐观锁:
在读操作不加锁,写操作进行加锁。事务完成之后校验家所签的数据,成功就执行下去,校验失败就回滚。 - 悲观锁:
在读写情况下都加锁。 - Mysql主从:
mysql一主多从,读写分离:写主库,读从库(所有数据库的数据一样)
数据一样的,那么当数据量太大的时候查询还是很慢 - 分库:
根据用户id分库)
所有数据库的表结构一样,存储的数据完全不一样
真实环境以用户id进行分库,每一个库的数据都很小,查询起来就快了 - 分表:
根据时间分表
当一个表中数据过大的时候,我们必须要对表拆分
购物清单表中有两千万数据
最近半年的购物数据时 一百万
半年到一年的数据有五百万
一年以前的数据有一千万
- 乐观锁:
高并发
高并发中一些概念
- PV(访问量): 页面访问量,页面刷新一次算一次。
- UV(独立访客): 即Unique Visitor,一个客户端(电脑,手机)为一个访客;
- DAU(日活跃用户数):登录或使用了某个产品的用户数,这与流量统计工具里的访客(UV)概念相似。
- 峰值QPS:
原理:每天80%的访问集中在20%的时间里,这20%时间叫做峰值时间
公式:( 总PV数 * 80% ) / ( 每天秒数 * 20% ) = 峰值时间每秒请求数(QPS) - QPS/TPS(每秒查询率):每秒能够查询次数(QPS/TPS= 并发数 / 平均响应时间)
并发数:并发数是指系统同时能处理的请求数量,这个也是反应了系统的负载能力。
吐吞量:吞吐量是指系统在单位时间内处理请求的数量
响应时间(RT):响应时间是指系统对请求作出响应的时间,一般取平均响应时间
例2:
- 每天200万PV,那么它的QPS = (2000000 * 0.8)/ (246060*0.2)≈ 93
- 假设按照上面那样一台机器的QPS是50,那么抗住每天200万PV的访问量需要2台这样的机器
django性能
原生django:
用原生django的server做处理的,在10000次请求的情况下brokenpipe的几率极高,成功率只有14%。
uwsgi + nginx:
uwsgi是性能极高的一个由C编写的服务器,它使用uwsgi协议
这次让它配合nginx处理django的request,参数为4进程+2线程,性能立即直线上升,处理请求的成功率也基本在90%左右