继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Go高并发秒杀实践

2019-08-26 12:18:0411188浏览

Cap

3实战 · 3手记 · 3推荐
TA的实战

Hello ,大家好,今天和大家分享下如何用GO来做电商高并发秒杀系统

本次分享的内容主要分为一下几个部分:

1.      秒杀基础功能介绍;

2.      秒杀基础技能准备;

3.      秒杀消息队列介绍;

4.      秒杀架构优化;

5.      秒杀前端优化;

6.      秒杀后端优化

做秒杀系统开始我们需要明确秒杀系统有哪些基础功能,我们在完成基础功能的基础上在通过逐步的分析系统压力点调整架构,让秒杀系统满足高并发需求;

一、秒杀基本功能

首先我们来从秒杀基础功能说起,主要通过基本需求的开发来掌握使用GO语言开发Web电商功能和功能开发流程。

第一步明确基本需求:订单管理,商品管理,用户登陆,商品展示和抢购这几个功能点;

第二步使用工具画出功能大体原型这里的工具课程中使用的是墨刀,就比如简单设计的登陆原型:

https://img4.mukewang.com/5d635c1f00016a3605790625.jpg

有了上面两个步骤我么就明确了秒杀基本功能和功能具体需要做成什么样子;

二、秒杀基础技能准备

1.Iris 基础使用

在开发功能之前我们对开发需要涉及的核心技能做简单介绍;

我们开发web功能通常会使用框架来简化我们的工作量,同样我们这里也是用到了框架,Go语言中的Iris 框架,下面就简单介绍下框架的是用;

Iris的是用也非常的简单,我们首先通过go get的 方式下载 代码包,代码:go get github.com/kataras/iris;

 

通过上面的go get 会自动下载iris需要依赖的包;

当我们安装完成后,只需要在我们的main.go 文件中创建iris 实例即可使用,具体如截图:

https://img1.mukewang.com/5d635c420001951208640375.jpg

上面截图中 通过三个步骤即可创建/hello 路由,我们在这基础添加我们的业务代码即可,那么如何开发我们业务代码?我的开发顺序又是什么?下面就来简单和大家分享下;

2. Iris 框架目录结构和开发顺序

我们首先来看下Iris Mvc的目录结构,如图:

https://img4.mukewang.com/5d635c660001ebd904390422.jpg

在图中我们可以看到,iris mvc的目录结构和我们平时开发的其他目录结构有许多相似的地方,

里面包括:模型(datamodels),数据库操作(repositories),服务(services),控制器(controllers),视图(views),入口(main.go)等六个方面;

我们日常的开发也是主要围绕这些目录进行的;

熟悉了目录结构我们开发下面说下开发顺序和节奏;

就拿后台商品管理功能来举例,

1.datamodels: 当我们明确功能需求后,首先要开发商品对应的模型就是在datamodel中创建模型文件;

2. repositories: 模型创建完成后,对应的数据库操作我们一般写在repositories 中,比如操作数据库增删改查;

3. services: 业务逻辑代码一般我们写在service里,比如判断ID大于10后调用插入数据库的操作;

4.controllers: 我们对外提供服务还需要创建指定路由的控制器,我在链接里面的URI路径就是在控制器里面创建的;

5.views:最后就是我们的视图渲染模版文件的开发;

主要流程总结:datamodels-> repositories-> services-> controllers-> views

基于以上流程我们就可以用Iris Mvc 开发web网站了;

三、秒杀消息队列介绍(RabbitMQ)

秒杀系统我们通常使用消息队列来保护我们的数据库,所以消息队列的地位也十分重要,下面我们就简单分享下消息队列RabbitMQ常用两种模式;

RabbitMQ 消息队列中我们经常使用到的有simple 模式,该模式的简单架构如图:

https://img1.mukewang.com/5d635c88000165c304950183.jpg

上图中P 是消息的生产端,红色部分是消息队列,C是消息的消费端,我们通过这种模式可以非常方便的解藕程序,在秒杀中用这种模式可以让访问高峰的流量进行排队处理,有效的保护数据库免被大流量拖垮;

第二个常用的消息模式是 工作模式,架构图如下:

https://img1.mukewang.com/5d635cac0001ead705970185.jpg

在上面图中我们可以看到是在simple 模式的基础上增加了多个消费者,这样能提升我们系统的处理能力,这种模式也非常常见,秒杀系统中也主要使用以上两种模式来处理消息;

当然消息队列里面还有,订阅模式,路由模式,话题模式和RPC模式有兴趣的同学可以深入研究下;

 

四、秒杀架构优化

我们基础功能开发完成后还不能满足我们高并发秒杀的要求,我们高并发秒杀一般会伴随着瞬时大流量

在这种情况下,我们系统就要对压力点进行梳理并且对每个压力点进行调整和设计,

调整的方向主要分为两个,1.提高压力点自身处理能力;2.满足每个压力点横行扩展能力,提高处理能力;

根据秒杀的特点最终优化架构图如下:

https://img1.mukewang.com/5d635cca0001c28f08560514.jpg

从上面的架构图可以看出,我们把接口验证部分独立了出来,在这部分能够实现我们的cookie验证,流量控制,速率控制,也可以添加自己的拦截逻辑;

当我们通过验证以后我们会通过SLB (负载均衡,如果性能不够可以自己用GO写个),转发请求到数量控制接口上(这里控制接口的性能可以达到30万QPS,12核12G),防止我们商品超卖;

我们主要优化和下功夫的地方也就是这这两个方面,通过了验证和请求以后,我们将通过RabbitMQ 消息队列对数据写如数据库的速率进行控制,防止流量大了爆库;

 

五、秒杀前端优化

我们商品展示的时候如果用动态的方式我们会消耗大量的服务器资源,并且会对服务器造成一定的压力;

我们根据秒杀的的特点,同一时间有大量流量涌入,主要会刷新页面请求静态资源。

从这个特点出发,我们可以把商品展示的页面进行静态化(生产html静态文件),并且把html文件和js,css ,图片等静态文件统一发布到CDN上,加快网站访问速度,并且能够降低流量资费;

所以我们前端采用静态化的方式来优化展示性能,数据交互的化通过ajax和后端接口进行交互;

 

六、秒杀后端优化

1.验证接口分离

这里是从架构图上能够看到,除去前端环节,SLB往下是服务端优化部分,服务端优化也是秒杀系统的核心部分,下面我们就来看下着重优化的环节;

从架构调整上来讲,我们首先需要把验证接口拆开来单独优化运行,也就是我们图上的分布式权限验证;

权限验证在我们系统中是非常耗资源也是压力最大的,我们这里使用hash一致性算法来实现我们验证接口的分布式,来提升验证接口的可以扩展性和整体处理能力;

同样的我们在验证环节,把权限验证的的方式也改成了Cookie验证(双向加密),用来减少服务架构复杂度,提高接口性能;

2.验证接口还能做哪些事情以及测试结果

除去我们上面的权限验证以外,我们在权限验证环节还能添加其它的验证规则,比如根据用户ID的访问速率控制,频率控制,还可以添加黑名单功能,禁止用户访问等规则;

其它特有的访问控制都可以添加在这个环节,性能的话主要依靠GO的语言本身的运行速度,秒杀整体接口压测结果2~3万QPS(业务逻辑包括:分布式权限验证+数量控制+写入RabbitMQ。测试机器 :12核12G阿里云服务);

3.秒杀数量控制接口实现

秒杀数量控制接口也是秒杀系统里比较重要的环节,我们这里采用GO提供API的方式来代替redis来实现数量控制。

当流量非常大的情况下redis 和redis 集群会存在横行扩展的瓶颈,因为redis集群中key如果是一个的话,其实在集群内部访问的是同一台机器,在这种情况下当QPS超过一定程度项目就会出现瓶颈(一般来说8WQPS左右)。如果要满足横向扩展就使用类似哨兵模式搭建集群(这样实现起来太复杂,成本也高);

经过调整设计,我们首先从架构上减少了外部依赖,另外GO提供的单机接口能力可以达到 30WQPS(加互斥锁,没优化机器的情况下,测试机器:12核12G阿里云服务器)也非常可观,我们还能在数量控制接口中来完成数量发放的逻辑,比如间隔一定时间发放一个有效抢购,也可以每隔一定访问个数发放一个有效抢购等;

同样的,如果QPS要求非常高,可以简单横向扩展数量控制接口服务器即可;

 

4.消息队列引入

整个秒杀过程中消息队列也是举足轻重的一环,我们通过前面的逐层拦截和计算,落到我们数据库的真实请求瞬时可能非常大,为了削减瞬时大流量对我们数据库可能造成的压力,我们就引入消息队列的机制来让我们请求按照我们设想的速度运行,从而保障我们系统的稳定性;

在秒杀中我们经常用到的就是RabbitMQ的简单模式(一般情况下已经满足我的需求);

当商品数量大,数据库性能高的时候想提高消费能力,我们通常还会使用到RabbitMQ的工作模式,也就是在simple下开多个消费队列进行消息的消费;

在消费消息的时候,我们通常会设置消费完一个消息后在消费下一个消息。

 

总结

首先:我们通过明确需求,画原型,开发基础功能,我们能够掌握GO web 开发的基本流程。

其次:在基础功能的基础上通过对秒杀场景的分析优化基础功能,调整架构达到系统需求的处理能力,通过这种方式来和同学们分享日常架构演进过程。

最后:在我们设计好的架构基础上,对每项技术细节进行深度优化,提高系统整体能力来实现最终目标。这个环节对大家的要求比较高,技术优化要大家熟悉常用技术的原理,并且能够分析特定场景下优劣,以简化架构,提性能,省成本,易实现为目标选择比较好的方案落地。

 秒杀实践心得:尽可能早的在上层拦截流量,用易扩展的架构设计应对不断增长的流量,数据库闲庭信步;

····················

欢迎关注课程:

《全流程开发 GO实战电商网站高并发秒杀系统》

 


打开App,阅读手记
35人推荐
发表评论
随时随地看视频慕课网APP

热门评论

老师您好 如果我在本地启动秒杀接口、 数量控制接口、 还有一个秒杀界面。秒杀界面访问后端秒杀接口那么请求会跨域。使用nginx后,跨域还是无法解决。

你的那个初级教程学完了是否可以直接学习这个教程

MU课全流程开发 GO实战电商网站高并发秒杀系统,点击链接可直接获取:


查看全部评论