第九周作业
请简述 JVM 垃圾回收原理。
JVM将内存分为了五个区域,分为两类,每个线程共享的:堆,方法区; 每个线程独有的:栈,程序计数器,私有方法栈。
JVM回收的区域的堆的,里面主要存放了每个Java对象的实例。这里使用了 分代垃圾算法,分为年轻代,老年代,永久代/元空间。 年轻代里面又分为伊甸园区和两个存活区。年轻代的回收算法有几种,老年代也有几种如cms,parold等。jdk8支持G1,G1将整个堆分为很多个小的区域region,每个region可能是老年代也可能是年轻代,所以它表面上是复制算法,整体上看也是标记整理。还有很多。。。。。
设计一个秒杀系统,主要的挑战和问题有哪些?核心的架构方案或者思路有哪些?
一、如何理解秒杀系统
秒杀系统其实主要解决两个问题,一个是并发读,一个是并发写。并发读的核心优化理念是尽量减少用户到服务端来“读”数据,或者让他们读更少的数据;并发写的处理原则也一样,它要求我们在数据库层面独立出来一个库,做特殊的处理。另外,我们还要针对秒杀系统做一些保护,针对意料之外的情况设计兜底方案,以防止最坏的情况发生。
总之,要遵循几个原则,就是要保证用户请求的数据尽量少、请求数尽量少、路径尽量短、依赖尽量少,并且不要有单点。
二、秒杀系统的要求
其实,秒杀的整体架构可以概括为“稳、准、快”几个关键字。
1、所谓稳,就是整个系统架构要满足高可用,流量符合预期时肯定要稳定,就是超出预期时也不能掉链子,要保证秒杀活动顺利完成。
2、所谓准,就是秒杀10台iPhone,那就只能成交10台,多一台少一台都不行。一旦库存不对,那平台就要承担损失,所以准就是要求保证数据一致性。
3、所谓快,就是说系统的性能要足够高,否则你怎么支撑这么大的流量呢?不光是服务器端要做极致的性能优化,而且在整个请求链路上都要做协同的优化,每个地方快一点,整个系统就完美了。
稳、准、快对应架构上的高可用、一致性和高性能的要求。
1、高性能。
秒杀涉及大量的并发读和并发写,因此支持高并发访问。系列笔记,从设计数据的动静分离方案、热点的发现与隔离、请求的削峰与分层过滤、服务端的极致优化这4个方面介绍。
2、一致性。
秒杀中商品减库存的实现方式同样关键。可想而知,有限数量的商品在同一时刻被很多倍的请求同时来减库存减库存又分为“拍下减库存”、“付款减库存”以及预扣等几种,在大并发更新的过程中都要保证数据的准确性,其难度可想而知。后面会专门讲解如何设计秒杀减库存方案。
3、高可用。
就是设计PlanB来兜底,以便在最坏情况发生时仍然能够从容应对。
1) 对现有网站业务的冲击
因为秒杀活动只是网站营销的一个附加活动,这个活动具有时间短,并发访问量大的特点,如果和网站原有应用部署在一起,必然会对现有业务造成冲击,稍有不慎可能导致整个网站瘫痪。
2) 高并发情况以及数据库的负载
用户在秒杀开始前,通过不停的刷新浏览器页面以保证不会错过秒杀,这些请求如果按照一般的网站应用架构,访问应用服务器、连接数据库,会对应用服务器、数据库服务器造成极大的负载压力。
3) 突然增加的网络和服务器带宽
假设商品页面大小200K(主要是商品图片大小),那么需要的网络和服务器带宽是2G(200K×10,000),这些网络带宽是因为秒杀活动新增的,超过网站平时使用的带宽。
4) 直接下单
秒杀的游戏规则是到了秒杀时间才能开始对商品下单购买,在此时间点之前,只能浏览商品信息,不能下单。而下单页面也是一个普通的URL,如果得到这个URL,不用等到秒杀开始就可以下单了。
5) 防止机器秒杀
防止网上的一些“秒杀器”
针对上面的5个问题,对应的策略如下:
1) 秒杀系统独立部署
为了避免因为秒杀活动的高并发访问而拖垮整个网站,使整个网站不必面对蜂拥而来的用户访问,将秒杀系统独立部署,如果需要,还可以使用独立的域名,以和网站完全隔离,即使秒杀系统崩溃了,也不会对网站造成任何影响。
2) 秒杀商品页面静态化
秒杀商品页面重新设计,不使用网站原来的商品详情页面,页面内容静态化:商品描述,商品参数,成交记录,用户评价全部写入一个静态页面,用户请求不需要经过应用服务器的业务逻辑处理,也不需要访问数据库。所以秒杀商品服务不需要部署动态的Web服务器、数据库服务器。
3) 租借秒杀活动网络带宽
对于因为秒杀新增的网络带宽,必须和运营商重新购买或者租借。为了减轻网站服务器的压力,需要将秒杀商品页面缓存在CDN,同样需要和CDN服务商临时租借新增的出口带宽。
4) 动态生成随机下单页面URL
为了避免用户直接访问下单页面URL,需要将该URL动态化,即使秒杀系统的开发者也无法在秒杀开始前访问下单页面的URL。办法是在下单页面URL加入由服务器端生成的随机数作为参数,在秒杀开始的时候才能得到。
思路:
1、把商品的数量放到redis中。
2、秒杀时使用decr或decrBy命令对商品数量减一。如果不是负数说明抢到。(比如key: 秒杀id_商品id)
3、一旦返回数值是负数说明商品已售完。
时间方案(解决频繁刷新取时间,以及判断秒杀是否过期):
1、确定一个秒杀开始时间和结束时间,并把它放在redis里面。
2、使用活动开始时间-当前时间可以计算出当前秒杀是否正在进行以及倒计时。
倒计时方案(解决频繁刷新取时间):
1、使用活动开始时间-当前时间可以计算出一个秒为单位的数值。
2、在redis中设置一个key(活动开始标识)。设置key的过期时间为第三步计算出来的时间。
3、展示页面的时候取出key的有效时间。Ttl命令(比如key: 秒杀id。expire key)。使用js倒计时。
4、一旦活动开始的key失效,说明活动开始。
5、需要在活动的逻辑中,先判断活动是否开始。
评论 (1 条评论)