抽奖活动的高可用、高并发优化 |
您所在的位置:网站首页 › 王者积分抽奖一天最多50次嘛 › 抽奖活动的高可用、高并发优化 |
这几年工作中做过不少营销活动,这里以抽奖活动为例,讨论一下如何设计出一个高可用、高并发的营销系统。 高可用、高并发架构的核心是分流和限流。系统架构时,应根据每一种营销活动的场景与特性,制定不同的分流、限流方案。 一 业务在开始进行架构讨论前,我们的简单描述一下业务,以方便我们有针对性的进行讨论。 1. 业务需求公司希望拉更多的新用户来注册我们的app,所以想通过一个抽奖活动,用一些奖励和刺激的手段来促使用户使用我们的app,并通过奖励手段让用户帮我们一起推广宣传。业务主要诉求如下: 用户需要在app中或者活动页面(H5)中进行某些操作,以获取抽奖机会;例如分享给好友以后奖励一次抽奖机会。 每天每人最多拥有N次抽奖机会。 活动结束后给中奖用户发奖品。 每个人只能中一次奖。 …… 2. 抽奖主流程
这是系统的核心流程,也是后面进行性能优化的核心内容。 3. 分析 对活动而言,最重要的是曝光量,只有更多的分享与传播,才能让更多的人参与进来,活动效果才越好,对技术上的要求就是能够提供尽可能好的用户体验。 抽奖活动的页面中,大部分内容都是静态的,只有抽奖按钮需要与服务端交互;对此可以通过客户端、CDN缓存等提升用户体验。 营销活动是拿真金白银来推广,所以需要有效的机制能防止被人恶意攻击,将全部奖品刷走。 如果活动中奖品价值都较高,此种情况下,通常奖品数量有限,中奖概率不高,所以即便是抽奖的并发量较大,实际写DB的压力也并不大,即在扣减奖品库存、向DB中插入中奖记录等环节的写压力并不会大。 如果活动发放类似于优惠券的虚拟奖品,数量可能很大,中奖概率非常高,那么当抽奖并发量大时,写DB的压力会很大。 二 核心指标 1. 高并发 营销活动对系统性能的要求,一般来说比常规业务高出很多;如果推广的效果比较好,流量可能会远超初始预期。基于此,系统应该能够支持较高的并发,并且在流量快速上升并超过容量规划时,能够及时、方便扩容。 2. 高可用核心是提供尽可能好的性能支持,让更多人能够使用我们的产品。具体见高性能优化部分内容 3. 隔离性营销活动不能影响常规业务;因为营销活动变动频繁,修改时应尽可能的避免影响到其他业务;前一次活动应该能够沉淀出一些内容,降低下一次类似的活动的实现成本。 4. 低耦合根据上面的需求我们可以看到,营销活动旺旺与主业务有交集。营销活动的特点是变化频繁,定制化需求多,应尽量降低营销活动与常规业务的耦合性。 可以考虑通过旁支流程来解决此问题。例如,用户在app上操作以后奖励抽奖机会这个业务,将用户的行为作为事件,通过MQ消息向外广播,营销活动监听相关的MQ消息,根据MQ消息给用户奖励抽奖机会。 5. 防刷在营销活动利益的驱动下,常常会有人找系统漏洞,钻系统空子,通过一些手段来刷系统奖品,影响营销效果。一般而言,有以下常规问题需要防范: 防恶意注册用户 防恶意调用接口 防奖品被少部分人获取 防用户误操作 三 架构高并发的核心思路是逐级分流,逐步分散流量。 高可用的核心思路是通过备份、限流、降级、熔断等手段提升可用性。 1. 整体思路充分分流,通过缓存、队列、消息等手段将大流量逐步分散。 以空间换时间,通过缓存来提升每个请求的处理速度,提升系统并发量。 异步处理,分析并识别出可以异步处理的逻辑,将他们异步化。 分层逐级拦截非法请求,仅让有效的请求到达底层系统;尽可能让每一次写操作都能成功。 根据每个系统的服务能力,设定流量极限,流量超过极限值后进行限流。 2. 分阶段优化模型 为了达到最高的并发性能,需要对整个环节的各个环节进行优化。现实中往往通过如下的倒三角形模型来逐层优化。
注意:这里不过多讲述概念性的内容,而是根据抽奖的需求讲述一些常规的方案;更多内容见博客《高并发技术》 客户端优化方案有:客户端(app、浏览器)缓存。 网络优化方案有:动静分离、静态化 服务端优化包括:缓存(硬盘、堆、分布式)、通信模型优化、异步化技术、线程池、DB存储优化。 响应优化包括:返回结果压缩。 3. 缓存策略通过分层缓存策略,对每一个环节进行有优化,提升性能。
客户端(或浏览器)缓存:减少用户请求数量,降低系统压力,提升用户体验。 CDN缓存:合理地利用CDN,内容缓存放置在离用户最近的地方,加快响应的速度。 Web服务器缓存:减小后端应用服务器压力,抵挡瞬间峰值和/或针对少量定点内容的攻击。 应用层缓存:减小后端应用服务器压力,加快响应速度。 4. 分流模型
从图中可以看到,经过前面的逐层分流,最终只有少部分请求会进行DB操作。当绝大部分的流量都被通过种种手段分担,系统自然就可以轻松处理剩余的少量流量,这也就意味着系统可以具有非常高的性能。 四 高并发优化 1. 逐级分流 1) 客户端缓存 我们的营销活动都是通过H5来承接的,app通过webview来加载或者直接通过浏览器加载数据时,可以利用浏览器缓存或者手机SD卡,将数据缓存在客户端,例如图片、CSS、JS文件等。 越多的内容从本地缓存读取,响应速度会越快;不过需要注意缓存数据的更新问题,以及内存占用问题。 2) 动静分离 一个抽奖活动页面,绝大多数树内容都是静态的图片、css、js等,极端情况下可能只有一个抽奖按钮需要与服务端交互。通过将图片、css、js等内容存储在CDN节点中,用户浏览活动页面时,直接从距离用户最近的CDN节点获取静态资源,不用和服务端交互。优化模型如下:
在营销活动的场景中,使用此种方案时,至少可以让90%-95%的流量不用与服务端交互,可以节省大量带宽,对性能提升非常明显。 3) 防误操作 用户点击抽奖按钮,调用服务端接口时,当请求的响应速度比较慢时,如果客户端不做处理,用户会感觉到卡顿;此种情况下用户和可能会反复点击抽奖按钮,这无疑会进一步加大服务端的访问量,服务端的响应速度可能进一步降低;另外因为每点击一次都需要消耗一次抽奖机会,因一次卡顿导致用户耗费多次抽奖机会也是不合适的。 这种问题的处理方式比较多,例如:可以通过在H5端通过js控制,点击抽奖按钮以后,在请求返回之前将按钮置灰,禁止用户再次点击或者弹出一个loading动画来解决此问题。 这种方案在服务器压力大,响应慢时效果比较明显;另外,可以明显的提升用户体验。 4) 防代码请求 如果活动的奖励足够吸引人,就可能有第三方通过代码直接调用抽奖接口。因为代码的执行速度远快于手的点击动作,这可能给营销活动带来非常大的危害,同时也会给系统带来非常大的并发压力。因为风控的性能损耗较大,所以在营销活动中一般不能通过风控系统来解决此问题。 一般而言,每一家公司都会有自己的安全策略,保证请求的安全可靠,应尽可能让第三方伪造此流程的难度加大;除此之外,运营活动中要能够识别出异常流量,做好应对措施,尽可能的降低危害。 a) 伪造一个用户多个线程中都使用相同的用户进行请求。这种场景比较好解决,通过userId加一个分布式锁即可解决。 b) 伪造多个用户每个线程使用不同的用户进行请求。这种比较麻烦,常见处理手段有: 在用户注册时加限制,尽可能杜绝通过代码自动注册的行为,让每一个注册的用户尽量可靠。 和业务沟通,限制每个用户每天获取抽奖机会的次数,限制每人中奖次数。 抽奖机会通过用户的行为产生。例如:到社区对帖子评论以后才给一次机会,这将增大用户伪造请求的难度。 如果发现一定时间内某个ip下的流量明显异常,可以对此ip进行限流。例如:一个ip的请求量超过1000/min时,拒绝此ip的请求。注意,此方案可能有误判,因为当多人使用同一个局域网时,此时服务端收到的ip可能是相同的。 添加小黑屋功能,发现恶意用户、ip,将他们拉入小黑屋,一段时间内禁止他们后续的访问。 5) 业务规则拦截根据前文中的需求我们可以得出:同一个用户只允许中一次奖;每天最多抽奖三次。当收到抽奖请求时,我们可以判断是否符合这这些规则: 可以将中奖用户放在缓存中,收到抽奖请求或抽中时,通过缓存校验此用户之前是否已中奖。 可以将抽奖次数放在缓存中,通过计数器自减的方式扣减抽奖机会。 2. 缓存大量的运算将消耗大量服务器资源,频繁的DB操作也会给DB带来较大的压力,在高并发场景中,常常通过缓存运算结果或者DB记录,以降低资源消耗,提升请求的响应速度。 1) 缓存不常变动的数据缓存非常适合存储不经常变动的数据,通过缓存他们可以极大的提升性能。 如,活动中奖品一般不会频繁改变,页面中需要展示奖品信息时,我们可以将奖品信息加载到缓存中,每次请求时直接读取缓存。 2) 缓存实时性要求不高的数据业务上如果对某些数据的实时性要求并不高,那么也可以通过缓存降低系统的性能损耗,提升请求速度。 如:活动中需要播报中奖信息,业务上并不要求实时展示最新中奖的几人,所以可以通过启动一个线程,将最近一段时间内需要播报的名单加载到缓存中,播报时从缓存中直接返回数据。 3) 频繁变动的内容走缓存频繁变动且持久化意义不大的数据非常适合走缓存。 如,用户完成一些任务以后,奖励一些抽奖机会,奖励的抽奖机会就很适合存储在缓存。使用redis或者tair的原子性加、减操作,每奖励一次抽奖机会,自增1,每抽奖一次,自减1。 4) 从缓存减库存抽中奖品时,需要将此奖品总数减1,这其实就是一种减库存操作。并发情况下从DB中减库存,一来性能比较差,二来为了避免脏写可能导致DB更新失败概率大增。此时改为从缓存中减库存。 a) 减库存活动开始前,将奖品库存加载到缓存。 抽奖时直接从缓存中扣除;如果扣除库存以后,剩余奖品数量>=0,表示扣减库存成功,然后发送MQ消息;如果库存扣除后,剩余奖品数量 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |