官方出品!揭秘阿里巴巴APP 8.0 视觉品牌升级背后的设计思路 京东抢购秒杀软件


如何设计一个秒杀系统


  1. 自己可以code一个 。

  2. 用百度H5做 。

  3. 用互动大师做 。


官方出品!揭秘阿里巴巴APP 8.0 视觉品牌升级背后的设计思路
阿里巴巴副总裁、中国内贸事业部总经理汪海在对外分享时提出 1688 已经从信息平台时代进入数字化营销平台时代,让 1688 用户在平台内完成营销和销售一体化的整个商业闭环 。1688 的使命也升级成「在数字化经济时代,让天下没有难做的生意!」在全新的业务态势下,为了更好的满足用户需求,阿里巴巴(1688)主客升级势在必行 。
首页重要性
首页既是业务分流的中心场景,也是平台卖家判断平台打法,买卖家感知平台价值的重要「门面」 。从 UED 专业视角来看,首页是定义 APP 内体验范式及视觉风格的核心场景 。
如何改?
1. 盘点现象,定义问题
满足业务新的诉求:平台阶段性战略不同,1688 从曾经的信息平台过渡到交易平台,如今向数字营销平台转型,旧的内容框架难以承载业务的新发展 。
提升分流质量:从过去的数据效果来看,需重新判断,在 For 特色采购需求和服务大面采购需求之前,如何平衡调优,提升首页的流量转化效能 。
体验升级:移动端 APP 天然生长在手机系统上,系统的风格更迭也牵动着 APP 的变化和升级 。在 8.0 升级前,1688APP 存在着 5.0、6.0、7.0 多个由不同设计师在不同时间点所设计的场景,到8.0,APP 趋待从框架层、表现层以及品牌等方面进行统一及升级 。
改版策略
1. 聚焦用户价值,基于业务打法升级内容框架
APP 升级前与业务对焦,我们收到三点诉求:
在内容框架制定上,我们聚焦用户价值,舍掉 7.0 时的内容版块个性化,聚焦做商品的个性化,仅保留For大面用户的营销、内容场景,提升算法推荐区的曝光率,以此区域的商品做首页的直接转化 。
2. 弱化容器,突出内容,塑造心智
视觉容器升级
做平视觉框架,选择「大间距分隔」,为内容留出干净、简洁的视觉空间 。
精简内容栅格,避免形式给用户阅读带来的负担 。
提高留白率,提升页面整体的透气性,为内容留出更清爽、轻松的阅读空间 。
拉大字体大小的梯度,加重字体颜色梯度,提升文字的清晰度和可读性 。
强调版块特性,塑造买家心智感知,达成业务目标
强化搜索:7.0时,曾上线过将搜索做到「主观上觉得显眼」的测试方案,但相较于之前沉浸式搜索,数据几乎没变化 。
8.0 阶段,从视觉表现层跳出看:「强化搜索」并不意味把搜索设计得更「显眼」,而是达成「让更多用户更高频地使用搜索」这一目标 。如提升搜索底纹词、热搜词精准度和吸引力、增加搜索布点等,都可能助力达成业务目标 。
基于用户单手操作时,拇指在屏幕不同区域的点击体验,选择将搜索组件移到更易于点击、视线更聚焦的屏幕位置,上线后数据提升非常明显 。
Banner 升级:7.0 的 Banner 画面丰富度高,加之描述字段多,用户阅读有一定成本,较难在 3 秒内掌握全 Banner 的信息 。此外,相比于 C 类用户,B 类用户会更偏理性,我们选择以更冷静、克制的「视觉语气」与 B 类商人对话,而非渲染氛围引导点击 。(上线后,同样的活动内容,按新、老两版规范设计投放两套 Banner,新版较老版 UV CTR 约高出 48%)
For 新人:以差异化的利益、个性化秒杀、新人攻略做用户的承接 。
营销场景心智差异化表达:营销由伙拼爆品、天天特卖两部分组成,我们判断爆品主打心智为「卖得火爆又便宜」,特卖主打心智是「限时限量抢便宜」,选择将两个区块最关键的特质做强化表达 。
内容场景(直播)动态化、互动感、实时性传递:抽象出直播间的方形版面+内容叠加形式来设计,大坑位以动图传递给用户直播的动态感,以红包、个性化商品的多维实时轮播气泡传达直播的互动感、实时性 。
3. 升级品牌,贯穿APP场景
为什么要做APP应用内的品牌设计?
品牌设计是将内容层(平台价值)与接收层(用户)做柔性链接的一环,譬如在 APP 场景中,由于有商品、商家、商机等「干货」,即使不特意做品牌设计,用户也能与平台保持刚性、稳定的连接 。而反过来看,品牌做得很好,但平台没有「干货」,用户也不会单奔着品牌设计来平台 。我们认为,做 APP 应用内的品牌设计,核心价值在于助力用户认知到平台特性,感知平台价值 。从设计专业视角来看,APP 应用内的品牌设计,有利于定义并统一 APP 内体验范式及视觉风格,保障用户的体验 。
怎么做?
每位设计师所处的业务环境不一样,解决问题策略和方式也千差万别,在 APP 应用内的品牌设计中,个人选择是通过厘清内容层(平台)多层次诉求及 For 用户的价值点,认知、感知接收层(用户)特质及内容倾向,基于内容层底料+接收层用户特质确定设计底层范式,塑造用户感知 。
1. 图形范式
在阿里巴巴商业操作系统中,1688 聚焦做 B 类业务,直接服务对象是 B 类买卖家,业务细分出档口尖货、淘工厂、企业采购、淘货源、微商代发、工业品超级店、跨境专供等,这些都是具有一定 B 类特质及体量感的场景,故在 APP 业务门洞及常规图标的表达上,基于扁平 vs 写实、轻盈 vs 厚重、活泼 vs 稳重的维度,图形选定轻拟物、弱对比的设计范式,塑造 B 类场景 For 买家的沉稳、份量感 。


