mirror of
https://github.com/chai2010/advanced-go-programming-book.git
synced 2025-05-29 08:12:21 +00:00
update rl
This commit is contained in:
parent
45af0ca3b3
commit
9476096132
@ -93,15 +93,32 @@ Transfer/sec: 5.51MB
|
|||||||
|
|
||||||
这里的 `hello world` 服务没有任何业务逻辑。真实环境的程序要复杂得多,有些程序偏 Network-bound,例如一些 cdn 服务、proxy 服务;有些程序偏 CPU/GPU bound,例如登陆校验服务、图像处理服务;有些程序偏 Disk IO-bound,例如专门的存储系统,数据库。不同的程序瓶颈会体现在不同的地方,这里提到的这些功能单一的服务相对来说还算容易分析。如果碰到业务逻辑复杂代码量巨大的模块,其瓶颈并不是三下五除二可以推测出来的,还是需要从压力测试中得到更为精确的结论。
|
这里的 `hello world` 服务没有任何业务逻辑。真实环境的程序要复杂得多,有些程序偏 Network-bound,例如一些 cdn 服务、proxy 服务;有些程序偏 CPU/GPU bound,例如登陆校验服务、图像处理服务;有些程序偏 Disk IO-bound,例如专门的存储系统,数据库。不同的程序瓶颈会体现在不同的地方,这里提到的这些功能单一的服务相对来说还算容易分析。如果碰到业务逻辑复杂代码量巨大的模块,其瓶颈并不是三下五除二可以推测出来的,还是需要从压力测试中得到更为精确的结论。
|
||||||
|
|
||||||
对于 IO/Network bound 类的程序,其表现是网卡/磁盘 IO 会先于 CPU 打满,这种情况即使优化 CPU 的使用也不能提高整个系统的吞吐量,可能只能提高磁盘的读写速度,增加内存大小,提升网卡的带宽。而 CPU bound 类的程序,则是在存储和网卡未打满之前 CPU 占用率提前到达 100%,CPU 忙于各种计算任务,而 IO 设备相对则较闲。
|
对于 IO/Network bound 类的程序,其表现是网卡/磁盘 IO 会先于 CPU 打满,这种情况即使优化 CPU 的使用也不能提高整个系统的吞吐量,只能提高磁盘的读写速度,增加内存大小,提升网卡的带宽来提升整体性能。而 CPU bound 类的程序,则是在存储和网卡未打满之前 CPU 占用率提前到达 100%,CPU 忙于各种计算任务,IO 设备相对则较闲。
|
||||||
|
|
||||||
无论哪种类型的服务,在资源使用到尽头的时候等待着用户的都是请求堆积,超时,系统 hang 死,最终伤害到终端用户。对于 web 服务来说,瓶颈不一定总是在系统内部,也有可能在外部。非计算密集型的系统往往会在关系型数据库环节失守,而这时候 web 模块本身还远远未达到瓶颈。
|
无论哪种类型的服务,在资源使用到极限的时候都会导致请求堆积,超时,系统 hang 死,最终伤害到终端用户。对于分布式的 web 服务来说,瓶颈还不一定总在系统内部,也有可能在外部。非计算密集型的系统往往会在关系型数据库环节失守,而这时候 web 模块本身还远远未达到瓶颈。
|
||||||
|
|
||||||
不管我们的服务瓶颈在哪里,最终要做的事情都是一样的,那就是流量限制。
|
不管我们的服务瓶颈在哪里,最终要做的事情都是一样的,那就是流量限制。
|
||||||
|
|
||||||
## 常见的流量限制手段
|
## 常见的流量限制手段
|
||||||
|
|
||||||
## 如何实现一个 leaky-bucket 类型的流量限制器
|
流量限制的手段有很多,最常见的:漏桶、令牌桶两种:
|
||||||
|
|
||||||
|
1. 漏桶是指我们有一个一直装满了水的桶,每过固定的一段时间即向外漏一滴水。如果你接到了这滴水,那么你就可以继续服务请求,如果没有接到,那么就需要等待下一滴水。
|
||||||
|
2. 令牌桶则是指匀速向桶中添加令牌,服务请求时需要从桶中获取令牌,令牌的数目可以按照需要消耗的资源进行对应的调整。如果没有令牌,可以选择等待,或者放弃。
|
||||||
|
|
||||||
|
这两种方法看起来很像,不过还是有区别的。漏桶流出的速率固定,而令牌桶只要在桶中有令牌,那就可以拿。也就是说令牌桶是允许一定程度的并发的,比如同一个时刻,有 100 个用户请求,只要令牌桶中有 100 个令牌,那么这 100 个请求全都会放过去。令牌桶在桶中没有令牌的情况下也会退化为漏桶模型。
|
||||||
|
|
||||||
|
实际应用中令牌桶应用较为广泛,开源界流行的限流器大多数都是基于令牌桶思想的。并且在此基础上进行了一定程度的扩充,比如 `github.com/juju/ratelimit` 提供了几种不同特色的令牌桶填充方式:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewBucket(fillInterval time.Duration, capacity int64) *Bucket
|
||||||
|
|
||||||
|
func NewBucketWithQuantum(fillInterval time.Duration, capacity, quantum int64) *Bucket
|
||||||
|
|
||||||
|
func NewBucketWithRate(rate float64, capacity int64) *Bucket
|
||||||
|
```
|
||||||
|
|
||||||
|
## 如何实现一个流量限制器
|
||||||
|
|
||||||
## 题外话: 分布式流量限制
|
## 题外话: 分布式流量限制
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user