class RedisCli {
protected static $redis;
public static function getRedisInstance($conf){
if(isset(self::$redis)){
return self::$redis;
}
try{
$redis = new \Redis();
$re = $redis->connect($conf['host'], $conf['port']);
if(!$re){
throw new \Exception('connect redis error');
}
if(isset($conf['auth'])){
$re = $redis->auth($conf['auth']);
if(!$re){
throw new \Exception('redis auth error');
}
}
self::$redis = $redis;
return $redis;
}catch(\Exception $e){
throw new \Exception($e->getMessage());
}
}
public static function addOrder($redis, $key, $orderId){
$ttl = time() - 600;
$re = $redis->zadd($key, $ttl, $orderId);
return $re;
}
public static function getOrders($redis, $key, $num = 1){
/*
array(1) {
[3334]=>
float(1573703310)
}
*/
$orders = $redis->zrangebyscore($key, 0, time(), ['limit'=>[0, $num], 'withscores'=>TRUE]);
if(!$orders){
return [];
}
// 移除元素
foreach($orders as $k => $v){
$redis->zrem($key, $k);
}
return $orders;
}
public static function getAndDeleteOrder($redis, $key, $num = 1){
$script = " local score= redis.call(
'ZRANGEBYSCORE', KEYS[1], ARGV[1], ARGV[2], 'WITHSCORES' , 'LIMIT' , ARGV[3] , ARGV[4]
)
if score ~= false and #score ~= 0 then
local i = 1
while i <= #score do
redis.call('ZREM', KEYS[1] , score[i])
i=i+2
end
end
return score";
$result = $redis->eval($script, [$key, 0, time(), 0, $num], 1);
/*
$redis->eval的返回结果:
array(4) {
[0]=>
string(4) "3334"
[1]=>
string(10) "1573701647"
[2]=>
string(4) "3333"
[3]=>
string(10) "1573702072"
}
*/
$return = [];
$count = count($result);
if($count > 0){
for($i = 0; $i < $count; $i+=2){
$return[$result[$i]] = $result[$i + 1];
}
}
/*
array(1) {
[3334]=>
string(10) "1573702856"
}
*/
return $return;
}
}
$conf = ['host'=>'127.0.0.1', 'port'=>6379, 'auth'=>'123456'];
$redis = RedisCli::getRedisInstance($conf);
$key = 'orderkey';
$orderId = 3334;
// 添加
RedisCli::addOrder($redis, $key, $orderId);
// 消费,由于可能存在多进程的并发,使用Lua优化版,
while(true){
try{
// $data = RedisCli::getOrders($redis, $key);
$data = RedisCli::getAndDeleteOrder($redis, $key);
if(empty($data)){
sleep(1);
}else{
var_dump($data);
}
}catch(\Exception $e){
}
}