点开工具、字典、anything


2019-06-21周报

<h2>redis锁</h2> <p>一种为了避免access_token过期时,处理并发请求时用到的redis锁</p> <p><strong>需要用到的redis缓存</strong> 锁标志:$lock = string:{action_name}:access_token:lock access_token储存:$accessToken = string:{action_name}:access_token</p> <p><strong>设计思路</strong> 当需要刷新access_token时,先使用Redis的setnx写入锁并expire过期时间,写入成功则继续往下执行access_token获取方法,获取access_token后写入缓存$accessToken,再将锁删除;如果写锁失败,检测获取$accessToken,获取到值返回,否则返回再次尝试拿锁。 <img src="https://www.showdoc.cc/server/api/common/visitfile/sign/57d22526205d253fb24d136be2671a16?showdoc=.jpg" alt="" /></p> <pre><code>public function refreshToken() { $redis = Redis::connection(); $redis-&gt;del($this-&gt;redisKey['access_token']); //删除原access_token $times = 0; while ($times &lt; 20) { //设置循环时间大于锁的生命,如果并发时前几次请求失败,后面还可以续上 $setLock = $redis-&gt;setnx($this-&gt;redisKey['access_token_lock'], 1); //写锁 if ($setLock) { //写锁成功,发起请求 $redis-&gt;expire($this-&gt;redisKey['access_token_lock'], 5); //设置锁的生命,如果本次请求失败,才能解锁进行下一次锁操作 $accessToken = FUNCTION::requestAccessToken(); //请求接口 if ($accessToken) $redis-&gt;setex($this-&gt;redisKey['access_token'], EXPIRETIME, $accessToken); //成功获取到access_token后,写入缓存 return $accessToken; } $accessToken = $redis-&gt;get($this-&gt;redisKey['access_token']); //检测是否已有可用access_token if ($accessToken) return $accessToken; usleep(500000); $times++; } return false; }</code></pre> <h3>虽然这种方式比较符合业务情况,但是对redis锁来说没有活用性,因此把锁独立出来,可以供多处使用</h3> <p>一个业务要拿到<strong>锁的名称</strong>后才能继续往下执行,<strong>当业务完成后,记得删锁</strong></p> <pre><code class="language-php">public function redisLock($redisKey) { $times = 0; while ($times &lt; 2000) { $setLock = $this-&gt;redis-&gt;setnx($redisKey . '_lock', 1); if ($setLock) { $this-&gt;redis-&gt;expire($redisKey . '_lock', 10); return $redisKey . '_lock'; } usleep(5000); $times++; } return false; }</code></pre> <h2>MongoDB</h2> <p>文档:<a href="https://docs.mongodb.com/manual/reference/command/">https://docs.mongodb.com/manual/reference/command/</a> <strong>实例化链接</strong></p> <p><code>$this-&gt;mongoManage = new \MongoDB\Driver\Manager("mongodb://username:password@127.0.0.1:20000/database")</code></p> <p><strong>直接执行commonds来进行aggregate(聚合)、count(计数)、group(分组)、distinct(去重)等操作</strong></p> <pre><code class="language-php">//$command:需要执行的命令 public function command($command) { $commandObj = new \MongoDB\Driver\Command($command); $cursor = $this-&gt;mongoManage-&gt;executeCommand($this-&gt;config['mongo_db'], $commandObj); return $cursor-&gt;toArray(); }</code></pre> <p><strong>collections筛选commands</strong></p> <pre><code class="language-php">$command = [ 'listCollections' =&gt; 1, 'filter' =&gt; ['name' =&gt; ['$regex' =&gt; $tableKey]], ]; $result = $this-&gt;command($command);</code></pre> <p>当使用aggregate的commands时,如果要用到$match筛选,务必把$match放在0位</p>

页面列表

ITEM_HTML