一、为什么要限速?
通常在使用各类网盘工具或者在网站下载较大的文件时都会遇到限流的问题。打个比方,用户从宽带运营商那里所购买的实际宽带是 100 Mb/s,但在下载文件的过程中,下载速度却只能达到 10 Mb/s 或者更低,这种情况就可以认定为服务端或客户端做了限速处理。
站在客户的角度上讲,限速确实是个令人反感的机制,下载速度慢,一个文件经常要下载很久,虽然办理了高速宽带却享受不到高速的下载,服务提供商也清楚限速会引起客户反感,那为什么还要额外增加这一层限制?其实服务器限流的原因有很多,最常见的便是以下几种原因:
保护服务器:服务器处理大量请求可能会导致服务器过载,影响服务器的性能和稳定性,限流可以确保服务器运行于合理的负载范围内,从而保障服务的总体可用性;
平衡流量:限流可以平衡服务器的流量,防止个别用户占用过多的带宽,而导致其他用户请求无法得到合理响应的情况。
出于商业考虑:对普通用户限速是为了向付费用户提供更高的带宽、更快的下载速度,保障付费用户的体验。
二、常见的限速方式
常见的限速方式大致分为 2 种:客户端限速和服务端限速:
客户端(前端)限速:是指在服务器和客户端之间进行流量控制,即限制客户端发起请求时的数据传输速率,常见的前端限速方式包括:带宽限制、IP 地址限制、端口限制、应用程序限制等,前端限速通常在网络层面进行,通过限制客户端请求的速率来控制整个网络的流量;
服务端(后端)限速:是指在服务器处理请求时进行流量控制,即限制服务器响应客户端请求的数据传输速率,常见的后端限速方式包括:下载速度限制、下载配额限制、下载时间限制、IP 地址限制等,后端限速通常在应用程序层面进行,通过限制服务器响应请求的速率来控制服务器的流量和负载。
而后端限速相对于前端限速更加有效和安全,后端限速更难被绕过,可以限制整个服务的全局访问速率,更容易集中管理和监控。相比之下,前端限速只能影响单个客户端,需要在每个客户端上执行,并且可能需要更新客户端代码,使得管理和监控限速措施更加复杂。当然在某些情况下,前端限速也可能是必要的措施。
三、常用的后端限速算法
常用的后端限速算法:
令牌桶算法:基于令牌桶的思想来限制流量,通过限制每个请求从令牌桶中获取令牌的速率来实现限速。
漏桶算法:基于漏桶的思想来限制流量,通过漏桶来限制请求发送的速率。
固定窗口算法:通过固定的时间窗口来限制请求的发送速率。
滑动窗口算法:通过滑动窗口来限制请求的发送速率,允许在每个窗口内的请求速率不超过指定的速率。
看到算法,可能有不少开发者可能都觉得有些压力,如何实现它以及实现后是否稳定,这都会成为在开发过程中遇到的问题。而 EdgerOS 为了解决开发者这样的苦恼,为了让开发者更加专注于业务与功能上的实现,在 JSRE 引擎 1.10.0 版本 中增加了 Throttle 限流模块,开发者可以轻松的通过该模块进行流控限制。
四、Throttle 模块实现原理
在 EdgerOS 开发过程中我们可以通过 Require() 方法导入 Stream 模块中的限流类 Throttle。
const Throttle = require ( 'stream' ) . Throttle
Throttle 类对象,可以限制数据流的速率从而保护后端服务,具体来说,Throttle 可以控制从另一个可读流中读取数据的速率,并且可以通过设置速率限制,确保不会超出规定的最大速率。这个实现非常重要,因为当有大量数据同时从一个服务中读取时,服务的性能可能会受到影响,因此限制数据流的速率可以确保服务始终可以保持良好的性能。
Throttle 类内部有一套完整的速率限制,具体来说,Throttle 使用了通过内部属性来存储速率限制和其他信息,类中包含了计时器、时间戳、速率等信息,以及从源可读流读取的数据。Throttle 通过源流的事件来判断,是否有数据可以读取,以及如何执行限速,在保证数据一致性的同时,也兼顾了快速相应的需求。
五、如何使用 Throttle 限速?
const Throttle = require ( 'stream' ) . Throttle
var src = fs. createReadStream ( './data.txt' ) ;
var thr = new Throttle ( src, {
rate: 50 * 1024 } ) ;
var start = Date. now ( ) ;
thr. on ( 'data' , ( ) = > {
} ) ;
thr. on ( 'end' , ( ) = > {
var cost = Date. now ( ) - start;
console. log ( 'cost:' , cost, 'ms' ) ;
} ) ;
EdgerOS 中所搭载的 JSRE 是一个立志降低开发者门槛的 Javascript 运行时,在不断的持续迭代中从 Device 模块,到 SyncTable 数据库,以及最新新增的 CloudHost 模块和 Throttle 模块。
一直在将复杂的协议和业务场景做最精简的封装提供给开发者使用,使开发者可以将工作重心完全放在业务开发中,提高开发者的工作效率。随着 EdgerOS 以及 JSRE 日渐成熟,相信未来会有更多好用易用的功能模块出现在 EdgerOS 开发生态中。