弹性可伸缩微服务架构设计中的流控话题探讨

不羁岁月 提交于 2020-01-14 06:13:55

先简单谈可伸缩弹性服务架构

先简单谈弹性可伸缩服务架构,具体的架构设计后面会有文章详细介绍。
何为弹性?何为可伸缩?其实这是架构设计中除了考虑高可用,高稳定性,高性能,易扩展因素外更进一步的思考。
弹性,顾名思义,面对剧烈冲击的时候仍能应保持正常功能和服务。剧烈冲击一般可以理解为突增流量。
可伸缩,一般指服务节点和整体服务器资源的可动态调度和部署。
具体方案这里不详细展开,这里着重谈一下在弹性架构设计中经常用到的流程手段和原理。

流控的意义

流量一般都会经过反向代理层,应用服务层,数据层,而者每一层之间都因该有流量控制组件的身影,每一层流控的目的和意义都不一样,但总体都是为了保证整体应用的高可用性和高稳定性,各个层的流控作用如下:

  1. 反向代理层
    过滤恶意流量,主要是对恶意攻击流量和爬虫进行甄别
    灰度测试的流量分发
    对后端服务层的QPS过载保护
    2.服务层
    可以通过微服务框架对服务和接口进行治理包括,服务降级,限流等
    对第三方接口进行QPS过载保护
  2. 数据层
    包括通过限流组件防止流量雪崩式的压向数据库,避免数据库的服务端因某个应用的tps过高而引发资源问题

流控原理(或称方法论)

  1. 漏桶原理 (leaky bucket)
    在这里插入图片描述
    简单的说就是桶是有容量(capacity)限制的,流量(请求)进入通内后一定的速度流出,每次流出的流量大小是固定的,达到桶的容量限制后,流量会被拒绝。
    Wiki的上原文解释如下:
    The leaky bucket is an algorithm based on an analogy of how a bucket with a leak will overflow if either the average rate at which water is poured in exceeds the rate at which the bucket leaks or if more water than the capacity of the bucket is poured in all at once, and how the water leaks from the bucket at an (almost) constant rate. It can be used to determine whether some sequence of discrete events conforms to defined limits on their average and peak rates or frequencies, or to directly limit the actions associated to these events to these rates, and may be used to limit these actions to an average rate alone, i.e. remove any variation from the average.
  2. 令牌桶原理
    在这里插入图片描述
    理解令牌桶算法的要点是流量过来是需要领取桶内的令牌的,拿到令牌即可通过,否则继续等待或直接拒绝,桶内的令牌总数也是有限制的,在消耗桶内令牌的同时,还会以一定速率想桶内添加固定量的令牌。
    有兴趣的可以看下Wiki的原文描述:
    The token bucket algorithm is based on an analogy of a fixed capacity bucket into which tokens, normally representing a unit of bytes or a single packet of predetermined size, are added at a fixed rate. When a packet is to be checked for conformance to the defined limits, the bucket is inspected to see if it contains sufficient tokens at that time. If so, the appropriate number of tokens, e.g. equivalent to the length of the packet in bytes, are removed (“cashed in”), and the packet is passed, e.g., for transmission. The packet does not conform if there are insufficient tokens in the bucket, and the contents of the bucket are not changed. Non-conformant packets can be treated in various ways:
    • They may be dropped.
    • They may be enqueued for subsequent transmission when sufficient tokens have accumulated in the bucket.
    • They may be transmitted, but marked as being non-conformant, possibly to be dropped subsequently if the network is overloaded.
    A conforming flow can thus contain traffic with an average rate up to the rate at which tokens are added to the bucket, and have a burstiness determined by the depth of the bucket. This burstiness may be expressed in terms of either a jitter tolerance, i.e. how much sooner a packet might conform (e.g. arrive or be transmitted) than would be expected from the limit on the average rate, or a burst tolerance or maximum burst size, i.e. how much more than the average level of traffic might conform in some finite period.

案例及demo

比较经典的开源限流实现如java 版guava ratelimiter ,另外还有redisratelimiter。 还有nginx 的limit_conn和limit_req_zone,其中limit_req_zone是用漏桶算法实现的限流机制。go语言也有l类似rateimiter实现,如juju/ratelimit ,和golang.com/x/rime/rate 两个版本的实现,均是基于token bucket 算法的实现。个人觉得go语言的实现非常简洁,适合大家来理解限流组件的使用,下面就go版本作简要介绍,其他版本的可以自行查阅资料:


```go
		...
		var lim *rate.Limiter
		lim = rate.NewLimiter(2, 1)
		...
		//流量控制
		if ok :=lim.AllowN(time.Now(),1);ok{
			fmt.Println("accept ")
			handler(writer,request)
		}else {
			log.Print("refused by limiter.....")
			 defaultHandler(writer,request)
		}
		
```具体demo 见:https://github.com/smileclound/go_ratelimiter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!