优化代码
parent
16ab38200b
commit
3bc0fc69ff
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Contracts;
|
||||||
|
|
||||||
|
interface HashRedisInterface
|
||||||
|
{
|
||||||
|
public function get(string ...$key);
|
||||||
|
|
||||||
|
public function add(string $key, string $value);
|
||||||
|
|
||||||
|
public function rem(string ...$key);
|
||||||
|
|
||||||
|
public function incr(string $member, int $score);
|
||||||
|
|
||||||
|
public function count();
|
||||||
|
|
||||||
|
public function all();
|
||||||
|
|
||||||
|
public function isMember(string $key);
|
||||||
|
|
||||||
|
public function delete(string $key);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Contracts;
|
||||||
|
|
||||||
|
interface ListRedisInterface
|
||||||
|
{
|
||||||
|
public function push(string ...$value);
|
||||||
|
|
||||||
|
public function pop();
|
||||||
|
|
||||||
|
public function count();
|
||||||
|
|
||||||
|
public function clear();
|
||||||
|
|
||||||
|
public function all();
|
||||||
|
|
||||||
|
public function delete(string $key);
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Contracts;
|
||||||
|
|
||||||
|
interface LockRedisInterface
|
||||||
|
{
|
||||||
|
public function lock(string $key, $lockTime = 1, $timeout = 0);
|
||||||
|
|
||||||
|
public function delete(string $key);
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Contracts;
|
||||||
|
|
||||||
|
interface SetRedisInterface
|
||||||
|
{
|
||||||
|
public function count();
|
||||||
|
|
||||||
|
public function add(string ...$member);
|
||||||
|
|
||||||
|
public function rem(string ...$member);
|
||||||
|
|
||||||
|
public function isMember(string $member);
|
||||||
|
|
||||||
|
public function randMember($count = 1);
|
||||||
|
|
||||||
|
public function all();
|
||||||
|
|
||||||
|
public function delete(string $key);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Contracts;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
|
||||||
|
interface StreamRedisInterface
|
||||||
|
{
|
||||||
|
public function add(array $messages, $maxLen = 0, $isApproximate = false);
|
||||||
|
|
||||||
|
public function rem(string ...$id);
|
||||||
|
|
||||||
|
public function ack(string $group, string $id);
|
||||||
|
|
||||||
|
public function count();
|
||||||
|
|
||||||
|
public function all();
|
||||||
|
|
||||||
|
public function clear();
|
||||||
|
|
||||||
|
public function delete();
|
||||||
|
|
||||||
|
public function info(string $operation = 'stream');
|
||||||
|
|
||||||
|
public function run(Closure $closure, string $group, string $consumer, $count = 1);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Contracts;
|
||||||
|
|
||||||
|
interface StringRedisInterface
|
||||||
|
{
|
||||||
|
public function set(string $key, string $value, $expires = null);
|
||||||
|
|
||||||
|
public function get(string $key);
|
||||||
|
|
||||||
|
public function delete(string $key);
|
||||||
|
|
||||||
|
public function isExist(string $key);
|
||||||
|
|
||||||
|
public function ttl(string $key);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Contracts;
|
||||||
|
|
||||||
|
interface ZSetRedisInterface
|
||||||
|
{
|
||||||
|
public function add(string $member, float $score);
|
||||||
|
|
||||||
|
public function rem(string ...$member);
|
||||||
|
|
||||||
|
public function incr(string $member, float $score);
|
||||||
|
|
||||||
|
public function isMember(string $member);
|
||||||
|
|
||||||
|
public function count();
|
||||||
|
|
||||||
|
public function all($asc = true, $is_score = true);
|
||||||
|
|
||||||
|
public function rank($page = 1, $size = 10, $asc = true);
|
||||||
|
|
||||||
|
public function getMemberRank(string $member, $asc = true);
|
||||||
|
|
||||||
|
public function getMemberScore(string $member);
|
||||||
|
|
||||||
|
public function delete(string $key);
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Repository;
|
||||||
|
|
||||||
|
use App\Cache\Contracts\HashRedisInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis Hash
|
||||||
|
*
|
||||||
|
* @package App\Cache\Repository
|
||||||
|
*/
|
||||||
|
class HashRedis implements HashRedisInterface
|
||||||
|
{
|
||||||
|
use RedisTrait;
|
||||||
|
|
||||||
|
private $prefix = 'rds:hash';
|
||||||
|
|
||||||
|
private $name = 'default';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Hash 值
|
||||||
|
*
|
||||||
|
* @param string ...$key
|
||||||
|
* @return array|string
|
||||||
|
*/
|
||||||
|
public function get(string ...$key)
|
||||||
|
{
|
||||||
|
$func = function ($k) {
|
||||||
|
return (string)$this->redis()->hGet($this->getKeyName(), $k);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (func_num_args() == 1) return $func($key[0]);
|
||||||
|
|
||||||
|
$array = [];
|
||||||
|
foreach ($key as $arg) {
|
||||||
|
$array[$arg] = $func($arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置 Hash 值
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function add(string $key, string $value)
|
||||||
|
{
|
||||||
|
$this->redis()->hSet($this->getKeyName(), $key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除 hash 值
|
||||||
|
*
|
||||||
|
* @param string ...$key
|
||||||
|
* @return bool|int
|
||||||
|
*/
|
||||||
|
public function rem(string ...$key)
|
||||||
|
{
|
||||||
|
return $this->redis()->hDel($this->getKeyName(), ...$key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给指定元素累加值
|
||||||
|
*
|
||||||
|
* @param string $member 元素
|
||||||
|
* @param int $score
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function incr(string $member, int $score)
|
||||||
|
{
|
||||||
|
return $this->redis()->hincrby($this->getKeyName(), $member, $score);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Hash 中元素总数
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return (int)$this->redis()->hLen($this->getKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Hash 中所有元素
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function all()
|
||||||
|
{
|
||||||
|
return $this->redis()->hGetAll($this->getKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断 hash 表中是否存在某个值
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isMember(string $key)
|
||||||
|
{
|
||||||
|
return $this->redis()->hExists($this->getKeyName(), $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除 Hash 表
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function delete()
|
||||||
|
{
|
||||||
|
return (bool)$this->redis()->del($this->getKeyName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Repository;
|
||||||
|
|
||||||
|
use App\Cache\Contracts\ListRedisInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis List
|
||||||
|
*
|
||||||
|
* @package App\Cache\Repository
|
||||||
|
*/
|
||||||
|
class ListRedis implements ListRedisInterface
|
||||||
|
{
|
||||||
|
use RedisTrait;
|
||||||
|
|
||||||
|
private $prefix = 'rds:list';
|
||||||
|
|
||||||
|
private $name = 'default';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push 队列任务
|
||||||
|
*
|
||||||
|
* @param string ...$value
|
||||||
|
* @return false|int
|
||||||
|
*/
|
||||||
|
public function push(string ...$value)
|
||||||
|
{
|
||||||
|
return $this->redis()->lPush($this->getKeyName(), ...$value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取队列中的任务
|
||||||
|
*
|
||||||
|
* @return bool|mixed
|
||||||
|
*/
|
||||||
|
public function pop()
|
||||||
|
{
|
||||||
|
return $this->redis()->rPop($this->getKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取列表中元素总数
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return (int)$this->redis()->lLen($this->getKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除列表中所有元素
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function clear()
|
||||||
|
{
|
||||||
|
return $this->redis()->lTrim($this->getKeyName(), 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取列表中所有元素
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function all()
|
||||||
|
{
|
||||||
|
return $this->redis()->lRange($this->getKeyName(), 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除 List
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function delete()
|
||||||
|
{
|
||||||
|
return (bool)$this->redis()->del($this->getKeyName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Repository;
|
||||||
|
|
||||||
|
use App\Cache\Contracts\LockRedisInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis Lock
|
||||||
|
*
|
||||||
|
* @package App\Cache\Repository
|
||||||
|
*/
|
||||||
|
class LockRedis implements LockRedisInterface
|
||||||
|
{
|
||||||
|
use RedisTrait;
|
||||||
|
|
||||||
|
private $prefix = 'rds:lock';
|
||||||
|
|
||||||
|
private $lockValue = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取是毫秒时间戳
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private function time()
|
||||||
|
{
|
||||||
|
return intval(microtime(true) * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Redis 锁
|
||||||
|
*
|
||||||
|
* @param string $key 锁标识
|
||||||
|
* @param int $lockTime 过期时间/秒
|
||||||
|
* @param int $timeout 获取超时/毫秒
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function lock(string $key, $lockTime = 1, $timeout = 0)
|
||||||
|
{
|
||||||
|
$lockName = $this->getCacheKey($key);
|
||||||
|
|
||||||
|
$start = $this->time();
|
||||||
|
do {
|
||||||
|
$lock = $this->redis()->set($lockName, $this->lockValue, ['nx', 'ex' => $lockTime]);
|
||||||
|
if ($lock || $timeout === 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认 0.1 秒一次取锁
|
||||||
|
usleep(100000);
|
||||||
|
} while ($this->time() < $start + $timeout);
|
||||||
|
|
||||||
|
return $lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 释放 Redis 锁
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function delete(string $key)
|
||||||
|
{
|
||||||
|
$script = <<<LAU
|
||||||
|
if redis.call("GET", KEYS[1]) == ARGV[1] then
|
||||||
|
return redis.call("DEL", KEYS[1])
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
LAU;
|
||||||
|
|
||||||
|
return $this->redis()->eval($script, [$this->getCacheKey($key), $this->lockValue,], 1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Repository;
|
||||||
|
|
||||||
|
use Hyperf\Redis\Redis;
|
||||||
|
|
||||||
|
trait RedisTrait
|
||||||
|
{
|
||||||
|
private static $instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单例
|
||||||
|
*
|
||||||
|
* @return static
|
||||||
|
*/
|
||||||
|
static public function getInstance()
|
||||||
|
{
|
||||||
|
if (!(self::$instance instanceof static)) {
|
||||||
|
self::$instance = new static();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Redis 连接
|
||||||
|
*
|
||||||
|
* @return Redis|mixed
|
||||||
|
*/
|
||||||
|
protected function redis()
|
||||||
|
{
|
||||||
|
return redis();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存 KEY
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function getCacheKey(string $key)
|
||||||
|
{
|
||||||
|
return sprintf('%s:%s', trim($this->prefix, ':'), trim($key, ':'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存 KEY
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function getKeyName()
|
||||||
|
{
|
||||||
|
return $this->getCacheKey($this->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载数据到缓存
|
||||||
|
*/
|
||||||
|
public function reload()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Cache\Repository;
|
||||||
|
|
||||||
|
use App\Cache\Contracts\SetRedisInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis Set
|
||||||
|
*
|
||||||
|
* @package App\Cache\Repository
|
||||||
|
*/
|
||||||
|
class SetRedis implements SetRedisInterface
|
||||||
|
{
|
||||||
|
use RedisTrait;
|
||||||
|
|
||||||
|
private $prefix = 'rds:set';
|
||||||
|
|
||||||
|
private $name = 'default';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加集合元素
|
||||||
|
*
|
||||||
|
* @param string ...$member
|
||||||
|
* @return bool|int
|
||||||
|
*/
|
||||||
|
public function add(string ...$member)
|
||||||
|
{
|
||||||
|
return $this->redis()->sAdd($this->getKeyName(), ...$member);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除集合元素
|
||||||
|
*
|
||||||
|
* @param string ...$member
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function rem(string ...$member)
|
||||||
|
{
|
||||||
|
return $this->redis()->sRem($this->getKeyName(), ...$member);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是集合元素
|
||||||
|
*
|
||||||
|
* @param string $member
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isMember(string $member)
|
||||||
|
{
|
||||||
|
return $this->redis()->sIsMember($this->getKeyName(), $member);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取集合中所有元素
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function all()
|
||||||
|
{
|
||||||
|
return $this->redis()->sMembers($this->getKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取集合中元素个数
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return $this->redis()->scard($this->getKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取随机集合中的元素
|
||||||
|
*
|
||||||
|
* @param int $count
|
||||||
|
* @return array|bool|mixed|string
|
||||||
|
*/
|
||||||
|
public function randMember($count = 1)
|
||||||
|
{
|
||||||
|
return $this->redis()->sRandMember($this->getKeyName(), $count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除 Set 集合表
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function delete()
|
||||||
|
{
|
||||||
|
return (bool)$this->redis()->del($this->getKeyName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Repository;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use App\Cache\Contracts\StreamRedisInterface;
|
||||||
|
|
||||||
|
class StreamRedis implements StreamRedisInterface
|
||||||
|
{
|
||||||
|
use RedisTrait;
|
||||||
|
|
||||||
|
private $prefix = 'rds:stream';
|
||||||
|
|
||||||
|
private $name = 'default';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加消息
|
||||||
|
*
|
||||||
|
* @param array $messages 消息信息
|
||||||
|
* @param int $maxLen 消息队列最大长度
|
||||||
|
* @param false $isApproximate
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function add(array $messages, $maxLen = 0, $isApproximate = false)
|
||||||
|
{
|
||||||
|
return $this->redis()->xAdd($this->getKeyName(), '*', $messages, $maxLen, $isApproximate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除消息
|
||||||
|
*
|
||||||
|
* @param string ...$id 消息ID
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function rem(string ...$id)
|
||||||
|
{
|
||||||
|
return $this->redis()->xDel($this->getKeyName(), $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消费者消息确认
|
||||||
|
*
|
||||||
|
* @param string $group 消费组
|
||||||
|
* @param string $id 消息ID
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function ack(string $group, string $id)
|
||||||
|
{
|
||||||
|
return $this->redis()->xAck($this->getKeyName(), $group, [$id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取消息总数
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return $this->redis()->xLen($this->getKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有消息
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function all()
|
||||||
|
{
|
||||||
|
return $this->redis()->xRange($this->getKeyName(), '-', '+');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空消息队列
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function clear()
|
||||||
|
{
|
||||||
|
foreach ($this->all() as $k => $v) {
|
||||||
|
$this->rem($k);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除消息队列 KEY
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function delete()
|
||||||
|
{
|
||||||
|
return $this->redis()->del($this->getKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对消息队列进行修剪,限制长度
|
||||||
|
*
|
||||||
|
* @param int $maxLen
|
||||||
|
* @param bool $isApproximate
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function trim(int $maxLen, bool $isApproximate = false)
|
||||||
|
{
|
||||||
|
return $this->redis()->xTrim($this->getKeyName(), $maxLen, $isApproximate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function group($operation, $group, $msgId = '', $mkStream = false)
|
||||||
|
{
|
||||||
|
return $this->redis()->xGroup($operation, $this->getKeyName(), $group, $msgId, $mkStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function pending($group, $start = null, $end = null, $count = null, $consumer = null)
|
||||||
|
{
|
||||||
|
return $this->redis()->xPending($this->getKeyName(), $group, $start, $end, $count, $consumer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看队列信息
|
||||||
|
*
|
||||||
|
* @param string $operation [stream:队列信息,groups:消费组信息]
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function info(string $operation = 'stream')
|
||||||
|
{
|
||||||
|
return $this->redis()->xInfo($operation, $this->getKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 运行消息队列
|
||||||
|
*
|
||||||
|
* @param Closure $closure 闭包函数
|
||||||
|
* @param string $group 消费组
|
||||||
|
* @param string $consumer 消费者
|
||||||
|
* @param int $count 同时获取的任务个数
|
||||||
|
*/
|
||||||
|
public function run(Closure $closure, string $group, string $consumer, $count = 1)
|
||||||
|
{
|
||||||
|
$this->group('create', $group, '0');
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
$tasks = $this->redis()->xReadGroup($group, $consumer, [$this->getKeyName() => '>'], $count);
|
||||||
|
if (empty($tasks)) {
|
||||||
|
sleep(1);// 获取不到任务,延时一秒
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($tasks[$this->getKeyName()] as $id => $task) {
|
||||||
|
if ($closure($id, $task)) {
|
||||||
|
$this->ack($group, $id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Repository;
|
||||||
|
|
||||||
|
use App\Cache\Contracts\StringRedisInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String Cache
|
||||||
|
*
|
||||||
|
* @package App\Cache\Repository
|
||||||
|
*/
|
||||||
|
class StringRedis implements StringRedisInterface
|
||||||
|
{
|
||||||
|
use RedisTrait;
|
||||||
|
|
||||||
|
private $prefix = 'rds:string';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置缓存
|
||||||
|
*
|
||||||
|
* @param string $key 缓存标识
|
||||||
|
* @param string $value 缓存数据
|
||||||
|
* @param null $expires 过期时间
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function set(string $key, string $value, $expires = null)
|
||||||
|
{
|
||||||
|
return $this->redis()->set($this->getCacheKey($key), $value, $expires);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存数据
|
||||||
|
*
|
||||||
|
* @param string $key 缓存标识
|
||||||
|
* @return false|mixed|string
|
||||||
|
*/
|
||||||
|
public function get(string $key)
|
||||||
|
{
|
||||||
|
return $this->redis()->get($this->getCacheKey($key));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除 String 缓存
|
||||||
|
*
|
||||||
|
* @param string $key 缓存标识
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function delete(string $key)
|
||||||
|
{
|
||||||
|
return (bool)$this->redis()->del($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断缓存是否存在
|
||||||
|
*
|
||||||
|
* @param string $key 缓存标识
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isExist(string $key)
|
||||||
|
{
|
||||||
|
return (bool)$this->get($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存过期时间
|
||||||
|
*
|
||||||
|
* @param string $key 缓存标识
|
||||||
|
* @return bool|int
|
||||||
|
*/
|
||||||
|
public function ttl(string $key)
|
||||||
|
{
|
||||||
|
return $this->redis()->ttl($this->getCacheKey($key));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,169 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cache\Repository;
|
||||||
|
|
||||||
|
use App\Cache\Contracts\ZSetRedisInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ZSetRedis
|
||||||
|
*
|
||||||
|
* @package App\Cache\Repository
|
||||||
|
*/
|
||||||
|
class ZSetRedis implements ZSetRedisInterface
|
||||||
|
{
|
||||||
|
use RedisTrait;
|
||||||
|
|
||||||
|
private $prefix = 'rds:zset';
|
||||||
|
|
||||||
|
private $name = 'default';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加有序集合元素
|
||||||
|
*
|
||||||
|
* @param string $member
|
||||||
|
* @param float $score
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function add(string $member, float $score)
|
||||||
|
{
|
||||||
|
return $this->redis()->zAdd($this->getKeyName(), $score, $member);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除有序集合元素
|
||||||
|
*
|
||||||
|
* @param string ...$member
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function rem(string ...$member)
|
||||||
|
{
|
||||||
|
return $this->redis()->zRem($this->getKeyName(), ...$member);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给指定元素累加分数
|
||||||
|
*
|
||||||
|
* @param string $member 元素
|
||||||
|
* @param float $score
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function incr(string $member, float $score)
|
||||||
|
{
|
||||||
|
return $this->redis()->zIncrBy($this->getKeyName(), $score, $member);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取有序集合元素总数
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return $this->redis()->zCard($this->getKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取有序集合所有元素
|
||||||
|
*
|
||||||
|
* @param bool $asc [true:从高到低排序,false:从低到高排序]
|
||||||
|
* @param bool $is_score 是否需要分数值
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function all($asc = true, $is_score = true)
|
||||||
|
{
|
||||||
|
return $this->redis()->{$asc ? 'zRevRange' : 'zRange'}($this->getKeyName(), 0, -1, $is_score);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取排行榜单
|
||||||
|
*
|
||||||
|
* @param int $page 分页
|
||||||
|
* @param int $size 分页大小
|
||||||
|
* @param bool $asc [true:从高到低排序,false:从低到高排序]
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rank($page = 1, $size = 10, $asc = true)
|
||||||
|
{
|
||||||
|
$count = $this->count();
|
||||||
|
|
||||||
|
[$start, $end] = $asc ? ['+inf', '-inf'] : ['-inf', '+inf'];
|
||||||
|
|
||||||
|
$rows = $this->redis()->{$asc ? 'zRevRangeByScore' : 'zRangeByScore'}($this->getKeyName(), $start, $end, [
|
||||||
|
'withscores' => true,
|
||||||
|
'limit' => [($page - 1) * $size, $size]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$ranks = [];
|
||||||
|
foreach ($rows as $node => $score) {
|
||||||
|
$ranks[] = [
|
||||||
|
'rank' => $this->getMemberRank($node, $asc),
|
||||||
|
'node' => $node,
|
||||||
|
'score' => $score
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'count' => $count,
|
||||||
|
'page' => $page,
|
||||||
|
'size' => $size,
|
||||||
|
'ranks' => $ranks
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定区间分数
|
||||||
|
*
|
||||||
|
* @param string $start 最低分值
|
||||||
|
* @param string $end 最高分值
|
||||||
|
* @param array $options
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function range(string $start, string $end, array $options = [])
|
||||||
|
{
|
||||||
|
return $this->redis()->zRangeByScore($this->getKeyName(), $start, $end, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定元素的排名
|
||||||
|
*
|
||||||
|
* @param string $member 元素
|
||||||
|
* @param bool $asc [true:从高到低排序,false:从低到高排序]
|
||||||
|
* @return false|int
|
||||||
|
*/
|
||||||
|
public function getMemberRank(string $member, $asc = true)
|
||||||
|
{
|
||||||
|
return $this->redis()->{$asc ? 'zRevRank' : 'zRank'}($this->getKeyName(), $member) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定元素的分数
|
||||||
|
*
|
||||||
|
* @param string $member 元素
|
||||||
|
* @return bool|float
|
||||||
|
*/
|
||||||
|
public function getMemberScore(string $member)
|
||||||
|
{
|
||||||
|
return $this->redis()->zScore($this->getKeyName(), $member);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是集合元素
|
||||||
|
*
|
||||||
|
* @param string $member
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isMember(string $member)
|
||||||
|
{
|
||||||
|
return $this->redis()->zScore($this->getCacheKey($this->name), $member);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除 ZSet 有序集合表
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function delete()
|
||||||
|
{
|
||||||
|
return (bool)$this->redis()->del($this->getKeyName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Command;
|
||||||
|
|
||||||
|
use App\Cache\Repository\HashRedis;
|
||||||
|
use App\Cache\Repository\ListRedis;
|
||||||
|
use App\Cache\Repository\LockRedis;
|
||||||
|
use App\Cache\Repository\SetRedis;
|
||||||
|
use App\Cache\Repository\StreamRedis;
|
||||||
|
use App\Cache\Repository\StringRedis;
|
||||||
|
use App\Cache\Repository\ZSetRedis;
|
||||||
|
use Hyperf\Command\Command as HyperfCommand;
|
||||||
|
use Hyperf\Command\Annotation\Command;
|
||||||
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Command
|
||||||
|
*/
|
||||||
|
class TestCommand extends HyperfCommand
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var ContainerInterface
|
||||||
|
*/
|
||||||
|
protected $container;
|
||||||
|
|
||||||
|
public function __construct(ContainerInterface $container)
|
||||||
|
{
|
||||||
|
$this->container = $container;
|
||||||
|
|
||||||
|
parent::__construct('test:command');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configure()
|
||||||
|
{
|
||||||
|
parent::configure();
|
||||||
|
$this->setDescription('Hyperf Demo Command');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
//$lock = LockRedis::getInstance();
|
||||||
|
//var_dump($lock->delete('ttt'));
|
||||||
|
//var_dump($lock->lock('ttt', 180));
|
||||||
|
|
||||||
|
//$string = StringRedis::getInstance();
|
||||||
|
//var_dump($string->set('yuandong', 'dong', 30));
|
||||||
|
//var_dump($string->ttl('yuandong'));
|
||||||
|
//var_dump($string->isExist('yuandong'));
|
||||||
|
|
||||||
|
//$hash = HashRedis::getInstance();
|
||||||
|
//for ($i = 0; $i < 10; $i++) {
|
||||||
|
// $hash->add('user:' . $i, (string)rand(0, 100));
|
||||||
|
//}
|
||||||
|
//var_dump($hash->count());
|
||||||
|
//var_dump($hash->all());
|
||||||
|
//var_dump($hash->isMember('user:1'));
|
||||||
|
//var_dump($hash->rem('user:3'));
|
||||||
|
//var_dump($hash->get('user:6'));
|
||||||
|
//$hash->incr('user:6',11);
|
||||||
|
//var_dump($hash->get('user:6'));
|
||||||
|
|
||||||
|
//$list = ListRedis::getInstance();
|
||||||
|
//$list->push('1','2','3','4','5');
|
||||||
|
//var_dump($list->all());
|
||||||
|
//var_dump($list->clear());
|
||||||
|
//var_dump($list->count());
|
||||||
|
|
||||||
|
//$set = SetRedis::getInstance();
|
||||||
|
//$set->add('user1','user:2','user:3');
|
||||||
|
//var_dump($set->all());
|
||||||
|
//var_dump($set->count());
|
||||||
|
//var_dump($set->isMember('user:3'));
|
||||||
|
//var_dump($set->randMember(2));
|
||||||
|
|
||||||
|
//$zset = ZSetRedis::getInstance();
|
||||||
|
//for ($i = 0; $i < 10; $i++) {
|
||||||
|
// $zset->add('user:' . $i, rand(0, 100));
|
||||||
|
//}
|
||||||
|
//var_dump($zset->count());
|
||||||
|
//var_dump($zset->all());
|
||||||
|
//var_dump($zset->getMemberScore('user:2'));
|
||||||
|
//var_dump($zset->getMemberRank('user:2'));
|
||||||
|
//var_dump($zset->rank());
|
||||||
|
//var_dump($zset->range('20','60'));
|
||||||
|
|
||||||
|
//$stream = StreamRedis::getInstance();
|
||||||
|
//var_dump($stream->info());
|
||||||
|
//for ($i = 0; $i < 10; $i++) {
|
||||||
|
// $stream->add([
|
||||||
|
// 'user_id' => $i,
|
||||||
|
// 'time' => time()
|
||||||
|
// ]);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//$stream->run(function (string $id, array $data): bool {
|
||||||
|
// echo PHP_EOL . " 消息ID: {$id} , 任务数据: " . json_encode($data);
|
||||||
|
//
|
||||||
|
// return true;
|
||||||
|
//}, 'default', 'default');
|
||||||
|
}
|
||||||
|
}
|
|
@ -226,7 +226,7 @@ class ContactsController extends CController
|
||||||
{
|
{
|
||||||
$num = ApplyNumCache::get($this->uid());
|
$num = ApplyNumCache::get($this->uid());
|
||||||
return $this->response->success([
|
return $this->response->success([
|
||||||
'unread_num' => $num ? $num : 0
|
'unread_num' => $num ?: 0
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue