电商那些年,我摸爬打滚出的高并发架构实战精髓

一、关于高并发

 

高并发是指在同一个时间点,有很多用户同时访问URL地址,比如:淘宝的双11、双12,就会产生高并发。又如贴吧的爆吧,就是恶意的高并发请求,也就是DDOS攻击,再屌丝点的说法就像玩LOL被ADC暴击了一样,那伤害你懂的。

 

1 高并发会来带的后果
 

  • 服务端:导致站点服务器/DB服务器资源被占满崩溃,数据的存储和更新结果和理想的设计是不一样的,比如:出现重复的数据记录,多次添加了用户积分等。
  • 用户角度:尼玛,这么卡,老子来参加活动的,刷新了还是这样,垃圾网站,再也不来了!
  • 我的经历:在做公司产品网站的过程中,经常会有这样的需求,比如搞个活动专题、抽奖、签到、积分竞拍等等,如果没有考虑到高并发下的数据处理,那就Game Over了,很容易导致抽奖被多抽走,签到发现一个用户有多条记录等等,各种超出正常逻辑的现象,这就是做产品网站必须考虑的问题,因为这些都是面向大量用户的,而不是像做ERP管理系统、OA系统那样,只是面向员工。

 

下面我进行实例分析,简单粗暴,动态分析,纯属本人经验分享,如有说错或者更好的建议,请留言,大家一起成长。

 

2 并发下的数据处理
 

通过表设计,如:记录表添加唯一约束,数据处理逻辑使用事物防止并发下的数据错乱问题。通过服务端锁进程防止包并发下的数据错乱问题。这里主要讲述的是在并发请求下的数据逻辑处理的接口,如何保证数据的一致性和完整性,这里的并发可能是大量用户发起的,也可能攻击者通过并发工具发起的并发请求。

 

例子1:通过表设计防止并发导致数据错乱
 

  • 需求点:

    【签到功能】一天一个用户只能签到一次,签到成功后用户获取到一个积分。

  • 已知表:

    1、用户表,包含积分字段;

    2、高并发意淫分析(属于开发前的猜测): 在高并发的情况下,会导致一个用户签到记录会有多条,或者用户签到后不止加一积分。

  • 我的设计:首先根据需求我会添加一张签到记录表,重点来了,这张表需要把用户唯一标识字段(ID,Token)和签到日期字段添加为唯一约束,或者唯一索引,这样就可以防止并发的时候插入重复用户的签到记录。然后再程序代码逻辑里,先执行签到数据的添加(这里可以防止并发,添加成功后再进行积分的添加,这样就可以防止重复地添加积分了。最后我还是建议所有的数据操作都写在一个sql事务里面, 这样在添加失败,或者编辑用户积分失败的时候可以回滚数据。

 

例子2:事务+通过更新锁,防止并发导致数据错乱;或者事物+Update的锁表机制

 

  • 需求点:【抽奖功能】抽奖一次消耗一个积分,抽奖中奖后编辑剩余奖品总数,剩余奖品总数为0,或者用户积分为0的时候无法进行抽奖。
  • 已知表:用户表,包含积分字段 奖品表,包含奖品剩余数量字段。
  • 高并发意淫分析(属于开发前的猜测):在高并发的情况下,会导致用户参与抽奖的时候积分被扣除,而奖品实际上已经被抽完了。
  • 我的设计:在事物里,通过WITH(UPDLOCK)锁住商品表,或者Update 表的奖品剩余数量和最后编辑时间字段,来把数据行锁住,然后进行用户积分的消耗,都完成后提交事物,失败就回滚。 这样就可以保证,只有可能存在一个操作在操作这件商品的数量,只有等到这个操作事物提交后,其他的操作这个商品行的事物才会继续执行。

 

例子3:通过程序代码防止包并发下的数据错乱问题
 

  • 需求点:【缓存数据到cache里】,当缓存不存在的时候,从数据库中获取并保存在cache里,如果存在从cache里获取,每天10点必须更新一次,其他时间点缓存两个小时更新一次 到10点的时候,凡是打开页面的用户会自动刷新页面。
  • 问题点:这里有个逻辑用户触发缓存的更新,用户刷新页面,当缓存存在的时候,会取到最后一次缓存更新时间,如果当前时间大于十点,并且最后缓存时间是10点前,则会从数据库中重新获取数据保存到cache中。 还有客户端页面会在10点时候用js发起页面的刷新,就是因为有这样的逻辑,导致10点的时候有很多并发请求同时过来,然后就会导致很多的sql查询操作,理想的逻辑是,只有一个请求会去数据库获取,其他都是从缓存中获取数据。(因为这个sql查询很耗服务器性能,所以导致在10点的时候,突然间数据库服务器压力暴增)
  • 解决问题:C#通过(锁)lock,在从数据读取到缓存的那段代码前面加上锁,这样在并发的情况下只会有一个请求是从数据库里获取数据,其他都是从缓存中获取。

 

3 访问量大的数据统计接口
 

  • 需求: 用户行为数据统计接口,用来记录商品展示次数,用户通过点击图片,或者链接,或者其他方式进入到商品详情的行为次数。
  • 问题点:这接口是给前端ajax使用,访问量会很大,一页面展示的时候就会有几十件商品的展示,滚动条滚到到页面显示商品的时候就会请求接口进行展示数据的统计,每次翻页又会加载几十件。
  • 意淫分析:设想如果同时有1W个用户同时在线访问页面,一个次拉动滚动条屏幕页面展示10件商品,这样就会有10W个请求过来,服务端需要把请求数据入库。在实际线上环境可能还会超过这个请求量,如果不经过进行高并发设计处理,服务器分分钟给跪了。
  • 解决问题:我们通过nodejs写了一个数据处理接口,把统计数据先存到redis的list里。(使用nodejs写接口的好处是,nodejs使用单线程异步事件机制,高并发处理能力强,不会因为数据逻辑处理问题导致服务器资源被占用而导致服务器宕机) 然后再使用nodejs写了一个脚本,脚本功能就是从redis里出列数据保存到mysql数据库中。这个脚本会一直运行,当redis没有数据需要同步到数据库中的时候,sleep,让在进行数据同步操作。

 

4 高并发的下的服务器压力均衡,合理站点架设,DB部署
 

以下我所知道的:

 

  1. 服务器代理nginx,做服务器的均衡负载,把压力均衡到多台服务器;
  2. 部署集群MySQL数据库, Redis服务器,或者MongoDB服务器,把一些常用的查询数据,并且不会经常的变化的数据保存到其他NoSQL DB服务器中,来减少数据库服务器的压力,加快数据的响应速度;
  3. 数据缓存,Cache;
  4. 在高并发接口的设计中可以使用具有高并发能力的编程语言去开发,如:nodejs做web接口;
  5. 服务器部署,图片服务器分离,静态文件走CDN;
  6. DBA数据库的优化查询条件,索引优化;
  7. 消息存储机制,将数据添加到信息队列中(redis list),然后再写工具去入库
  8. 脚本合理控制请求,如,防止用户重复点击导致的ajax多余的请求,等等。

 

5 并发测试神器推荐
 

  1. Apache JMeter
  2. Microsoft Web Application Stress Tool
  3. Visual Studio 性能负载

 

二、关于高并发架构

 

为了让业务可以流畅地运行并且给用户一个好的交互体验,我们需要根据业务场景预估达到的并发量等因素,来设计适合自己业务场景的高并发处理方案。

 

在电商相关产品开发的这些年,我有幸遇到了并发下的各种坑,这一路摸爬滚打过来有着不少的血泪史,这里进行总结,作为自己的归档记录,同时分享给大家。

 

1 服务器架构
 

业务从发展的初期到逐渐成熟,服务器架构也是从相对单一到集群,再到分布式服务。 

一个可以支持高并发的服务少不了好的服务器架构,需要有均衡负载,数据库需要主从集群,NoSQL缓存需要主从集群,静态文件需要上传CDN,这些都是能让业务程序流畅运行的强大后盾。

 

服务器这块多是需要运维人员来配合搭建,具体我就不多说了,点到为止。

大致需要用到的服务器架构如下:

 

服务器:

  • 均衡负载(如:nginx,阿里云SLB)
  • 资源监控
  • 分布式

 

数据库:

  • 主从分离,集群
  • DBA 表优化,索引优化,等
  • 分布式

 

NoSQL:

  • Redis

    主从分离,集群

  • MongoDB

    主从分离,集群

  • memcache

    主从分离,集群

 

CDN:

  • html
  • css
  • js
  • image

 

2 并发测试
 

高并发相关的业务,需要进行并发的测试,通过大量的数据分析评估出整个架构可以支撑的并发量。

 

测试高并发可以使用第三方服务器或者自己测试服务器,利用测试工具进行并发请求测试,分析测试数据得到可以支撑并发数量的评估,这个可以作为一个预警参考,俗话说知己自彼百战不殆。

 

第三方服务:

  • 阿里云性能测试

 

并发测试工具:

  • Apache JMeter
  • Visual Studio性能负载测试
  • Microsoft Web Application Stress Tool

 

3 实战方案
 

1)通用方案

 