此外,异常/空白场景也是平台与用户互动,塑造用户感知品牌的机会 。在空态 情感 化插图部分的绘制上,力求塑形出有份量、易读、有意味的场景以示对应空态,并佐以轻微动效,增强空态的互动感 。(在收藏夹、我的供应商等工具型场景,基于空态信息的价值考虑,将空态与工具新手引导相结合,并未做常规的插图 。)

2. 色彩范式
标准色
随着业务的发展,我们基于新的业务态势,丰富了 1688 品牌色,以橙红色作营销、利益属性的表达,以商务蓝作服务、数字化属性的表达,以金色作权益属性的表达 。
辅助色
在实际产品设计中,品牌色并不足以表达各类业务场景中的多层次的内容 。因此,基于 VI 品牌色,裂变出不同重量、层次更丰富的品牌辅助色 。
场景用色规则
基于买家角色及场景特征定义用色规则 。
1688色域及选色示意
以 HSB 模式划定出偏沉稳的 1688 色域,在日常 banner 及业务场景中可灵活取用 。

3. 动效范式及应用
动效是设计的重要手段,良好的动效表达能增强信息表达强度,清晰信息层级关系,提升用户体验的舒适度 。做动效之前,将 APP 信息结构平整到三层,保障内容在页面简洁明畅地呈现 。
在实际落地中,动效实现非常依赖技术资源,故动效设计之前,应考虑一个前提:动效设计增益内容表达,价值可论证,效果可衡量;同时,考虑接收层用户的商人特质,我们期望动效表达给用户以稳定感,并且在设计表达上能兼顾效率 。
在动效呈现部分,主要以缓入、缓出、缓动结合曲线来调节,总的来说,内容入场时节奏稍慢,速度缓,分层加载,交代清信息在 Z 轴上的层次关系,内容出场时节奏快,速度快,内容层级不用再做分层消失 。
APP 内典型场景的动效案例及演示:
4. 业务品牌的价值传递
此外,除以上在图形、色彩、动效等基础维度收口外,我们也需要将业务品牌放声给买卖家,以达成业务品牌的价值传递 。在 1688 向数字营销平台转型的阶段,业务提出了「源头厂货通天下」的口号,我们通过设计手段,利用 APP 开机启动页及下拉刷新的空间,将「货通天下」的概念强化表达 。
结语
以上便是此次首页改版阶段性的记录 。在 8.0 的视觉体系里,为更好地突出内容,视觉容器选择尽可能做轻、做平,以冷静、克制的「视觉语气」与 B 类商人对话 。当然,这是设计师和业务同学阶段性的选择 。后续品牌的完善及产品的优化,仍需结合数据持续打磨

