轻型的接口访问频率限制服务模型的设计与实现【转】

原文地址:http://www.iam3y.com/html/878.html

最近需要设计open api的接口频次控制相关实现,便查阅相关文档。

接口频次控制主要包括两方面:

(1)业务ID对某一个接口某时间间隔(如一分钟)内访问的次数 限制

(2)业务ID在某个时间周期(如一天)内访问的次数 限制

对于存储并进行频次计数的服务来说,要具备以下的特点:

(1)自更新能力,在某个约定的时间点对所有的node(节点)进行自更新操作,也就是常说的出厂设置

(2)协议轻型能力,协议必须尽可能简单,才能达到高效的目的

(3)增删查改能力,允许业务调用方对某个节点的数据增删查改

以上所提节点,如node,大体包含了如下分支

node.bizid,业务id,给某个客户分配的业务id,是客户在频次计数系统里的唯一标识

node.m_count,某分钟周期内访问次数

node.count,某计数周期内访问次数,如一天。

node.starttime,计数开始周期

node.endtime,计数结束周期,记录客户最后一次接口访问的时间,也用于频次计数系统的自更新

node.m_starttime,分钟计数开始时间

node.m_endtime,分钟计数结束时间,当(node.m_endtime-node.m_starttime)<60 && node.m_count>M_MAX_COUNT,接口访问被拒绝,当(node.m_endtime- node.m_starttime)> 60,同时更新node.m_endtime,node.m_starttime为当前时间,重置node.m_count

同样,天计数周期的原理也如此。

基于以上目标,我们看系统要怎么去实现,如下内容为转载内容。

原文链接 轻型的访问频率限制服务模型的设计与实现

        为防止开放系统的公共接口被过度调用,本文提出一种面向系统内部的访问频率限制服务轻型模型,并给出泛型键值索引、频率约束算法等关键技术实现。该服务模 型抽象了各种业务的访问频率限制逻辑,记录各个键值对特定业务的访问间隔和访问时间,通过频率约束算法,为系统公共接口提供访问频率约束依据,使得公共接 口可以对外界请求做出拒绝,消除了因接口过调用而带来的系统安全隐患,提高了系统的服务质量以及接口调用的有效性。


关键字:访问频率限制; MMAP集群;泛型键值索引

1.引言
对于大型开放平台,其公开的服务接口会被外界频繁调用,在不加任何访问频率的控制策略,这些接口甚至可能会被过度调用。给系统带来额外的负担。
过度调用,会导致两方面的后果:接口调用者通过对服务接口的多次调用间接获取系统安全信息,对系统造成隐患,常见的有:短时间内对登陆服务接口,通过枚举 组合,破解用户系统密码。另一方面,因为用户个体数量庞大,单个用户对接口大量的调用,会影响其他用户的服务质量,降低系统的有效负荷。

        用户访问数达到一定量级的系统平台均会遇到上述问题,并各自都有相应的解决方法。但现成的方法是,把访问限制功能作为独立的模块,系统内部需要使用此功能 的业务,就把该模块的拷贝纳入作为业务的子模块。这种系统组织方式既不利于维护,也不利于管理。而且访问约束所适用的类型往往是固定的,不易于扩展。用户 访问数据的存储方面,已有的方式主要分两种:客户端记录,或在服务端用数据库存储。前者的访问数据可能被篡改,有安全隐患;作为一种基础功能模块,后者的 做法代价较为昂贵,可能会占用大量的数据库连接,降低业务处理能力。

        针对上述问题,本文提出一种轻型的访问频率限制服务模型(Access Frequency Restrict Service Model, AFRSM)。此模型本身是一种面向平台内部的私有服务接口。系统边界以内的一切需要进行访问频率限制的模块和对外服务接口均可通过简单的协议共同使用此 服务(Frequency Restrict Service, FRS)。最终达到统一管理和使用访问频率限制服务的目的。


2.FRSM概述
2.1 架构
频率限制服务(Frequency Restrict Service, FRS)作为CGI、Web-Service等公共服务接口的依赖服务,自身对性能有较高的要求。在设计模型时我们偏重其并发处理能力以及轻型的数据存储。
FRS由三大块组成:微服务器框架、MMAP文件群以及一组配置文件。其中服务器我们采用了并发度较高的epoll模型,除守护进程外还可配置n个子进程 进一步增加其并发性能。服务只处理两种类型的请求:Query和Update,分别对应FRS的查询接口和更新接口。公共服务(记为PS)通过FRS的查 询接口可以获知:当前用户/当前IP是否仍对于该服务(PS)有使用权,如有权使用则表示该用户在服务(PS)中没有被限制;反之,则表示该用户在服务 (PS)中已被约束。


在FRS的核心处理模块中,包含了一些核心算法,用以访问和更新MMAP文件群。
Config-Cache是FRS的重要组成部分之一,在守护进程启动时,指定配置文件内容机会被缓存在中,之后每次访问配置文件实际上都会在内存中命中 需获取的配置项。配置文件在此分两种类型:(1)服务器相关的配置(srv.xml),用于指定服务器的子进程数,所绑定的主机端口等;(2)业务配置 (map.xml),用于注册各个业务的频率限制细则:业务标识、时间间隔、间隔内最大访问次数。


2.2协议
FRS采用TCP协议,并在此基础之上构建应用层协议。由于FRS是内部服务,不对外公开,因此不存在数据包的保密问题;同时FRS属于轻型服务,在一次服务请求过程中不会传输过多数据,因此不需要考虑数据包压缩的问题。应用层协议的构建原则是:简单并易于扩展。
HTTP-XML协议是我们所采用的应用层协议。即,使用HTTP头描述数据包体的长度、请求命令类型等信息。具体请求/响应数据则采用XML协议描述,以便在此基础上进行扩展修改。

2.3 部署与使用
FRS作为一种内部服务,其使用者是位于系统最外层的CGI、Web-Service、其他Server等公开服务接口。通用的HTTP-XML协议使得其它服务的逻辑中可以很方便实现对FRS的调用。
FRS的客户端使用模式相对固定,主要分=两个步骤: a. Query, b. Update.
当且仅当key在服务(BizID)中没有被约束,调用者key才能继续使用该业务,并在使用完毕后,必须更新记录key对这次业务的使用情况
4 FRS使用模式
由于从步骤(02)开始需要依赖步骤(01)的结果,步骤(01)必须使用同步模式请求FRS。如该业务采用异步I/O模型[3]的可能在此进行特殊处理,采取局部的同步请求。

3.关键问题分析
3.1 泛型的键值索引
FRS中的访问记录我们采用轻型的MMAP存储,使用时只需把文件数据映射到内存中即可。然而遍历文件找到真正需要的数据是一项耗时的操作,尤其在文件较 大的情况下。为此,本文采用泛型的键值索引,将MMAP文件平均划分为m块存储区域(称为关键节点,key-node),在目标数据存储或检索之前,预先 为其估算出一个关键节点,使MMAP可以快速定位到该区域。键值不同的数据有可能会被安排在同一个关键节点中,称为估算冲突。冲突的数据会被安排在该关键 节点的一条冲突链上,进行小区域遍历检索。

上侧描述的是单个MMAP文件存储。垂直排布示意的是关键节点,与其紧连的是该节点的冲突链。冲突链是有长度限制的,因为m=1的极端情况下,冲突 链将占满整个文件,检索算法会退化为文件遍历检索。较为理想的情况是尽量减少冲突链的长度,尽可能一次命中。当某条冲突链用尽的时候,我们需要考虑采用淘 汰算法,将过期的节点抹掉/复用。假定允许的冲突长度为Length conflict (包含关键节点本身),每个节点存储大小为size node,则可计算出MMAP文件的大小:
size MMAP = size node * Length conflict * m


上述的泛型是指FRS的扩展性。在FRS中通过编程扩展可以支持:以不同数据类型作为索引主键,只要实现该种数据类型的索引估算接口,和比较接口即可。其 中,索引估算接口在知道关键节点总量m的前提下,用来计算关键节点。如:Integer类型的键值可以采用求模运算得到关键节点索引,而String类型 则可以使用现成的Bob Hash算法[5];而比较接口则是在冲突链上用来进行键值比较,最终定位到目标数据。


MMAP集群由多个同构的MMAP文件构成。它适用于更大数据量存储。假定一个MMAP群当中有n个存储文件。即相当于将数据存储容量扩展了n倍。根据上述说明,可得出总的数据存储大小为
size MMAP = size node * Length conflict * m* n。


总体看来,使用MMAP群模式对数据进行存储检索,实际上使用了2级检索:第一级,索引到文件;第二级,索引到关键节点。
为了使用方便,我们把上述对MMAP的访问步骤封装成一组操作:Init-MMAP、Find-Node、Erase-Node、Update-Node。由于MMAP是多进程共享访问的,因此这些操作(尤其是修改文件数据的操作)都需要使用信号量互斥处理。
Init-MMAP:在守护进程启动时,根据配置文件初始化MMAP/MMAP群的规模。
Create-Node:创建新节点。
Find-Node:找到目标数据节点。
Erase-Node:删除目标节点。通常在淘汰处理时调用。
Update-Node:更新目标数据节点。

3.2 频率限制
频率限制是FRS的核心模块之一。在保证它的有效性的前提下,我们尽量简化了它的实现逻辑。它基于以下简单的数据结构和算法(图6):
其中Interval和Max分别是某业务ID所对应的时间间隔和限制次数(于配置文件中设定)。这两个参数控制了个体在一个时间段内访问业务的次数。
由算法可知,在Interval时间段内:
第1次访问一个业务时,会通过FRS创建一个新的记录节点(记为node),并把node.Start和node.End更新为当前时间戳,node.Count记为1图6 频率限制算法示意
第n次(n<=Max)访问该业务,则保持node.Start不变,node.End更新为当前时间戳,node.Count记为n;
第n次(n> Max)访问该业务,仍然继续保持node.Start的值不变,node.End更新为当前时间戳,但由于node.Count已到达极限值,访问被拒绝。
当且仅当,在下次访问时满足:解除时间间隔约束(node.end-node.start>=Interval)条件,node.start才会重 置为当前时间戳。回到处理第1次访问逻辑的状态。有两种情况会促使FRS调用Create-Node去创建一个新节点:(1)第一次访问;(2)因为节点 过旧而被淘汰,需要新建。

4.结束语
通过简单的协议和高并发的服务器模型,我们在本文中把访问频率限制功能抽象成一种内部服务接口,并在实现中使用MMAP集群确保了其数据访问存储的轻型 性。在实际应用运营过程中,该服务模型可胜任10,000,000级别日访问量的开放平台,保证了有效的服务质量以及系统安全。实践表明,将平台内部功能 抽象为服务,能提高其应用服用程度,明显降低了功能的维护和扩展成本,具有一定的推广意义。

原文地址:https://www.cnblogs.com/jimcsharp/p/5534840.html