日用户流量大,但是比较分散,偶尔会有用户高聚的情况;
 

场景: 用户签到,用户中心,用户订单等。

服务器架构图: 

 

说明:

场景中的这些业务基本是用户进入APP后会操作到的,除了活动日(618、双11等),这些业务的用户量都不会高聚集,同时这些业务相关的表都是大数据表,业务多是查询操作,所以我们需要减少用户直接命中DB的查询;优先查询缓存,如果缓存不存在,再进行DB查询,将查询结果缓存起来。

 

更新用户相关缓存需要分布式存储,比如使用用户ID进行hash分组,把用户分布到不同的缓存中,这样一个缓存集合的总量不会很大,不会影响查询效率。

方案如:

 

用户签到获取积分:

  • 计算出用户分布的key,Redis,hash中查找用户今日签到信息
  • 如果查询到签到信息,返回签到信息
  • 如果没有查询到,DB查询今日是否签到过,如果有签到过,就把签到信息同步Redis缓存。
  • 如果DB中也没有查询到今日的签到记录,就进行签到逻辑,操作DB添加今日签到记录,添加签到积分(这整个DB操作是一个事务)
  • 缓存签到信息到Redis,返回签到信息
  • 注意这里会有并发情况下的逻辑问题,如:一天签到多次,发放多次积分给用户。

 

用户订单:

  • 这里我们只缓存用户第一页的订单信息,一页40条数据,用户一般也只会看第一页的订单数据
  • 用户访问订单列表,如果是第一页读缓存,如果不是读DB
  • 计算出用户分布的key,Redis,hash中查找用户订单信息
  • 如果查询到用户订单信息,返回订单信息
  • 如果不存在就进行DB查询第一页的订单数据,然后缓存redis,返回订单信息

 

 

用户中心:

  • 计算出用户分布的key,Redis hash中查找用户订单信息
  • 如果查询到用户信息,返回用户信息
  • 如果不存在进行用户DB查询,然后缓存redis,返回用户信息

 

其他业务:

  • 上面例子多是针对用户存储缓存,如果是公用的缓存数据需要注意一些问题,如:公用的缓存数据需要考虑并发下的可能会导致大量命中DB查询,可以使用管理后台更新缓存,或者DB查询的锁住操作。

 

以上例子是一个相对简单的高并发架构,并发量不是很高的情况可以很好的支撑,但是随着业务的壮大,用户并发量增加,我们的架构也会进行不断的优化和演变,比如对业务进行服务化,每个服务有自己的并发架构,自己的均衡服务器,分布式数据库,NoSQL主从集群,如:用户服务、订单服务。

 

2)消息队列

 

秒杀、秒抢等活动业务,用户在瞬间涌入产生高并发请求。
 

场景:定时领取红包等。

服务器架构图:

说明:

  • 场景中的定时领取是一个高并发的业务,像秒杀活动用户会在到点的时间涌入,DB瞬间就接受到一记暴击,hold不住就会宕机,然后影响整个业务;
  • 像这种不是只有查询的操作并且会有高并发的插入或者更新数据的业务,前面提到的通用方案就无法支撑,并发的时候都是直接命中DB;
  • 设计这块业务的时候就会使用消息队列的,可以将参与用户的信息添加到消息队列中,然后再写个多线程程序去消耗队列,给队列中的用户发放红包;

 

方案如:

  • 定时领取红包;
  • 一般习惯使用 redis的 list;
  • 当用户参与活动,将用户参与信息push到队列中;
  • 然后写个多线程程序去pop数据,进行发放红包的业务;
  • 这样可以支持高并发下的用户可以正常的参与活动,并且避免数据库服务器宕机的危险。

 

附加: 通过消息队列可以做很多的服务。 

如:定时短信发送服务,使用sset(sorted set),发送时间戳作为排序依据,短信数据队列根据时间升序,然后写个程序定时循环去读取sset队列中的第一条,当前时间是否超过发送时间,如果超过就进行短信发送。

 

3)一级缓存

 

高并发请求连接缓存服务器超出服务器能够接收的请求连接量,部分用户出现建立连接超时无法读取到数据的问题;

 

