开放平台,我相信大家并不陌生。当需要把一个产品本身的一些功能开放出去,可以让三方开发者接入和使用,这就是开放平台做的事情。
为什么我们能用微信登录很多其他的应用,这就是因为这些应用通过接入微信开放平台提供的能力实现了授权登录。
开放平台流控需求分析
对于开放平台来说,有一个功能是必须要有的,那就是API的流控。
对于每一个接入开放平台的应用,都会分配一个Appkey,这个Appkey下面会关联你申请了哪些API。然后接入的API有些是不限量,可以一直调用。有些是需要申请调用包,比如一天10万次的调用量。
除了总量的限制,还有对频率的限制。比如每秒每个API调用频率的限制,每秒每个Appkey调用频率的限制。
要实现这些流控的功能,最好的方式就是已经有一个流量治理平台,里面提供了限流的功能。像开放平台这种还不属于普通的系统限流,有点偏业务限流了,因为有具体的数量指标。
技术选型
这也就是前面文章里面跟大家讲什么时候要自研,什么时候可以直接用开源。当需求无法满足,就只能自研了。
自研可以在开源的基础上开发,增加业务限流的功能,支持租户的功能,可以多租户接入。支持按Appkey时间内的总量限流,支持API时间内的数量限流。
如果没有现成的治理平台可以接入,那么就需要业务方自己进行开发。自己开发一般都会使用MySQL+Redis去实现。
实现原理
MySQL用于存储基本配置信息,比如Appkey对应的流控信息,API对应的流控信息。
Redis用于数量扣减提高性能使用,使用这个方案必然会带来一个数据一致性的问题,就是MySQL里的数据如何跟Redis保持一致。
为什么要用Redis?
假设不用Redis也就意味着每次调用后都需要更新MySQL里面的调用次数。在高并发的情况下,性能肯定是需要优先考虑的问题。
用Redis还是为了扛高并发,而且这个业务场景也不复杂,就一个计数而已,Redis本身也支持原子操作。
Redis只是用来辅助使用的,并不是作为业务数据的存储系统。所以这里就涉及到数据一致性的问题。
如何保持一致?
这里我们再思考下,是否需要强一致性?
不需要,而且这个场景也不好做。所以只需要保证最终一致即可。
对于计数信息,可以采取提前同步到Redis中,也可以采用延迟加载的方式。比如对某个Appkey下的某个API进行计数,key可以这样设计 Appkey:API ,过期时间就是你要限制的时间段,比如按天来限制。
这里需要有个定时同步Redis里面的计数信息到MySQL里面的任务,时间间隔可以自行设置。假设Redis没做持久化,重启后数据丢失,这个时候会从MySQL里面查出计数信息进行初始化,如果你同步间隔是10分钟一次,那么只会有这10分钟的调用次数丢失。
我认为对于一般开放平台来说,丢了一些计数信息没啥大问题,无非就是让三方多调用一些数量的接口。但是具体业务具体分析,如果你们的API是按次计费的,那么本方案可能不适合,涉及到钱的还是得强一致。
单机还是集群?
这个话题,前面的文章《流量治理神器-Sentinel的限流模式,选单机还是集群?》里面我们也聊到过。
那么在开放平台的这个业务场景下,毫无疑问的是要选择集群限流。首先它是一个业务场景的限流,有明确的限流指标,单机限流没有全局的存储,无法反馈本身的结果给其他服务,就会导致业务结果不正确。