业务场景1
人工智能领域的语义识别语自动对话。现对试用用户的试用行为进行限速,限制每个用户每分钟最多发起10次调用
解决方案
1.设计计数器,记录调用次数,用于控制业务执行次数。以用户id作为key,使用次数作为value
2.在调用前获取次数,判断是否超过限定次数
不超过次数的情况下,每次调用计数+1
业务调用是白,技术-1
3.为计数器设置生命周期为指定周期,例如1秒/分钟,自动清空周期内使用次数
方法1
127.0.0.1:6379> get 415
(nil)
127.0.0.1:6379> setex 415 60 1
OK
127.0.0.1:6379> get 415
"1"
127.0.0.1:6379> incr 415
(integer) 2
127.0.0.1:6379> get 415
"2"
127.0.0.1:6379> incr 415
(integer) 3
127.0.0.1:6379> incrby 415 7
(integer) 10
解决方案改良
取消最大值的判定,利用incr操作超过最大值抛出异常的形式替代每次判断是否大于最大值
判断是否为nul,如果是,设置为Max-次数
如果不是,计数+1
业务调用失败,计数-1
127.0.0.1:6379> get 415
(nil)
127.0.0.1:6379> setex 415 60 9223372036854775797
OK
127.0.0.1:6379> get 415
"9223372036854775797"
127.0.0.1:6379> incr 415
(integer) 9223372036854775798
127.0.0.1:6379> incr 415
(integer) 9223372036854775799
127.0.0.1:6379> incr 415
(integer) 9223372036854775800
127.0.0.1:6379> incr 415
(integer) 9223372036854775801
127.0.0.1:6379> incr 415
(integer) 9223372036854775802
127.0.0.1:6379> incr 415
(integer) 9223372036854775803
127.0.0.1:6379> incr 415
(integer) 9223372036854775804
127.0.0.1:6379> incr 415
(integer) 9223372036854775805
127.0.0.1:6379> incr 415
(integer) 9223372036854775806
127.0.0.1:6379> incr 415
(integer) 9223372036854775807
127.0.0.1:6379> incr 415
(error) ERR increment or decrement would overflow
127.0.0.1:6379> incr 415
业务场景2
微信消息展示顺序,使用微信的过程中,当微信接受消息后,会默认将最近接受的消息置顶,当多个好友及关注的订阅号同时发送消息时,该排序会不停的进行交替。同时还可以将重要的会话设置为置顶。一旦用户离线后,再次打开微信是,消息该按照什么样的顺序显示?
set置顶用户为400和500
用户300发送消息,判断是否在set置顶,否,加入list普通
400发送消息,在set置顶中,加入list置顶
200发送消息,重复过程,右进,list普通有300与200
300发送消息,list普通300左出,list普通有200 300
解决方案
1.依赖list的数据具有顺序的特征对消息进行管理,将list结构作为栈使用
2.对置顶与普通会话创建独立list分别管理
3.当某个list中接收到用户消息后,将消息发送方的id从list的一侧加入list(此处设定为左侧)
4.多个相同id发出的消息反复入栈会出现问题,在入栈之前无论是否具有当前id对应的消息,先删除对应id
5.推送消息时先推送置顶会话list,在推送普通会话list,推送完成的list清除所有数据
6.消息的数量,也就是微信用户对话数量采用计数器的思想另行记录,伴随list操作同步更新
127.0.0.1:6379> lrem 100 1 300
(integer) 0
127.0.0.1:6379> lpush 100 300
(integer) 1
127.0.0.1:6379> lrem 100 1 400
(integer) 0
127.0.0.1:6379> lpush 100 400
(integer) 2
127.0.0.1:6379> lrem 100 1 200
(integer) 0
127.0.0.1:6379> lpush 100 200
(integer) 3
127.0.0.1:6379> lrem 100 1 300
(integer) 1
127.0.0.1:6379> lpush 100 300
(integer) 3
127.0.0.1:6379> lrange 100 0 -1
1) "300"
2) "200"
3) "400"
Tip17:
redis应用于基于时间顺序的数据操作,而不关注具体时间