因此需要有个方案当高并发时候时候可以减少命中缓存服务器;

 

这时候就出现了一级缓存的方案,一级缓存就是使用站点服务器缓存去存储数据,注意只存储部分请求量大的数据,并且缓存的数据量要控制,不能过分的使用站点服务器的内存而影响了站点应用程序的正常运行,一级缓存需要设置秒单位的过期时间,具体时间根据业务场景设定,目的是当有高并发请求的时候可以让数据的获取命中到一级缓存,而不用连接缓存NoSQL数据服务器,减少NoSQL数据服务器的压力。

 

比如APP首屏商品数据接口,这些数据是公共的不会针对用户自定义,而且这些数据不会频繁的更新,像这种接口的请求量比较大就可以加入一级缓存;

 

服务器架构图:

 

合理地规范和使用NoSQL缓存数据库,根据业务拆分缓存数据库的集群,这样基本可以很好支持业务,一级缓存毕竟是使用站点服务器缓存所以还是要善用。

 

4)静态化数据

 

高并发请求数据不变化的情况下如果可以不请求自己的服务器获取数据那就可以减少服务器的资源压力。

 

对于更新频繁度不高,并且数据允许短时间内的延迟,可以通过数据静态化成JSON、XML、HTML等数据文件上传CDN,在拉取数据的时候优先到CDN拉取,如果没有获取到数据再从缓存,数据库中获取,当管理人员操作后台编辑数据再重新生成静态文件上传同步到CDN,这样在高并发的时候可以使数据的获取命中在CDN服务器上。

 

CDN节点同步有一定的延迟性,所以找一个靠谱的CDN服务器商也很重要。

 

5)其他方案

 

对于更新频繁度不高的数据,APP、PC浏览器,可以缓存数据到本地,然后每次请求接口的时候上传当前缓存数据的版本号,服务端接收到版本号判断版本号与最新数据版本号是否一致,如果不一样就进行最新数据的查询并返回最新数据和最新版本号,如果一样就返回状态码告知数据已经是最新。减少服务器压力:资源、带宽。


时间: 2024-10-26 13:47:03

电商那些年,我摸爬打滚出的高并发架构实战精髓的相关文章

腾讯的电商大平台策略也日渐浮出水面

每日经济新闻记者 谢晓萍 蒋佩芳发自北京.上海 在将电子商务独立后,腾讯的电商大平台策略也日渐浮出水面. 昨日 (6月12日),<每日经济新闻>记者获悉,当当网与分拆不久的腾讯电商正式达成合作,由当当网独家运营腾讯电商旗下QQ网购的图书.母婴业务,全面进行站外合作. 随后,记者从当当网.腾讯电商处证实了上述消息.据知情人士透露,双方将于本周正式对外公布此消息,根据合作细节,图书频道将于6月中旬上线,而母婴频道拟7月~8月份正式上线. 同时,腾讯将再次投入5亿元的营销资源,展开为期三天的QQ网购

电商到底怎么了,疯狂的背后映衬出了什么

京东.苏宁国美先后放出狠话要让价格一降到底,让不少消费者在期待的同时,也产生了疑问,电商到底怎么了,疯狂的背后映衬出了什么? 这两天,京东商城.苏宁易购.国美网上商城,三大国内电器商在网上展开了一场激烈的电器价格战,17日上午,乌鲁木齐市国美.苏宁实物店也紧跟其后,开启了电器大促销活动.电视.冰箱.洗衣机是这次促销的重头产品,打出了全疆最低价,差价双倍返还的标语. 乌鲁木齐市国美大十字分店店长 郝爽爽:"在9月20号之前如果顾客在我们商场买的商品,有其他卖场比我们便宜的情况下,我们会双倍返还差价

社区和电商嫁接仍在“摸石头”

中介交易 SEO诊断 淘宝客 云主机 技术大厅 在微信的朋友圈适合扩散哪些信息呢?原创或转贴一篇<23种酱的做法>,或者别的什么.如果你想在这里做点儿买卖,多多少少会冒出跳蚤市场的感觉,--亲爱的邻居,我有一把用了两年仍然几乎全新的锅铲,不锈钢的!只要5块钱!--很有爱,但是非典型. 所以不要急于帮助京东和腾讯设计商业模式,可以先把镜头拉远一点,看看嫁接在社区上的电商,在消费者市场反馈如何. 按照评论家们的光荣传统,谈社区言必称Facebook,我们一起看看Facebook的电商实验.2009

