代码优化
parent
cad0468af7
commit
20735e551e
|
@ -11,11 +11,9 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Amqp\Consumer;
|
||||
|
||||
use App\Model\Group\Group;
|
||||
use Hyperf\Amqp\Annotation\Consumer;
|
||||
use Hyperf\Amqp\Result;
|
||||
use Hyperf\Amqp\Message\ConsumerMessage;
|
||||
use Hyperf\Redis\Redis;
|
||||
use Hyperf\Amqp\Message\Type;
|
||||
use Hyperf\Amqp\Builder\QueueBuilder;
|
||||
use PhpAmqpLib\Message\AMQPMessage;
|
||||
|
@ -26,9 +24,11 @@ use App\Model\Chat\ChatRecordsCode;
|
|||
use App\Model\Chat\ChatRecordsFile;
|
||||
use App\Model\Chat\ChatRecordsInvite;
|
||||
use App\Model\Chat\ChatRecordsForward;
|
||||
use App\Model\Group\Group;
|
||||
use App\Service\SocketClientService;
|
||||
use App\Service\SocketRoomService;
|
||||
use App\Constants\SocketConstants;
|
||||
use App\Cache\Repository\LockRedis;
|
||||
|
||||
/**
|
||||
* 消息推送消费者队列
|
||||
|
@ -125,11 +125,9 @@ class ChatMessageConsumer extends ConsumerMessage
|
|||
public function consumeMessage($data, AMQPMessage $message): string
|
||||
{
|
||||
if (isset($data['event'])) {
|
||||
$redis = container()->get(Redis::class);
|
||||
|
||||
// [加锁]防止消息重复消费
|
||||
$lockName = sprintf('ws:message-lock:%s:%s', SERVER_RUN_ID, $data['uuid']);
|
||||
if (!$redis->set($lockName, 1, ['nx', 'ex' => 60])) {
|
||||
$lockName = sprintf('ws-message:%s-%s', SERVER_RUN_ID, $data['uuid']);
|
||||
if (LockRedis::getInstance()->lock($lockName, 60)) {
|
||||
return Result::ACK;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,6 @@ class LockRedis implements LockRedisInterface
|
|||
end
|
||||
LAU;
|
||||
|
||||
return $this->redis()->eval($script, [$this->getCacheKey($key), $this->lockValue,], 1);
|
||||
return $this->redis()->eval($script, [$this->getCacheKey($key), $this->lockValue], 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,9 @@ use Hyperf\HttpServer\Annotation\Middleware;
|
|||
use App\Middleware\JWTAuthMiddleware;
|
||||
use App\Service\ArticleService;
|
||||
use App\Service\UploadService;
|
||||
use App\Support\RedisLock;
|
||||
use Hyperf\Utils\Str;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use App\Cache\Repository\LockRedis;
|
||||
|
||||
/**
|
||||
* Class ArticleController
|
||||
|
@ -177,14 +177,14 @@ class ArticleController extends CController
|
|||
'sort_type' => 'required|in:1,2'
|
||||
]);
|
||||
|
||||
$lockKey = "article_class_sort:{$params['class_id']}_{$params['sort_type']}";
|
||||
$lockKey = "article:sort_{$params['class_id']}_{$params['sort_type']}";
|
||||
|
||||
// 获取Redis锁
|
||||
if (RedisLock::lock($lockKey, 1, 3)) {
|
||||
$lock = LockRedis::getInstance();
|
||||
if ($lock->lock($lockKey, 3, 500)) {
|
||||
$isTrue = $this->articleService->articleClassSort($this->uid(), (int)$params['class_id'], (int)$params['sort_type']);
|
||||
|
||||
// 释放Redis锁
|
||||
RedisLock::release($lockKey, 1);
|
||||
$lock->delete($lockKey);
|
||||
} else {
|
||||
$isTrue = false;
|
||||
}
|
||||
|
|
|
@ -19,39 +19,5 @@ namespace App\Helper;
|
|||
*/
|
||||
class StringHelper
|
||||
{
|
||||
/**
|
||||
* 将字符串转换成二进制
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public static function str2Bin(string $str): string
|
||||
{
|
||||
//列出每个字符
|
||||
$arr = preg_split('/(?<!^)(?!$)/u', $str);
|
||||
//unpack字符
|
||||
foreach ($arr as &$v) {
|
||||
$temp = unpack('H*', $v);
|
||||
$v = base_convert($temp[1], 16, 2);
|
||||
unset($temp);
|
||||
}
|
||||
|
||||
return join(' ', $arr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将二进制转换成字符串
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public static function bin2Str(string $str): string
|
||||
{
|
||||
$arr = explode(' ', $str);
|
||||
foreach ($arr as &$v) {
|
||||
$v = pack('H' . strlen(base_convert($v, 2, 16)), base_convert($v, 2, 16));
|
||||
}
|
||||
|
||||
return join('', $arr);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -93,6 +93,8 @@ class TalkService extends BaseService
|
|||
if ($records) {
|
||||
$data['msg_text'] = $records['text'];
|
||||
$data['updated_at'] = $records['created_at'];
|
||||
} else {
|
||||
$data['updated_at'] = '2020-01-01 00:00:00';
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Support;
|
||||
|
||||
/**
|
||||
* Class RedisLock
|
||||
*
|
||||
* @package App\Support
|
||||
*/
|
||||
class RedisLock
|
||||
{
|
||||
|
||||
/**
|
||||
* 锁前缀标识
|
||||
*/
|
||||
const PREFIX = 'lock';
|
||||
|
||||
/**
|
||||
* 获取Redis连接
|
||||
*
|
||||
* @return \Hyperf\Redis\Redis
|
||||
*/
|
||||
public static function getRedis()
|
||||
{
|
||||
return redis();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得锁,如果锁被占用,阻塞,直到获得锁或者超时。
|
||||
* 1、如果 $timeout 参数为 0,则立即返回锁。
|
||||
* 2、建议 timeout 设置为 0,避免 redis 因为阻塞导致性能下降。请根据实际需求进行设置。
|
||||
*
|
||||
* @param string $key 缓存KEY
|
||||
* @param string|int $requestId 客户端请求唯一ID
|
||||
* @param integer $lockSecond 锁定时间 单位(秒)
|
||||
* @param integer $timeout 取锁超时时间。单位(秒)。等于0,如果当前锁被占用,则立即返回失败。如果大于0,则反复尝试获取锁直到达到该超时时间。
|
||||
* @param integer|float $sleep 取锁间隔时间 单位(秒)。当锁为占用状态时。每隔多久尝试去取锁。默认 0.1 秒一次取锁。
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function lock(string $key, $requestId, $lockSecond = 20, $timeout = 0, $sleep = 0.1)
|
||||
{
|
||||
if (empty($key)) {
|
||||
throw new \Exception('获取锁的KEY值没有设置');
|
||||
}
|
||||
|
||||
$start = self::getMicroTime();
|
||||
$redis = self::getRedis();
|
||||
|
||||
do {
|
||||
$acquired = $redis->rawCommand('SET', self::getLockKey($key), $requestId, 'NX', 'EX', $lockSecond);
|
||||
if ($acquired) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($timeout === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
\Swoole\Coroutine\System::sleep($sleep);
|
||||
} while (!is_numeric($timeout) || (self::getMicroTime()) < ($start + ($timeout * 1000000)));
|
||||
|
||||
return (bool)$acquired;
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放锁
|
||||
*
|
||||
* @param string $key 被加锁的KEY
|
||||
* @param string|int $requestId 客户端请求唯一ID
|
||||
* @return bool
|
||||
*/
|
||||
public static function release(string $key, $requestId)
|
||||
{
|
||||
if (strlen($key) === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$lua = <<<LAU
|
||||
if redis.call("GET", KEYS[1]) == ARGV[1] then
|
||||
return redis.call("DEL", KEYS[1])
|
||||
else
|
||||
return 0
|
||||
end
|
||||
LAU;
|
||||
|
||||
self::getRedis()->rawCommand('eval', $lua, 1, self::getLockKey($key), $requestId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取锁 Key
|
||||
*
|
||||
* @param string $key 需要加锁的KEY
|
||||
* @return string
|
||||
*/
|
||||
public static function getLockKey(string $key)
|
||||
{
|
||||
return self::PREFIX . ':' . $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前微秒
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getMicroTime()
|
||||
{
|
||||
return bcmul(microtime(true), 1000000);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue