app('redis')->connection('default')->funnel('key000')
// 每个资源最大锁定10秒自动过期,只有60个资源(并发),在3秒内获取不到锁抛出异常
->releaseAfter(10)->limit(60)->block(3)
->then(function () {
// 获取锁成功,执行业务
}, function () {
// 获取锁失败
return false;
});

  

<?php

namespace Illuminate\Redis\Limiters;

use Illuminate\Contracts\Redis\LimiterTimeoutException;

class ConcurrencyLimiter
{
/**
* The Redis factory implementation.
*
* @var \Illuminate\Redis\Connections\Connection
*/
protected $redis; /**
* The name of the limiter.
*
* @var string
*/
protected $name; /**
* The allowed number of concurrent tasks.
*
* @var int
*/
protected $maxLocks; /**
* The number of seconds a slot should be maintained.
*
* @var int
*/
protected $releaseAfter; /**
* Create a new concurrency limiter instance.
*
* @param \Illuminate\Redis\Connections\Connection $redis
* @param string $name
* @param int $maxLocks
* @param int $releaseAfter
* @return void
*/
public function __construct($redis, $name, $maxLocks, $releaseAfter)
{
$this->name = $name;
$this->redis = $redis;
$this->maxLocks = $maxLocks;
$this->releaseAfter = $releaseAfter;
} /**
* 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 (! $slot = $this->acquire()) {
if (time() - $timeout >= $starting) {
throw new LimiterTimeoutException;
} usleep(250 * 1000);
} if (is_callable($callback)) {
return tap($callback(), function () use ($slot) {
$this->release($slot);
});
} return true;
} /**
* Attempt to acquire the lock.
*
* @return mixed
*/
protected function acquire()
{
$slots = array_map(function ($i) {
return $this->name.$i;
}, range(1, $this->maxLocks)); return $this->redis->eval($this->luaScript(), count($slots),
...array_merge($slots, [$this->name, $this->releaseAfter])
);
} /**
* Get the Lua script for acquiring a lock.
*
* KEYS - The keys that represent available slots
* ARGV[1] - The limiter name
* ARGV[2] - The number of seconds the slot should be reserved
*
* @return string
*/
protected function luaScript()
{
return <<<'LUA'
for index, value in pairs(redis.call('mget', unpack(KEYS))) do
if not value then
redis.call('set', ARGV[1]..index, "1", "EX", ARGV[2])
return ARGV[1]..index
end
end
LUA;
} /**
* Release the lock.
*
* @param string $key
* @return void
*/
protected function release($key)
{
$this->redis->del($key);
}
}

  

Lavavel5.5源代码 - 并发数控制的更多相关文章

  1. Linux Shell多进程并发以及并发数控制

    1. 基础知识准备 1.1. linux后台进程 Unix是一个多任务系统,允许多用户同时运行多个程序.shell的元字符&提供了在后台运行不需要键盘输入的程序的方法.输入命令后,其后紧跟&a ...

  2. Java并发工具类之并发数控制神器Semaphore

    Semaphore(信号量)使用来控制通知访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源. 我们可以这么理解Semaphore,比如一个厕所只有6个坑,同时只能满足6个人上厕所( ...

  3. GO瞬间并发数控制

    var wg2 sync.WaitGroup wg2.Add(nums) xc :=0 parallelNum := plt.MaxParallel var waitCount int32 = 0 f ...

  4. Shell-使用mkfifo实现多任务并发及并发数控制

    以下为代码实现的一个模拟场景:3个生产者,在不断提供服务,处理需求,假设1s处理一个. 20个消费者,在不断消耗供给产品,提交需求,假设3s消耗一个. 情景分析:由于消费者的提交需求能力 和 生产者处 ...

  5. Tomcat并发数优化,修改service.xml性能调优 增加最大并发连接数

    可以在控制台的启动信息里看见,默认状态下没有被打开nio配置,启动时的信息,如下: 2010-2-1 12:59:40 org.apache.coyote.http11.Http11Protocol ...

  6. 利用apache限制IP并发数和下载流量控制

    一,为什么要对IP并发数,下载流量进行控制 说正题之前,先给大家讲个故事,那是在2007年,我进了一家公司,当时我们正在给达芙妮做电子商务网,www.idaphne.com.从三月份开始做的吧,九月份 ...

  7. dubbo是如何控制并发数和限流的?

    ExecuteLimitFilter ExecuteLimitFilter ,在服务提供者,通过 的 "executes" 统一配置项开启: 表示每服务的每方法最大可并行执行请求数 ...

  8. 高并发实时弹幕系统 并发数一定是可以进行控制的 每个需要异步处理开启的 Goroutine(Go 协程)都必须预先创建好固定的个数,如果不提前进行控制,那么 Goroutine 就随时存在爆发的可能。

    小结: 1.内存优化1.一个消息一定只有一块内存使用 Job 聚合消息,Comet 指针引用. 2.一个用户的内存尽量放到栈上内存创建在对应的用户 Goroutine(Go 程)中. 3.内存由自己控 ...

  9. 吞吐量(Throughput)、QPS、并发数、响应时间(RT)对系统性能的影响

    首先对吞吐量().QPS.并发数.响应时间(RT)几个概念一直比较模糊,也不知道哪些指标可以较好的衡量系统的性能.今天特意查了些资料做一些记录:首先看一些概念(来自百度百科) 1. 响应时间(RT) ...

随机推荐

  1. 关于Android中的ViewTreeObserver

    ViewTreeObserver结构 extends Object java.lang.Object ↳ android.view.ViewTreeObserver ViewTreeObserver概 ...

  2. IOS 录音(AVAudioRecorder)

    #import "HMViewController.h" #import <AVFoundation/AVFoundation.h> @interface HMView ...

  3. 创建git项目的feature分支以及下载特定分支的仓库代码

    在掌握了基础git的使用后可以按照这个步骤来: 下载项目:git clone <仓库地址>如果要下载非master的某分支代码:git clone -b <分支名> <仓 ...

  4. VI编辑器查找替换

    1.Vi下进行查找 VI命令模式下:输入“/要查找的词”回车就会进入查找,你可以按“n”查找下一个,按“N”查找上一个.类似查找命令“?”与“/”的区别是“/”为向下查找,“?”为向上查找. 2.Vi ...

  5. 原生ajax接收json字符串(简单介绍)

    什么是json? JSON的全称是 Javascript Object Notation(javascript对象表示法),是基于javascript对象字面量,如果单从眼睛看,JSON里的数据是被保 ...

  6. Android学习笔记_56_应用Tween动画 (渐变、缩放、位移、旋转)

    1.实现listview每个项先向右移动,再向左移动(回到原来位置) TranslateAnimation ta = new TranslateAnimation( Animation.RELATIV ...

  7. 188. Best Time to Buy and Sell Stock IV——LeetCode

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  8. CSS实战3

    1. z-index  层级   div 层 <!DOCTYPE html> <html> <head lang="en"> <meta ...

  9. Linux学习——目录结构

    在Linux当中,一切皆为文件,包括目录也属于文件.FHS(Filesystem Hierarchy Standard)的出现对文件目录系统做出了统一规范. Linux的目录结构: / - 根 /bi ...

  10. Java并发编程:JMM和volatile关键字

    转载请标明出处: http://blog.csdn.net/forezp/article/details/77580491 本文出自方志朋的博客 Java内存模型 随着计算机的CPU的飞速发展,CPU ...