原文链接:https://www.cnblogs.com/catcher1994/p/11106767.html
前言
相信我们大家或多或少都有接触过,一些需要收费的接口。虽然说这个收费的标准和模式都不一样,实现的思路自然也是略有区别。
今天来简单说一下按次计费接口的实现思路。
何为按次计费
按次计费,简单来说,就是每次成功的调用都需要收费。
当然,这个也只是最终的结果,在这之前,往往会要求调用方先购买一定的使用次数,才能正常发起调用,也才可以进行计费操作。
举个简单的例子,有一个数据供应商提供了一个天气数据的接口,假设它的价格是1分钱1次。
那么这个时候有个人想买它的这个接口100次,就要先给钱,才能拿到接口的相关信息,然后才能正常调用。
这里还会涉及到一个有效调用和无效调用,只能是有效的接口调用才能真正的扣调用方的次数。
什么样的情况能定义为有效调用,这个就是由供应商那边自己定的了。正常是能在规定的时间内返回有数据的结果。
到这里,背景已经交代清楚了,下面我们就来看看思路。
简单的实现思路
个人认为,思路这边主要就是下面4个要考虑的点:
- 次数怎么样扣减
- 调用日志如何记录
- 如何看到实时余次
- 余次不足的通知
下面依次来看一下。
次数怎么样扣减
这里是借助redis来完成这一操作的。一个是加次数,一个是减次数。
加次数,在用户购买次数的时候就将购买的次数写进redis,key的格式可以类型这样 【countapi:用户名:接口名】,然后value就是用户购买的次数了。
减次数,在用户成功调用的时候就进行减一的操作就可以了。
调用日志如何记录
为什么要记录这个调用日志,可以理解为就是和调用方扯皮的依据。一般会记录,用户,调用时间,IP,入参和出参等。
这个调用日志是不会有修改操作的,只有添加和查询。所以可以优先选择把它存储到ES中。
异步入库是首选,不会阻碍正常的查询。
直接把调用日志写入kafka,由另一个程序读kafka,然后慢慢的写入ES。
当然,RabbitMQ也是一个选择,可以视情况选择。
注,这里有必要做一下容错处理,如果 kafka或RabbitMQ 宕机了,这部分调用记录要先保存到一个地方,然后等kafka或RabbitMQ恢复了再扔进ES。
如何看到实时余次
单个用户的余次,还可以直接从redis中拿出来。如果是要看一堆用户,还要分页,这个可能就不太好办了。
所以用户在购买次数的时候,除了把次数写进redis,肯定也会生成一条购买记录在数据库中。
用户一直在查,redis中的次数一直在减少,但是购买记录中的次数却是没有减少的,给管理人员带来的假象就是用户没有调用过,这个肯定是不行的。
一般情况下,也不会每查一次就去更新数据库,因为如果量大,数据库的压力就会比较大。
所以可以考虑每隔5~10秒读取一次redis中的次数,然后更新到数据库中。这样得到的余次可以认为是近似实时的。
余次不足的通知
这个通知就相对简单了,拿到最近的剩余次数,如果低于某个阀值,就发邮件或短信通知用户就可以了。
最后附上一张简易的示意图。