app('redis')->connection('default')->throttle('key000')
// 每60秒,只能有10个资源被获取,在3秒内获取不到锁抛出异常
->allow(10)->every(60)->block(3)
->then(function () {
// 获取锁成功,执行业务
}, function () {
// 获取锁失败
return false;
});
<?php

namespace Illuminate\Redis\Limiters;

use Illuminate\Contracts\Redis\LimiterTimeoutException;

class DurationLimiter
{
/**
* The Redis factory implementation.
*
* @var \Illuminate\Redis\Connections\Connection
*/
private $redis; /**
* The unique name of the lock.
*
* @var string
*/
private $name; /**
* The allowed number of concurrent tasks.
*
* @var int
*/
private $maxLocks; /**
* The number of seconds a slot should be maintained.
*
* @var int
*/
private $decay; /**
* The timestamp of the end of the current duration.
*
* @var int
*/
public $decaysAt; /**
* The number of remaining slots.
*
* @var int
*/
public $remaining; /**
* Create a new duration limiter instance.
*
* @param \Illuminate\Redis\Connections\Connection $redis
* @param string $name
* @param int $maxLocks
* @param int $decay
* @return void
*/
public function __construct($redis, $name, $maxLocks, $decay)
{
$this->name = $name;
$this->decay = $decay;
$this->redis = $redis;
$this->maxLocks = $maxLocks;
} /**
* Attempt to acquire the lock for the given number of seconds.
*
* @param int $timeout
* @param callable|null $callback
* @return bool
* @throws \Illuminate\Contracts\Redis\LimiterTimeoutException
*/
public function block($timeout, $callback = null)
{
$starting = time(); while (! $this->acquire()) {
if (time() - $timeout >= $starting) {
throw new LimiterTimeoutException;
} usleep(750 * 1000);
} if (is_callable($callback)) {
$callback();
} return true;
} /**
* Attempt to acquire the lock.
*
* @return bool
*/
public function acquire()
{
$results = $this->redis->eval($this->luaScript(), 1,
$this->name, microtime(true), time(), $this->decay, $this->maxLocks
); $this->decaysAt = $results[1]; $this->remaining = max(0, $results[2]); return (bool) $results[0];
} /**
* Get the Lua script for acquiring a lock.
*
* KEYS[1] - The limiter name
* ARGV[1] - Current time in microseconds
* ARGV[2] - Current time in seconds
* ARGV[3] - Duration of the bucket
* ARGV[4] - Allowed number of tasks
*
* @return string
*/
protected function luaScript()
{
return <<<'LUA'
local function reset()
redis.call('HMSET', KEYS[1], 'start', ARGV[2], 'end', ARGV[2] + ARGV[3], 'count', 1)
return redis.call('EXPIRE', KEYS[1], ARGV[3] * 2)
end if redis.call('EXISTS', KEYS[1]) == 0 then
return {reset(), ARGV[2] + ARGV[3], ARGV[4] - 1}
end if ARGV[1] >= redis.call('HGET', KEYS[1], 'start') and ARGV[1] <= redis.call('HGET', KEYS[1], 'end') then
return {
tonumber(redis.call('HINCRBY', KEYS[1], 'count', 1)) <= tonumber(ARGV[4]),
redis.call('HGET', KEYS[1], 'end'),
ARGV[4] - redis.call('HGET', KEYS[1], 'count')
}
end return {reset(), ARGV[2] + ARGV[3], ARGV[4] - 1}
LUA;
}
}

  

  