电商总结(四)基于共享存储的图片服务器架构

在当前这个互联网的时代,不管何种网站,对图片的需求量越来越大,尤其在电商网站中,几乎都会面临到海量图片资源的存储.访问等相关技术问题.在对图片服务器的架构,扩展,升级的过程中,肯定也会碰到各种各样的问题,各种各样的需求.当然这并不代表,就必须得弄一个特别NB的图片服务架构,简单,高效,稳定就行.所以今天就来总结一个特别简单,高效的图片服务架构:通过共享存储的方式来实现图片服务架构.   然而,也有一些人问我,现在大型网站的图片服务器的架构已经完全不是这样的了,别人家的图片系统,比你这个牛逼多了,

顶级VC:电商、游戏、O2O三领域将现高估值公司

8月12日下午消息,2014年Techcrunch国际创新峰会在京举办.在会上,GGV资本.红杉资本和IDG资本等风险投资人探讨了中美资本市场,将出现高估值公司的所在行业,以及创业公司的机会.IDG资本合伙人李丰认为,未来出现百亿美金高估值的公司将存在于三个行业:第一是涉及商品和服务的交易市场,即买卖商品的标准化电商网站;第二是娱乐虚拟化应用,比如游戏.视频等;第三是O2O是个性化的服务市场.这三个行业将依次出现高成长型高估值公司.上述三个行业的机会和潜力已经得到市场和投资人的认可,比如步入规模

奢侈品电商寺库获总规模超1亿美元高融资

摘要: 以尊享网为代表的奢侈品电商纷纷宣布破产之际,另一奢侈品电商寺库昨天却宣布,公司已完成总规模超过1亿美元的新一轮融资,为中国奢侈品及高端时尚电商领域获得的最大规模融资 以尊享网为代表的奢侈品电商纷纷宣布破产之际,另一奢侈品电商寺库昨天却宣布,公司已完成总规模超过1亿美元的新一轮融资,为中国奢侈品及高端时尚电商领域获得的最大规模融资. 此轮融资是寺库的D轮融资,由黎瑞刚创办并担任董事长的华人文化投资基金(简称CMC)领投,IDG资本.法国风投VentechChina(银泰资本).森合投资.盘

价格战背后电商劫:2012年超20位行业高管离职

每日经济新闻(博客,微博)记者 陶力 发自上海 经过此前的一涌而上,2012年的电商业步入"大鱼吃小鱼.快鱼踢慢鱼"的整合期,而整合的主要手段就是以资本实力为后盾的价格战. 在这波整合潮中,有胜者,也有落寞者,而落寞者中最引人关注的就是离职的电商高管.据<每日经济新闻>记者粗略统计,今年离职的电商高管人数已经超过20位,电商行业内部正经历着风起云涌的变革. 业绩与资本的双重压力 2012年,尽管电子商务投资热情不减,但大部分企业仍在赔本赚吆喝,迟迟无法改变亏损的困局.白热化

探秘电商秒杀抢购背后的 IT 架构

一年一度的双 11 购物节又要来了,剁手党们是否已经做好了准备?除了每年造就无数的败家买家外,双 11 也对各大各大电商平台的服务支撑提出了更高挑战.如何保证买家在购物过程中的流畅体验十分重要,再具性价比的商品在碰到网站无法响应时也会失去吸引力.因此,在各位买家开启买买买血拼模式的同时,各大电商平台也严阵以待,为一年中最繁忙的一天提供更强有力的 IT 技术保障. 我们注意到,虽然京东.淘宝.苏宁等大型电商已经凭借自身过硬的技术实力解决了高峰期间的 IT 压力,但是更多的中小型电商面对如此大的业务

电商网站如何优化才能事半功倍

  最近接了一个电子商务网站来优化,以前也了解一些B2B网站的推广方式,SEO优化只是其中一种,电子商务网站做好SEO优化也是必要地,今天就来聊一聊电商网站怎样做优化才能够事倍功半. 一.网站结构 电子商务网站的结构设计除了要对搜索引擎友好之处,还要让用户认可,一个清淅,整洁,大方的页面出现在用户眼里,第一印象就非常好.才有继续看下去的欲望. 一个扁平式的网站结构既有利于搜索引擎访问,也有利于客户浏览,就是我们常说的树型结构.产品栏目分类一定要有针对性,有需求性,在栏目标题中含有关键词. 二.页