其他分享
首页 > 其他分享> > 分布式令牌的发放与回收

分布式令牌的发放与回收

作者:互联网

一、概述

首先说一下使用场景,在分布式环境中,想要控制令牌的发放数量,并且还需要将用完的令牌回收回来,可以理解为 Java 中 Semaphore 类的分布式实现。

 

二、技术实现

借助于 Redis,依赖于 Redis 对客户端命令进行串行执行的特性来保证功能的实现。

实现思路,以下是针对于单个 token 的,当然多个 token 是可以并行的。

1、获取分布式锁

2、修改数据

3、释放分布式锁

这个分布式锁是支持自动续期的,但是这个修改数据的步骤很快,一般也不会发生自动续期,为了兜底,加上了自动续期。

数据结构的定义

首先定义一个 redis key:token:manager,它的数据结构是 Set,里面存储的是各种 token 的值,比如一个 token 是负责接口限流,那么这个 token 的值可以定义为 token:api_limit,然后存储在 token:manager中。

接下来,怎么去知道这个 token 被发放了多少次令牌数呢?

可以以这个 token 的值作为 redis 的 key,接着上面说的这个 key 就是token:api_limit,它的数据结构也是 Set,里面存什么呢?里面存储令牌持有者的信息,这就产生一个要求,在分布式环境下,令牌持有者的标识必须是唯一的。

此时,可以通过计算 Set 结构中元素的数量,得出这个 token 已经发放了多少次令牌。

如果令牌发放出去了,持有令牌的线程挂了,没来记得将令牌还回来怎么办呢?

需要为令牌设置一个自动过期时间,由于加入了自动过期时间,又会导致业务逻辑没执行完令牌被过期了,导致出现令牌超发的问题,还需要加入令牌自动续期机制,可见为了更好用,系统是更复杂的。

自动过期怎么做呢?

用一个普通的字符串类型进行存储上面token:api_limit内的令牌持有者信息,比如:token:api_limit@val@thread-1,然后对这个 key 设置自动过期时间。

此时还要考虑一个问题,就是这个字符串类型的 key 如何与上面 Set 结构里的元素进行联动呢?

在业务代码中加入一个定时任务,定时扫描这些 key,如果过期了,就去 Set 集合里操作删除即可。

 

用图表示如下:

 

代码地址:吴庆龙/redis-token (gitee.com)

 

标签:令牌,Set,过期,回收,token,key,分布式
来源: https://www.cnblogs.com/wuqinglong/p/16512179.html