Lavavel5.5源代码 - 限流工具的更多相关文章

  1. Guava限流工具RateLimiter使用

    公司最近在推一个限流工具接入,提供的功能有单机限流.集群限流等.想了解一下限流的原理和设计,看了一下wiki里面有提到用了guava的ratelimiter工具,查了一些资料了解了一下 主要的限流算法 ...

  2. guava的限流工具RateLimiter使用

    guava限流工具使用 非常详细的一篇使用博客:https://www.cnblogs.com/yeyinfu/p/7316972.html 1,原理:Guava RateLimiter基于令牌桶算法 ...

  3. java限流工具类

    代码 import com.google.common.util.concurrent.RateLimiter; import java.util.concurrent.ConcurrentHashM ...

  4. java高并发系列 - 第15天:JUC中的Semaphore,最简单的限流工具类,必备技能

    这是java高并发系列第15篇文章 Semaphore(信号量)为多线程协作提供了更为强大的控制方法,前面的文章中我们学了synchronized和重入锁ReentrantLock,这2种锁一次都只能 ...

  5. Spring Cloud Zuul 限流详解(附源码)(转)

    在高并发的应用中,限流往往是一个绕不开的话题.本文详细探讨在Spring Cloud中如何实现限流. 在 Zuul 上实现限流是个不错的选择,只需要编写一个过滤器就可以了,关键在于如何实现限流的算法. ...

  6. 高并发之API接口限流

    在开发高并发系统时有三把利器用来保护系统:缓存.降级和限流 缓存 缓存的目的是提升系统访问速度和增大系统处理容量 降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再 ...

  7. Spring Cloud限流详解

    转自:https://blog.csdn.net/tracy38/article/details/78685707 在高并发的应用中,限流往往是一个绕不开的话题.本文详细探讨在Spring Cloud ...

  8. Spring Cloud限流思路及解决方案

    转自: http://blog.csdn.net/zl1zl2zl3/article/details/78683855 在高并发的应用中,限流往往是一个绕不开的话题.本文详细探讨在Spring Clo ...

  9. Spring Cloud(十二):Spring Cloud Zuul 限流详解(附源码)(转)

    前面已经介绍了很多zuul的功能,本篇继续介绍它的另一大功能.在高并发的应用中,限流往往是一个绕不开的话题.本文详细探讨在Spring Cloud中如何实现限流. 在 Zuul 上实现限流是个不错的选 ...

随机推荐

  1. 打杂程序员之ftp换成外网ip咋就登陆不上?

    主动模式ftp N连接到ftp的21端口.然后客户端开端口监听,并通过N+1端口发送命令给FTP服务器.服务器反过来连接用户本地端口. 被动模式解决从服务器到客户端数据端口的入口反向连接被防火墙过滤掉 ...

  2. 关于 C# 中接口的一些小结

    < 关于 C# 中“接口”的一些小结 > 对于 C# 这样的不支持多重继承的语言,很好的体现的层次性,但是有些时候多重继承的确有一些用武之地.   比如,在 Stream 类 . 图形设备 ...

  3. Aligning Plots in a Column作图列对齐

    Plot[Sin[x], {x, 0, Pi}] Plot[10000 Sin[x], {x, 0, Pi}] 直接作图左边无法对齐,影响图的美观.可以使用左边界空格实现列对齐,代码如下: optio ...

  4. Sde各类命令详解(sdemon 、sdelayer、sdeservice、sdetable、sdeconfig、SdeExport_SdeImport)

      Sdemon命令详解: http://wenku.baidu.com/view/3b53e8ec0975f46527d3e1c2.html 1.重建空间索引       D:\Program Fi ...

  5. angularJS 单页面 两个及以上个 ng-app 的处理方式

    <div ng-app="myApp1" ng-controller="myCtrl1"> 名: <input type="text ...

  6. Angular js 过滤器 笔记(转自菜鸟教程)

    1.uppercase,lowercase 大小写转换 {{ "lower cap string" | uppercase }} // 结果:LOWER CAP STRING {{ ...

  7. visual studio code配置项

    // 通过将设置放入设置文件中来覆盖设置. { //-------- 编辑器配置 -------- // 控制字体系列. "editor.fontFamily": "Co ...

  8. 学习笔记-java 集合

    背景: 看的是<java核心技术 第8版>,覆盖jdk1.6.主要是对集合全局和细节进行全面掌握,较深入的理解集合.本人对java比较熟悉,但是对于细节的理解不深,知识点还不全,这是知识的 ...

  9. FastDFS 初始

    FastDFS 详细介绍 FastDFS是一个开源的分布式文件系统,她对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适合以文件为 ...

  10. C#转Java之路之三:多线程并发容器即线程安全的容器

    CopyOnWriteArrayList 和 CopyOnWriteArraySet: 是java中两个比较重要的并发容器.适用于读多于写的场景,且集合数据不太大的场合. 特别是CopyOnWrite ...