(二)微信红包高并发系统设计方案(1)2017年1月28日,正月初一,微信公布了用户在除夕当天收发微信红包的数量——142亿个,而其收发峰值也已达到76万每秒 。百亿级别的红包,如何保障并发性能与资金安全?这给微信带来了超级挑战 。面对挑战,微信红包在分析了业界“秒杀”系统解决方案的基础上,采用了 SET化、请求排队串行化、双维度分库表 等设计,形成了独特的高并发、资金安全系统解决方案 。实践证明,该方案表现稳定,且实现了除夕夜系统零故障运行 。概要:
一、业务 特点 :海量的并发要求;严格的安全级别
二、技术 难点 :并发请求抢锁;事务级操作量级大;事务性要求严格
三、解决高并发问题 通常 使用的 方案 :
1.使用内存操作替代实时的DB事务操作(优点:内存操作替代磁盘操作,提高了并发性能 。)
2使用乐观锁替代悲观锁 。应用于微信红包系统,则会存在下面三个问题:滚并返回失败;并发大失败,小成功 。DB压力大 。
四、微信 红包 系统的高并发解决 方案 :
1.系统垂直SET化,分而治之 。
2.逻辑Server层将请求排队,解决DB并发问题 。
3.双维度库表设计,保障系统性能稳定
类似“秒杀”活动,群里发一个红包=“秒杀”商品上架;抢红包的动作=“秒杀”的查询库存;拆红包=“秒杀”
同一时间有10万个群里的用户同时在发红包,那就相当于同一时间有10万个“秒杀”活动发布出去 。10万个微信群里的用户同时抢红包,将产生海量的并发请求 。
微信红包是微信支付的一个商户,提供资金流转服务 。
用户发红包=购买一笔“钱”(在微信红包这个商户上),并且收货地址是微信群 。当用户支付成功后,红包“发货”到微信群里,群里的用户拆开红包后,微信红包提供了将“钱”转入折红包用户微信零钱的服务 。
资金交易业务比普通商品“秒杀”活动有更高的安全级别要求 。普通的商品“秒杀”商品由商户提供,库存是商户预设的,“秒杀”时可以允许存在“超卖”、“少卖”的情况 。但是对于微信红包,100元不可以被拆出101元;领取99元时,剩下的1元在24小时过期后要精确地退还给发红包用户,不能多也不能少 。
在介绍微信红包系统的技术难点之前,先介绍下简单的、典型的商品“秒杀”系统的架构设计,如下图所示 。
该系统由接入层、逻辑服务层、存储层与缓存构成 。Proxy处理请求接入,Server承载主要的业务逻辑,Cache用于缓存库存数量、DB则用于数据持久化 。
一个“秒杀”活动,对应DB中的一条库存记录 。当用户进行商品“秒杀”时,系统的主要逻辑在于DB中库存的操作上 。一般来说,对DB的操作流程有以下三步:
a. 锁库存
b. 插入“秒杀”记录
c. 更新库存
a.锁库存是为了 避免 并发请求时出现“ 超卖 ”情况 。同时要求这 三步操作 需要在 一个事务 中完成(难点:并发请求抢锁) 。
第一个事务完成提交之前这个锁一直被第一个请求占用,后面的所有请求需要 排队等待。同时参与“秒杀”的用户越多,并发进DB的请求越多,请求 排队越严重。
红包系统的设计上,除了并发请求抢锁之外,还有以下两个突出难点 :
首先,事务级操作量级大。上文介绍微信红包业务特点时提到,普遍情况下同时会有数以万计的微信群在发红包 。这个业务特点映射到微信红包系统设计上,就是有数以万计的“并发请求抢锁”同时在进行 。这使 得DB的压力 比普通单个商品“库存”被锁要大很多倍 。
其次,事务性要求严格。微信红包系统本质上是一个资金交易系统,相比普通商品“秒杀”系统有更高的事务级别要求 。
普通商品“秒杀”活动系统,解决高并发问题的方案,大体有以下几种:
如图2所示,将“实时扣库存”的行为上移到 内存Cache中操作,内存Cache操作成功直接给Server返回成功,然后 异步落DB持久化。
优点:提高了并发性能 。
缺点: 在内存操作 成功 但 DB持久化失败,或者内存 Cache故障 的情况下,DB持久化会 丢数据,不适合微信红包这种资金交易系统 。
商品“秒杀”系统中,乐观锁的具体应用方法,是在DB的“库存”记录中维护一个版本号 。在更新“库存”的操作进行前,先去DB获取当前版本号 。在更新库存的事务提交时,检查该版本号是否已被其他事务修改 。如果版本没被修改,则提交事务,且版本号加1;如果版本号已经被其他事务修改,则回滚事务,并给上层报错 。
这个方案解决了“并发请求抢锁”的问题,可以提高DB的并发处理能力 。
应用于微信红包系统,则会存在下面三个问题 :
1.在并发抢到相同版本号的拆红包请求中,只有一个能拆红包成功,其他的请求 将事务回滚并返回失败,给用户 报错,用户体验完全不可接受 。
2.将会导致 第一时间 同时拆红包的用户有一部分直接 返回失败,反而那些“ 手慢 ”的用户,有可能因为 并发减小 后拆红包 成功,这会带来用户体验上的负面影响 。
3.会带来 大数量 的 无效 更新 请求 、事务 回滚,给 DB 造成不必要的额外 压力。
微信红包用户发一个红包时,微信红包系统生成一个ID作为这个红包的唯一标识 。接下来这个红包的所有发红包、抢红包、拆红包、查询红包详情等操作,都根据这个ID关联 。
红包系统根据这个红包ID,按一定的规则(如按ID尾号取模等),垂直上下切分 。切分后,一个垂直链条上的逻辑Server服务器、DB统称为一个SET 。
各个SET之间相互独立,互相解耦 。并且同一个红包ID的所有请求,包括发红包、抢红包、拆红包、查详情详情等,垂直stick到同一个SET内处理,高度内聚 。通过这样的方式,系统将所有红包请求这个巨大的洪流分散为多股小流,互不影响,分而治之,如下图所示 。
这个方案解决了同时存在海量事务级操作的问题,将海量化为小量 。
红包系统是资金交易系统,DB操作的事务性无法避免,所以会存在“并发抢锁”问题 。但是如果到达DB的事务操作(也即拆红包行为)不是并发的,而是串行的,就不会存在“并发抢锁”的问题了 。
按这个思路,为了使拆红包的事务操作串行地进入DB,只需要将请求在 Server层以FIFO ( 先进先出 )的方式排队,就可以达到这个效果 。从而问题就集中到Server的FIFO队列设计上 。
微信红包系统设计了分布式的、轻巧的、灵活的FIFO队列方案 。其具体实现如下:
首先,将同一个红包ID的所有请求stick到同一台Server 。
上面SET化方案已经介绍,同个红包ID的所有请求,按红包ID stick到同个SET中 。不过在同个SET中,会存在多台Server服务器同时连接同一台DB(基于容灾、性能考虑,需要多台Server互备、均衡压力) 。
为了使同一个红包ID的所有请求,stick到同一台Server服务器上,在SET化的设计之外,微信红包系统添加了一层基于红包ID hash值的分流,如下图所示 。
其次,设计单机请求排队方案 。
将stick到同一台Server上的所有请求在被接收进程接收后,按红包ID进行排队 。然后 串行地进入worker进程 (执行业务逻辑)进行处理,从而达到 排队 的效果,如下图所示 。
最后,增加memcached控制并发 。
为了 防止 Server中的请求队列过载导致队列被降级,从而所有请求 拥进DB,系统增加了与Server服务器同机部署的 memcached,用于控制拆同一个红包的 请求并发数。
具体来说,利用memcached的 CAS原子累增操作,控制同时进入 DB执行拆红包事务的请求数,超过预先设定数值则 直接拒绝服务。用于 DB负载升高时的降级 体验 。
通过以上三个措施,系统有效地 控制了DB的“并发抢锁” 情况 。
红包系统的分库表规则,初期是根据 红包ID的hash值 分为多库多表 。随着红包数据量逐渐增大,单表数据量也逐渐增加 。而DB的性能与单表数据量有一定相关性 。当单表数据量达到一定程度时,DB性能会有大幅度下降,影响系统性能稳定性 。采用 冷热分离,将历史冷数据与当前热数据分开存储,可以解决这个问题 。
系统在以 红包ID维度 分库表的基础上,增加了以 循环天分表的维度,形成了 双维度分库表 的特色 。
具体来说,就是分库表规则像db_xx.t_y_dd设计,其中,xx/y是红包ID的 hash值后三位,dd的取值范围在01~31,代表一个月天数最多 31 天 。
通过这种双维度分库表方式,解决了DB单表数据量膨胀导致性能下降的问题,保障了系统性能的稳定性 。同时,在热冷分离的问题上,又使得数据搬迁变得简单而优雅 。
综上所述,微信红包系统在解决高并发问题上的设计,主要采用了SET化分治、请求排队、双维度分库表等方案,使得单组DB的并发性能 提升了8倍 左右,取得了很好的效果 。
http://www.infoq.com/cn/articles/2017hongbao-weixin
Redis 秒杀系统的设计与实现 还记得刚工作那会,每每听到大牛们聊技术,各种专业术语,巴拉巴拉的,简直像是在听天书,比如什么中间件、分布式、SOA、无状态、热更新、懒加载、ACID、LVS、LDAP、VIP、CDN、负载均衡、鲁棒性、POJO、DSL、DI、IOC,太多太多了 。一转眼快 10 年过去了,当很多新人再问到我这些名词的时候,我就在想,能不能用通俗易懂的大白话,就能聊明白这些专业的技术知识呢?
最近,给几个公司做技术咨询,经常会聊到秒杀系统 。所以,借这次机会,尝试用大白话和大家聊聊 Redis 秒杀系统的设计与实现,。
说起 “秒杀”,我相信大家肯定都耳熟能详了,双十一零点抢购、手机整点抢购、抢火车票、1 元秒杀、抢红包等等,都可以说是秒杀的各种应用场景了 。
秒杀系统的设计,难就难在,在极短的时间内,应对瞬时涌入平时成百上千倍的巨大流量,还包括各种攻击刷量作弊等未知流量,最终我们要保证在用户体验顺畅良好的情况下,不能多卖或者少卖 。
而当我们公司决定要做秒杀系统的时候,我就去找业务,到时大概会有多少 UV,不知道 10 倍或者 100 倍?然后去找老板,给技术多少预算,最多平时的 10 倍不能再多了,当然越少越好,呵呵,也就是说让我们用平时最多 10 倍的预算去解决不可预估的用户流量,怎么做?要是有钱直接扔 1 万台服务器跑去吧,钱能解决的事就不是事,但问题是现在还没那么多钱,还要把事情搞定 。
在聊秒杀系统设计之前,让我们先回到现实生活中,聊聊常见的“秒杀”场景和秒杀场景的独有特点,以及它们都是怎么应对的,在应对过程中都需要注意什么 。
日常生活中,其实也有很多秒杀场景,比如,早上 9 点超市开门,老大爷老大妈抢购蔬菜水果,是不是? 还有,新楼盘开盘抢购,是不是? 股市开盘、交易所现场,是不是?
对的,生活中其实有太多类似场景了,你有没有发现“秒杀”的独有特点呢?
记住了上面三个特点,我们就可以区分和确定秒杀的业务场景了 。这里我举一个特别的例子,你说挤公交车,算不算秒杀场景呢?
下面,我再和大家聊一个关于抢猪肉的故事 。
在保安部门充分讨论之后,保安大队长决定通过以下安排,在保证人员安全的前提下,还要做到相对公平 。
后来,活动井然有序的开始了,但是由于猪肉销售场地太远,销售窗口又少,老大爷和老大妈们买肉又精挑细选,导致整个过程很漫长,而且外面等候的人们都开始骚动起来,这个时候保安大队长赶紧找到经理:
故事讲完了,如果我们把上面的故事,理解为秒杀业务场景,我们就可以总结出一个 秒杀系统的设计原则 了:
淘宝运营计划书怎么写应该是刚接触这一行吧,运营计划很多,有每日计划、周计划、月计划、季度计划、年计划,看你要写的是什么了 。日计划就是每天的详细工作情况;周计划就是一个周的,可以适当加大目标,然后下个周调整;月计划更大些,目标放长远;季度和年计划在此基础上增加 。给你几点思路 。
1、对产品的认知、一个运营,需要认识产品,并且不仅仅是自己的产品,竞争对手的产品也要去熟悉、多看人家的详情、卖点、文案、标题、买家评价这些东西,自己挖掘优劣,然后回头优化自己的产品 。
2、稳定的流量,淘宝卖东西,流量为王,不管是钻展、直通车、淘宝客还是老客户、或者其他手段,你都要让你的店铺流量保持平稳然后增长,不然没有起色 。
3、看得见并且能操作可实现的未来,比如你现在店铺月成交额是50万,计划中下月成交额到70万,那么这多出来的20万在什么地方,是流量的提升,还是转化率增加,或者是客单价的提高,通过什么方法和手段来达到这个效果,要怎么样操作,你都要详细的罗列好 。
4、和公司的协同效应,一个运营,你再牛,没有客服的积极响应、没有发货的及时送出、没有库存的支撑、没有老板的资金支持,一切都是空谈,要保证KPI,就得保证整个公司协同起来,你要学会掌控这一切,也可以写入计划中 。
5、强有力的操作手段,不管你是钻展,直通车还是淘宝客、或者试客等,你接手了一个店铺,就要带来实际的效果,不然老板花钱请你干嘛 。所以你要有自己的手段和能力,保证公司在自己的运营下至少稳定发展 。
下班了,就打这些吧,欢迎交流 。
高并发,你真的理解透彻了吗?
高并发,几乎是每个程序员都想拥有的经验 。原因很简单:随着流量变大,会遇到各种各样的技术问题,比如接口响应超时、CPU load升高、GC频繁、死锁、大数据量存储等等,这些问题能推动我们在技术深度上不断精进 。
在过往的面试中,如果候选人做过高并发的项目,我通常会让对方谈谈对于高并发的理解,但是能系统性地回答好此问题的人并不多 。
大概分成这样几类:
1、对数据化的指标没有概念 :不清楚选择什么样的指标来衡量高并发系统?分不清并发量和QPS,甚至不知道自己系统的总用户量、活跃用户量,平峰和高峰时的QPS和TPS等关键数据 。
3、理解片面,把高并发设计等同于性能优化 :大谈并发编程、多级缓存、异步化、水平扩容,却忽视高可用设计、服务治理和运维保障 。
4、掌握大方案,却忽视最基本的东西 :能讲清楚垂直分层、水平分区、缓存等大思路,却没意识去分析数据结构是否合理,算法是否高效,没想过从最根本的IO和计算两个维度去做细节优化 。
这篇文章,我想结合自己的高并发项目经验,系统性地总结下高并发需要掌握的知识和实践思路,希望对你有所帮助 。内容分成以下3个部分:
高并发意味着大流量,需要运用技术手段抵抗流量的冲击,这些手段好比操作流量,能让流量更平稳地被系统所处理,带给用户更好的体验 。
我们常见的高并发场景有:淘宝的双11、春运时的抢票、微博大V的热点新闻等 。除了这些典型事情,每秒几十万请求的秒杀系统、每天千万级的订单系统、每天亿级日活的信息流系统等,都可以归为高并发 。
很显然,上面谈到的高并发场景,并发量各不相同,那到底多大并发才算高并发呢?
1、不能只看数字,要看具体的业务场景 。不能说10W QPS的秒杀是高并发,而1W QPS的信息流就不是高并发 。信息流场景涉及复杂的推荐模型和各种人工策略,它的业务逻辑可能比秒杀场景复杂10倍不止 。因此,不在同一个维度,没有任何比较意义 。
2、业务都是从0到1做起来的,并发量和QPS只是参考指标,最重要的是:在业务量逐渐变成原来的10倍、100倍的过程中,你是否用到了高并发的处理方法去演进你的系统,从架构设计、编码实现、甚至产品方案等维度去预防和解决高并发引起的问题?而不是一味的升级硬件、加机器做水平扩展 。
此外,各个高并发场景的业务特点完全不同:有读多写少的信息流场景、有读多写多的交易场景,那是否有通用的技术方案解决不同场景的高并发问题呢?
我觉得大的思路可以借鉴,别人的方案也可以参考,但是真正落地过程中,细节上还会有无数的坑 。另外,由于软硬件环境、技术栈、以及产品逻辑都没法做到完全一致,这些都会导致同样的业务场景,就算用相同的技术方案也会面临不同的问题,这些坑还得一个个趟 。
因此,这篇文章我会将重点放在基础知识、通用思路、和我曾经实践过的有效经验上,希望让你对高并发有更深的理解 。
先搞清楚高并发系统设计的目标,在此基础上再讨论设计方案和实践经验才有意义和针对性 。
高并发绝不意味着只追求高性能,这是很多人片面的理解 。从宏观角度看,高并发系统设计的目标有三个:高性能、高可用,以及高可扩展 。
1、高性能:性能体现了系统的并行处理能力,在有限的硬件投入下,提高性能意味着节省成本 。同时,性能也反映了用户体验,响应时间分别是100毫秒和1秒,给用户的感受是完全不同的 。
2、高可用:表示系统可以正常服务的时间 。一个全年不停机、无故障;另一个隔三差五出线上事故、宕机,用户肯定选择前者 。另外,如果系统只能做到90%可用,也会大大拖累业务 。
3、高扩展:表示系统的扩展能力,流量高峰时能否在短时间内完成扩容,更平稳地承接峰值流量,比如双11活动、明星离婚等热点事件 。
这3个目标是需要通盘考虑的,因为它们互相关联、甚至也会相互影响 。
比如说:考虑系统的扩展能力,你会将服务设计成无状态的,这种集群设计保证了高扩展性,其实也间接提升了系统的性能和可用性 。
再比如说:为了保证可用性,通常会对服务接口进行超时设置,以防大量线程阻塞在慢请求上造成系统雪崩,那超时时间设置成多少合理呢?一般,我们会参考依赖服务的性能表现进行设置 。
再从微观角度来看,高性能、高可用和高扩展又有哪些具体的指标来衡量?为什么会选择这些指标呢?
2.2.1 性能指标
通过性能指标可以度量目前存在的性能问题,同时作为性能优化的评估依据 。一般来说,会采用一段时间内的接口响应时间作为指标 。
1、平均响应时间:最常用,但是缺陷很明显,对于慢请求不敏感 。比如1万次请求,其中9900次是1ms,100次是100ms,则平均响应时间为1.99ms,虽然平均耗时仅增加了0.99ms,但是1%请求的响应时间已经增加了100倍 。
2、TP90、TP99等分位值:将响应时间按照从小到大排序,TP90表示排在第90分位的响应时间,分位值越大,对慢请求越敏感 。
3、吞吐量:和响应时间呈反比,比如响应时间是1ms,则吞吐量为每秒1000次 。
通常,设定性能目标时会兼顾吞吐量和响应时间,比如这样表述:在每秒1万次请求下,AVG控制在50ms以下,TP99控制在100ms以下 。对于高并发系统,AVG和TP分位值必须同时要考虑 。
另外,从用户体验角度来看,200毫秒被认为是第一个分界点,用户感觉不到延迟,1秒是第二个分界点,用户能感受到延迟,但是可以接受 。
因此,对于一个 健康 的高并发系统,TP99应该控制在200毫秒以内,TP999或者TP9999应该控制在1秒以内 。
2.2.2 可用性指标
高可用性是指系统具有较高的无故障运行能力,可用性 = 正常运行时间 / 系统总运行时间,一般使用几个9来描述系统的可用性 。
对于高并发系统来说,最基本的要求是:保证3个9或者4个9 。原因很简单,如果你只能做到2个9,意味着有1%的故障时间,像一些大公司每年动辄千亿以上的GMV或者收入,1%就是10亿级别的业务影响 。
2.2.3 可扩展性指标
面对突发流量,不可能临时改造架构,最快的方式就是增加机器来线性提高系统的处理能力 。
对于业务集群或者基础组件来说,扩展性 = 性能提升比例 / 机器增加比例,理想的扩展能力是:资源增加几倍,性能提升几倍 。通常来说,扩展能力要维持在70%以上 。
但是从高并发系统的整体架构角度来看,扩展的目标不仅仅是把服务设计成无状态就行了,因为当流量增加10倍,业务服务可以快速扩容10倍,但是数据库可能就成为了新的瓶颈 。
像MySQL这种有状态的存储服务通常是扩展的技术难点,如果架构上没提前做好规划(垂直和水平拆分),就会涉及到大量数据的迁移 。
因此,高扩展性需要考虑:服务集群、数据库、缓存和消息队列等中间件、负载均衡、带宽、依赖的第三方等,当并发达到某一个量级后,上述每个因素都可能成为扩展的瓶颈点 。
了解了高并发设计的3大目标后,再系统性总结下高并发的设计方案,会从以下两部分展开:先总结下通用的设计方法,然后再围绕高性能、高可用、高扩展分别给出具体的实践方案 。
通用的设计方法主要是从「纵向」和「横向」两个维度出发,俗称高并发处理的两板斧:纵向扩展和横向扩展 。
3.1.1 纵向扩展(scale-up)
它的目标是提升单机的处理能力,方案又包括:
1、提升单机的硬件性能:通过增加内存、 CPU核数、存储容量、或者将磁盘 升级成SSD 等堆硬件的方式来提升 。
2、提升单机的软件性能:使用缓存减少IO次数,使用并发或者异步的方式增加吞吐量 。
3.1.2 横向扩展(scale-out)
因为单机性能总会存在极限,所以最终还需要引入横向扩展,通过集群部署以进一步提高并发处理能力,又包括以下2个方向:
1、做好分层架构:这是横向扩展的提前,因为高并发系统往往业务复杂,通过分层处理可以简化复杂问题,更容易做到横向扩展 。
上面这种图是互联网最常见的分层架构,当然真实的高并发系统架构会在此基础上进一步完善 。比如会做动静分离并引入CDN,反向代理层可以是LVS+Nginx,Web层可以是统一的API网关,业务服务层可进一步按垂直业务做微服务化,存储层可以是各种异构数据库 。
2、各层进行水平扩展:无状态水平扩容,有状态做分片路由 。业务集群通常能设计成无状态的,而数据库和缓存往往是有状态的,因此需要设计分区键做好存储分片,当然也可以通过主从同步、读写分离的方案提升读性能 。
下面再结合我的个人经验,针对高性能、高可用、高扩展3个方面,总结下可落地的实践方案 。
3.2.1 高性能的实践方案
1、集群部署,通过负载均衡减轻单机压力 。
2、多级缓存,包括静态数据使用CDN、本地缓存、分布式缓存等,以及对缓存场景中的热点key、缓存穿透、缓存并发、数据一致性等问题的处理 。
3、分库分表和索引优化,以及借助搜索引擎解决复杂查询问题 。
4、考虑NoSQL数据库的使用,比如HBase、TiDB等,但是团队必须熟悉这些组件,且有较强的运维能力 。
5、异步化,将次要流程通过多线程、MQ、甚至延时任务进行异步处理 。
6、限流,需要先考虑业务是否允许限流(比如秒杀场景是允许的),包括前端限流、Nginx接入层的限流、服务端的限流 。
7、对流量进行 削峰填谷,通过 MQ承接流量 。
8、并发处理,通过多线程将串行逻辑并行化 。
9、预计算,比如抢红包场景,可以提前计算好红包金额缓存起来,发红包时直接使用即可 。
10、 缓存预热,通过异步 任务 提前 预热数据到本地缓存或者分布式缓存中 。
11、减少IO次数,比如数据库和缓存的批量读写、RPC的批量接口支持、或者通过冗余数据的方式干掉RPC调用 。
12、减少IO时的数据包大小,包括采用轻量级的通信协议、合适的数据结构、去掉接口中的多余字段、减少缓存key的大小、压缩缓存value等 。
13、程序逻辑优化,比如将大概率阻断执行流程的判断逻辑前置、For循环的计算逻辑优化,或者采用更高效的算法 。
14、各种池化技术的使用和池大小的设置,包括HTTP请求池、线程池(考虑CPU密集型还是IO密集型设置核心参数)、数据库和Redis连接池等 。
15、JVM优化,包括新生代和老年代的大小、GC算法的选择等,尽可能减少GC频率和耗时 。
16、锁选择,读多写少的场景用乐观锁,或者考虑通过分段锁的方式减少锁冲突 。
上述方案无外乎从计算和 IO 两个维度考虑所有可能的优化点,需要有配套的监控系统实时了解当前的性能表现,并支撑你进行性能瓶颈分析,然后再遵循二八原则,抓主要矛盾进行优化 。
3.2.2 高可用的实践方案
1、对等节点的故障转移,Nginx和服务治理框架均支持一个节点失败后访问另一个节点 。
2、非对等节点的故障转移,通过心跳检测并实施主备切换(比如redis的哨兵模式或者集群模式、MySQL的主从切换等) 。
3、接口层面的超时设置、重试策略和幂等设计 。
4、降级处理:保证核心服务,牺牲非核心服务,必要时进行熔断;或者核心链路出问题时,有备选链路 。
5、限流处理:对超过系统处理能力的请求直接拒绝或者返回错误码 。
6、MQ场景的消息可靠性保证,包括producer端的重试机制、broker侧的持久化、consumer端的ack机制等 。
7、灰度发布,能支持按机器维度进行小流量部署,观察系统日志和业务指标,等运行平稳后再推全量 。
8、监控报警:全方位的监控体系,包括最基础的CPU、内存、磁盘、网络的监控,以及Web服务器、JVM、数据库、各类中间件的监控和业务指标的监控 。
9、灾备演练:类似当前的“混沌工程”,对系统进行一些破坏性手段,观察局部故障是否会引起可用性问题 。
高可用的方案主要从冗余、取舍、系统运维3个方向考虑,同时需要有配套的值班机制和故障处理流程,当出现线上问题时,可及时跟进处理 。
3.2.3 高扩展的实践方案
1、合理的分层架构:比如上面谈到的互联网最常见的分层架构,另外还能进一步按照数据访问层、业务逻辑层对微服务做更细粒度的分层(但是需要评估性能,会存在网络多一跳的情况) 。
2、存储层的拆分:按照业务维度做垂直拆分、按照数据特征维度进一步做水平拆分(分库分表) 。
3、业务层的拆分:最常见的是按照业务维度拆(比如电商场景的商品服务、订单服务等),也可以按照核心接口和非核心接口拆,还可以按照请求源拆(比如To C和To B,APP和H5 ) 。
高并发确实是一个复杂且系统性的问题,由于篇幅有限,诸如分布式Trace、全链路压测、柔性事务都是要考虑的技术点 。另外,如果业务场景不同,高并发的落地方案也会存在差异,但是总体的设计思路和可借鉴的方案基本类似 。
高并发设计同样要秉承架构设计的3个原则:简单、合适和演进 。"过早的优化是万恶之源",不能脱离业务的实际情况,更不要过度设计,合适的方案就是最完美的 。
作者简介:985硕士,前亚马逊工程师,现大厂技术管理者 。
【官方出品!揭秘阿里巴巴APP 8.0 视觉品牌升级背后的设计思路 京东抢购秒杀软件】关于秒杀系统设计思路和京东抢购秒杀软件的内容就分享到这儿!更多实用知识经验,尽在 www.hubeilong.com