导语
微服务产品团队为了广大开发者朋友们能够更好的运用腾讯云微服务产品,将持续为咱们提供微服务上云快速入门的指引性文档,内容通俗易懂易上手,本篇为本系列的第二篇,为开发者朋友们详解高并发场景里限流的处理计划,欢迎咱们收看。
本篇文章将从以下四个方面为咱们详解高并发场景限流处理计划:
- 秒杀场景架构概述
- 限流完成原理及计划选型
- 限流装备实践
- 云书城沙盒环境演示
秒杀场景架构概述
场景特色
在电商职业里,商家常常会做产品促销的活动,来进行品牌推行或招引更多客户拜访,在这种大促的场景下,一般会有高并发流量进入体系,也便是咱们俗称的秒杀场景。在这种场景下,一般会遇到四个典型的特征。
- 瞬时恳求量大,产品价格低廉,招引许多用户在活动开端时进行抢购。
- 热点数据,指定部分产品参与活动,许多用户浏览量相对集中。
- 防止超卖,因产品让利较多,商家为操控本钱,所以数量有限。
- 不能影响其他事务,秒杀活动一起其他事务也需求正常进行。
在遇见以上特征带来的技术难题时,要怎么确保体系正常运转呢?主要有以下几个规划要点:
- 秒杀子体系与主站资源阻隔;
- 体系需求具有限流才干,能够消化掉秒杀开端瞬间的巨大流量;
- 体系需求具有快速扩展才干;
- 削峰填谷,防止写流量压垮数据库;
- 热点产品提早缓存,经过缓存承载读流量;
- 库存增减需求确保数据一致性。
架构方针
为确保活动的顺利开展,事务体系稳定,需求对承载高并发流量的架构进行合理改造。一般来讲,改造后的架构需求具有如下三个特色:
- 高功用:能够承载秒杀时较高的读写流量,确保呼应时长在可承受的范围内,并兼顾数据一致性。
- 高可用:确保体系不宕机,即便发生毛病,过载维护也能将毛病操控在小范围内,不会影响中心事务运转。
- 高扩展:体系具有水平/垂直扩展才干,防止单个服务成为功用瓶颈。
改造示例
下图是一个常见的电商平台架构,从上到下分别是流量链路途径的客户端、接入层、运用层以及数据层。在这样一个典型的架构上咱们该怎么改造,以完成高并发承载才干呢?
参考上图,首要会在③方位,接入层网关对南北流量的超量部分限流,防止后端体系过载,确保事务正常运转。
接下来,①、②、⑦这儿进行读缓存的优化:①方位,客户端对部分改变不灵敏的数据进行本地缓存,削减后端读取压力;②方位,CDN缓存图片、CSS、JS等静态文件,就近加快拜访,削减后端读取压力;⑦方位,Redis缓存热点数据,分担数据库查询压力,这三部分都是为了完成读优化的功用改造。
写数据的优化,在⑤方位,常运用MySQL进行读写别离办法布置,多实例进步读写功用。如单实例遇到功用瓶颈时,也可一起利用水平分库分表的办法进步并发才干;⑥方位,运用音讯行列进行异步解耦,以削峰填谷的办法操控恳求处理速度。
最终,在④方位,运用层服务支撑纵向或横向扩展,进步运用服务呼应才干。微服务之间选用熔断降级的战略,完成容错处理,防止集体毛病。
以上各实践均有助于处理高并发问题,但在实践规划中,架构师需求依据恳求QPS量级,选用计划组合的方法逐步推进。具体落地进度,也要依据改造本钱、资源本钱、功用进步回报率等因素进行综合评价。如下图所示。
限流完成原理及计划选型
接下来咱们会重点介绍阶段一和阶段二里的高并发限流才干。
什么是限流呢?限流是高并发体系中,关于服务提供方的一种常见的维护手段。经过操控QPS的办法,把后端服务无法承受的部分流量回绝掉,只将能够稳定处理的流量放入进来,防止后端服务被瞬时的流量顶峰冲垮,在南北向设置阈值,保障大后方的稳定性。
运用场景
- 产品秒杀:维护网站不被高并发拜访击垮;
- 防歹意恳求:防止歹意用户发送虚假流量,影响正常事务拜访;防止注入、篡改或DDos进犯等;
- 反爬虫:维护中心数据不被获取。
超量流量处理办法
- 回来失利:HTTP 429 Too Many Requests;
- 降级处理:自定义静态页面回来;
- 恳求排队:堵塞恳求,一段时刻后再持续处理,完成限速。
限流计数器
在限流运用的开发中,有多种代码逻辑完成,咱们最常见的便是限流计数器。
固定窗口计数器(Fixed Window)
办法:经过单位时刻设置,如秒、分钟、小时,选用离散计数的办法,核算这个时刻段里的流量值,一旦恳求大于阈值可承受范围,就会将这个恳求回绝掉。这种完成计划简略,而且内存优化,恳求会在自己所属时刻单位里核算,不会呈现跨时刻段的“堵塞现象”。
问题:因时刻段临界点问题,导致核算成果或许有偏差。以1s限定1000恳求为例,在上一个核算时刻的后0.5s进入了1000个恳求,在下一个核算时刻的前0.5s也进入了1000个恳求,由于时刻的连续性,实践1s内恳求抵达了2000,那限流是不契合预期的。
滑动窗口形式计数器(Sliding Window)
办法:对固定窗口的一种改善,原理类似TCP拥塞操控。将时刻单位整合为多个区间,在区间内核算计数,核算区间逐步进行窗口滑动,处理临界点问题。
问题:内存占用较大,恳求及时刻戳需保存。
限流计数器规划缺点
一般来讲,限流计数器适用于否决式限流,无法进行排队式限流,对流量“整形”,完成削峰填谷无能为力。
如果需求这样的功用,应该怎么改善呢? 最直观的主意,便是运用行列,将超量的流量进行暂存,延迟进行处理。完成这种才干的算法模型,便是咱们了解的漏桶算法。
漏桶算法
漏桶算法(Leaky Bucket)
如上图所示,网络流量和水流相同,不断的进入到体系,当咱们体系的可承载才干很小的情况下,咱们能够将超量的水在一个桶里暂存起来。当体系处理完前面的流量今后,后边的流量就会接着进行处理,这就起到了削峰填谷、流量限速的作用。下面为暗示代码。
漏桶Golang暗示代码
requests := make(chan int, 5)
for i := 1; i <= 5; i++ {
requests <- i
}
close(requests)
limiter := time.Tick(200 * time.Millisecond)
for req := range requests {
<-limiter
fmt.Println("request", req, time.Now())
}
才干:以固定的速率操控恳求的拜访速度;支撑堵塞式限流;选用FIFO行列,完成简略。
问题:当短时刻内有许多恳求时,速率无法动态调整。即便服务器负载不高,新恳求也得在行列中等候一段时刻才干被呼应,无法在固守时刻内许诺呼应,简略呈现恳求“饥饿”现象。
那这种问题又该怎么处理呢?能够用到一个叫做令牌桶的算法。
令牌桶算法(Token Bucket)
令牌桶算法和漏桶算法的最大差异,在于这个桶里装的不再是恳求,而是“通关”的令牌。每一个恳求过来今后,都在行列里排队。当咱们的监控体系发现许多恳求到来,能够人为的添加通关令牌,快速的消耗掉这一大波的恳求,使新进来的恳求不会等候太长时刻,从而造成饥饿现象。能够看一下下面的暗示代码:
令牌桶Golang暗示代码
limiter := make(chan time.Time, 3)
for i := 0; i < 3; i++ {
limiter <- time.Now()
}
go func() {
for t := range time.Tick(200 * time.Millisecond) {
limiter <- t
}
}() // token depositor, dynamic rate
requests := make(chan int, 5)
for i := 1; i <= 5; i++ {
requests <- i
}
close(requests)
for req := range requests {
<-limiter
fmt.Println("request", req, time.Now())
}
单机限流 vs 分布式限流
单机限流
概念:针对单个实例等级的限流,流量限额只针对当时被调实例生效。每一个实例都会有一个自己的限流值,当恳求抵达这个实例后,会进行计数,一旦超越现在能够承受的阈值后,就会直接回绝恳求。
问题:当咱们做一个出产环境布置的时候,肯定不会只要一个网关,或许会有五个、十个,一个集群的网关。那么这个集群里边的每一个实例,它是没有大局感知的,每个实例都只能看见自己的限流值,无法抵达共识,这种情况下很或许限流并不契合预期。
分布式限流
概念:针对服务下所有实例等级的限流,多个服务实例同享同一个大局流量限额。
办法:将所有服务的核算成果,存入集中式的中间件中,常用缓存完成如Redis,etcd,以完成集群实例同享流量配额;经过分布式锁、信号量或原子操作等操控办法,处理多实例并发读写问题。
衍生问题:获取配额会添加网络开支,处理才干会有所降低,怎么处理?集中式限流中间件不行用时,流量怎么应对?
分布式限流完成思路
咱们先来看看,完成一个简略的分布式限流,过程会有哪些:
-
发令牌的进程,和各个限流进程,经过统一中间件(如Redis、etcd等)进行交互;
-
发令牌进程在中间件上设置限流进程个节点;每个节点里,按阈值(如分钟)设置该节点的“令牌”数量,如 key = /token/1或许/token/2,value = ratelimit = 10;
-
限流进程将节点value,作为令牌运用,获取今后做原子性减一操作;
-
一旦进程当时节点value不行,按照环形拜访办法,运用下一个限流进程的令牌。
问题:刚才上面说到的两个衍生问题,在这样的完成下,怎么处理呢?
计划:
- 各限流器对中间件,能够进行batch更新,经过牺牲部分准确率,换取拜访压力削减,进步流控功用。
- 当中间件不行用时,当时实例可装备回绝所有恳求,或让流量正常经过。也可装备选用本地配额进行短路处理。
限流计划选型
Redis | 运用“INCR“和“EXPIRE”进行代码完成,或运用redis-cell模块 |
---|---|
Nginx | 官方限速模块,选用漏桶算法完成•limit_req_module: 约束 IP 在单位时刻内的恳求数•limit_conn_module: 约束同一时刻连接数 |
云原生网关(如Kong,APISIX) | 以插件的办法提供,支撑多种限流计划,支撑分布式限流•Kong:固定窗口,滑动窗口,令牌桶•APISIX:固定窗口,漏桶 |
服务办理中心(如北极星,Istio,Sentinel) | 一起提供限流和熔断功用,且可对服务间流量进行细粒度办理,如就近拜访等 |
限流装备实践
接下来咱们看一下,在云原生网关上怎么装备限流。
演示视频:v.qq.com/x/page/b336…
云原生网关限流
云原生优势
- 削减自建网关的运维本钱;
- 降低服务器资源本钱;
- 100%兼容开源网关Kong的API。
限流装备
- 支撑秒、分钟、小时、天、月、年等多时刻维度独自或组合装备限流值;
- 支撑匀速排队;
- 支撑自定义回来的才干,设置回来状态码、回来内容和回来头;
- 支撑按consumer、credential、ip、service、header、path等多个维度进行限流。
限流核算战略
- Local:计数值保存在Nginx本地内存中,功用最高,不适合集群布置形式(单节点布置时引荐);
- Cluster:计数值保存在Kong的数据库PostgreSQL中,功用较差,不适合高并发场景;
- Redis:计数值保存于外部Redis,适合集群布置场景,功用较高,需求额外的redis组件(集群布置时引荐)。
服务办理中心限流
对应的,在服务办理中心—北极星上装备限流。
演示视频:v.qq.com/x/page/t336…
接入层服务流量办理
- 支撑服务/接口/标签的限流才干;
- 支撑快速失利及匀速排队两种处理办法;
- 支撑秒、分钟、小时、天等时刻微服务间的限流才干。
服务间调用流量办理
- 毛病熔断,依据服务调用的失利率和过错数等信息对毛病资源进行除掉。
- 拜访限流,支撑服务/接口/标签多级限流才干,提早约束超越阈值的流量。
云书城沙盒环境演示
咱们模拟了一个在线的云书城。它具有多个微服务模块,比方保藏功用、购买功用,用户办理功用,订单查询功用等。在秒杀场景下,体系添加了一个秒杀子体系,专门为大促活动时,产品秒杀运用,先来看下架构图。
从最北向进来的流量会首要经过云原生网关,抵达商城主页。接下来流量进入事务网关层,它来做后端服务间gRPC的调用办理,最终是各微服务功用单元,经过事务逻辑进行分割。
接下来经过沙盒环境,演示云书城在大促期间,怎么应对高并发流量的拜访。
演示视频:v.qq.com/x/page/b336…
读写优化及扩缩容计划
横向扩缩容-TKE/EKS
演示视频中有运用到扩容的功用,这儿咱们简略讲解一下服务扩缩容。
了解K8S的同学都知道,选用Scale指令能够将服务的副本数进步,但是在限流的场景下,或许在大促时,这样手动操作肯定不现实。一个更好的计划是选用腾讯云上TKE/EKS的HPC功用,它具有守时扩缩容的才干,针对体系负载评价值,提早做好准备。合作HPA功用,针对QPS或体系负载进行动态的调整,将服务的承载才干,维持在一个合理的水位上。HPC与HPA相合作,基本能够做到流量顶峰时主动扩容,防止体系崩溃;流量低谷时主动缩容,节省本钱。
产品优势
- HPC组件的作用:守时执行pod扩容或缩容的动作。
- 选择HPC的原因:秒杀场景具有流量瞬间爆发式增长的特征,HPA组件扩容需求1分钟左右,这段时刻或许导致服务崩溃,HPC组件能够依据秒杀开端时刻设定提早扩容。HPA组件能够作为弥补,构成两层确保。
- 节点池装备:无需事先购买节点,因资源不足而无法调度实例时,完成主动扩缩容,节省本钱。
异步解耦-TDMQ Pulsar
在秒杀场景里,常常会对写恳求和读恳求进行优化。
写恳求的优化,咱们一般会想到,经过异步的办法来解耦数据层的拜访,而不是直接将恳求打到数据层上,由于数据层或许是体系里最单薄的一个环节。咱们将一些订单的处理或许用户购买信息的处理,放在音讯行列里,这种规划逻辑和网关限流排队是一致的,方针都是以可控的办法,将体系外部的恳求,维持在可承受范围内。
腾讯云有一款产品叫做TDMQ Pulsar ,它以存算别离办法完成,关于快速扩容更有优势,产品确保了上方的核算层处于一个无状态的布置形式,关于自身的扩容速度是非常快的。别的TDMQ Pulsar 数据层的规划机制,使得它和Kafka的最大差异,在于不约束 Topic 分区数,这样咱们能够发动更多的Consumer来进步消费吞吐量。在秒杀场景中处理订单的消费,是会非常有帮助的。
产品优势
- 选用BookKeeper协议完成数据强一致性;
- 存算别离的架构带来灵活的横向扩展才干 ;
- 高功用低延迟,单集群QPS>10万;
- 不同于Kafka,TDMQ Pulsar的顾客数量不受限于Topic的分区数,可发动更多的顾客进步处理才干;
- 支撑大局/局部次序音讯、守时音讯、延时音讯,满意各种事务需求。
热数据缓存-TDSQL Redis
上面说了写恳求的优化,接下来再说一下读恳求的优化。
读恳求前面说到,能够在客户层进行缓存,也能够在CDN层进行缓存,但更重要的是需求在数据库前也进行一次缓存,使得读恳求不会直接抵达体系最单薄的环节——数据库,构成一个“冲突缓存带”。这儿咱们常将一些热点数据放在Redis里来供大促期间运用。
产品优势
-
超高功用;标准版10万+QPS;集群版支撑千万级QPS。
-
主动容灾切换;双机热备架构;主机毛病后,拜访秒级切换到备机,无需用户干涉。
-
在线扩容;操控台一键操作扩容;扩容过程中无需停服。
标准版架构
集群版架构
总结
除了本文说到的高并发秒杀场景外,在互联网服务的许多场景下,当体系期望完成高可用、高功用、高扩展的规划方针,都会运用到腾讯如此原生网关产品所提供的才干,比方灰度发布、全链路染色、多环境路由和多活容灾等架构。
云原生网关(Cloud-Native Gateway)是腾讯云依据开源网关Kong推出的一款高功用高可用的网关产品,100%完美兼容开源。一起提供TKE/EKS集群直通,Nacos/Consul/Polaris/Eureka注册中心对接,实例弹性扩缩容等才干,并有特色才干插件增强,明显削减用户自建网关带来的开发及运维本钱。别的,多可用区布置的形式,也确保了事务连续性,防止单可用区毛病带来的服务中止。
无论在微服务架构下仍是传统Web架构下,云原生网关都能以流量网关、安全网关和服务网关所需求的各种才干特性,为事务云上布置提供助力。