- 项目背景:
在实际项目中经常会遇到系统在某一时间访问量特别大的问题,我们可以针对于系统进行横向扩展,但这往往需要更多的硬件和软件资源,但这一部分资源大部分时间是处于空闲状态的,从节约资源和浪费可耻的角度考虑,针对少数时间段访问量超过系统负荷的情况,我们可以采取限流器进行解决。在单位时间内,如果访问量超过设定阈值,进行拦截处理,拦截后的后续操作可能是加入中间件队列,也可能是直接快速返回。本文仅讨论限流器的一种实现方式(基于redis和zookeeper)。 - 设计思路:
直接上图,清晰明了:
- 核心代码:
分布式锁的获取和释放:/** * 获取分布式锁 * @param lockObj * @return 返回锁对象 */ public static InterProcessMutex acquire(String lockObj) { InterProcessMutex ipm = new InterProcessMutex(_client, _zkBaseDir+"/"+lockObj); try { ipm.acquire(); } catch (Exception e) { _logger.error(e); try { ipm.release(); } catch (Exception e1) { e1.printStackTrace(); } } return ipm; }
限流器核心逻辑实现:
/** * 获取限流通过权限 * @param limiterName 限流器名称,不同名称对应不同限流器 * @return */ public static boolean getRequestPermissions(String limiterName) { InterProcessMutex ipm = ZookeeperClient.acquire(limiterName); RedisUtil redis = RedisUtil.getRedisUtil(); long length = redis.llen(limiterName); boolean flag = false; if(length<_number) { redis.lpush(limiterName, System.nanoTime()+""); flag = true; }else { String lastItem =redis.lrange(limiterName, length-1, length).get(0); if(System.nanoTime()-Long.parseLong(lastItem)>(_frequency*1000000)) { redis.lpush(limiterName, System.nanoTime()+""); redis.rpop(limiterName); flag = true; }else { flag = false; } } try { ipm.release(); } catch (Exception e) { _logger.error(e); } return flag; }
- 项目源代码github地址:
https://github.com/hexinlin/redis-limiter.git
限流器实现:基于Redis+Zookeeper
最新推荐文章于 2024-04-27 17:02:17 发布