redis⾼并发下的处理考勤打卡数据
背景
最近公司⽤户量上来了,因此,对考勤打卡的瓶颈也就越发明显。每到打卡⾼峰期,公司APP就打开很慢,甚⾄服务开挂。针对这些问题,检查服务器发现,原来是考勤接⼝并发上来不停请求数据库导致的CPU剧增。因此,升级了服务器,提升了配置,但是还是不能抗住压⼒。因此,⾃⼰百度发现redis是个好东西,可以做缓存数据库,缓解mysql压⼒。因此,写下这篇⽂章。
主要运⽤
-  1.redis:hset,
-  2.定时任务
-  3.注意:设计时,是以每天为单位,异步同步redis缓存数据到mysql。
代码模块
<?php
/**
* Created by PhpStorm.
* User: FengYun
* Date: 2019/12/6
* Time: 9:47
*/
namespace App\Services\Sign;
use App\Services\ComService;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Redis;
class RedisBaseService extends ComService
{
private $config;
private $redis;
protected function __construct()
{
$this->redis = app('tion');
}
private function _getEnable()
{
$conf = $this->config;
return $conf['enable'];
}
/**
* 查询key
* @param $key
* @return mixed
*/
public function keys($key){
return $this->redis->keys($key);
}
/**
* 设置位图
* @param $key
* @param $offset
* @param  bool $value
* @param int $time
*/
public function setBit($key, $offset,$value,$time=0)
{
$result = $this->redis->setbit($key,$offset,$value);        if($time>0){
$this->redis->expire($key,$time);
}
return $result;
}
/**
* 获取位图
* @param $key
* @param $offset
* @return mixed
mysql下载app*/
public function getBit($key,$offset)
{
return $this->redis->getBit($key,$offset);
}
/**
* 统计位图
* @param $key
* @return mixed
*/
public function bitCount($key)
{
if(!$this->_getEnable()){
return null;
}
return $this->redis->bitCount($key);
}
/**
* 位图操作
* @param $operation
* @param $reKey
* @param array ...$key
* @return mixed
*/
public function bitOp($operation,$reKey,...$key)
{
if(!$this->_getEnable()){
return null;
}
return $this->redis->bitOp($operation,$reKey,$key);    }
/**
* 计算在某段位图中 1或0第⼀次出现的位置
* @param $key
* @param null $end
* @return mixed
*/
public function bitPos($key,$bit,$start,$end=null)
{
if(!$this->_getEnable()){
return null;
}
return $this->redis->bitPos($key,$bit,$start,$end);    }
/**
* 删除位图
* @param $key
* @return mixed
*/
public function del($key)
{
return $this->redis->del($key);
}
/**
* 写⼊
* @param $key
* @param $hashKey
* @param $value
* @return bool
*/
public function hSet($key, $hashKey, $value )
{
return $this->redis->hset($key,$hashKey,$value);    }
/**
* 批量获取
* @param $key
* @return bool
*/
public function hGetAll($key)
{
return $this->redis->hGetAll($key);
}
/
**
* @param $key
* @param $hashKey
* @return bool
*/
public function hExists($key,$hashKey)
{
return $this->redis->hExists($key,$hashKey);
}
/**
* @param $key
* @return bool
*/
public function hKeys($key)
{
return $this->redis->hKeys($key);
}
/**
*/
public function hLen($key)
{
return $this->redis->hLen($key);
}
/**
* 管道技术批量⼊库
* @param $key
* @param $value
*/
public function setPipe($key,$value)
{
$this->redis->multi();
$this->redis->set('sign_'.$key,$value);
$this->redis->get('sign_'.$key);
$replies=$this->redis->exec();
print_r($replies);
}
}
2.打卡封装(根据需要⽽定,可省略)
<?php
/**
* Created by PhpStorm.
* User: FengYun
* Date: 2019/12/6
* Time: 10:13
*/
namespace App\Services\Sign;
class RedisSignService extends RedisBaseService
{
private $keySign= 'sign_';//签到记录key
private $key = 0;
public function __construct($keySign)
{
parent::__construct();
//格式:前缀_2019_10_11:265|E234FD|20191206101112|1 =>1/0    }
}
3.打卡数据组装封装
<?php
/**
* Created by PhpStorm.
* User: Moer
* Date: 2019/12/6
* Time: 9:46
*/
namespace App\Services\Sign;
class SignService
{
public static function userSignIn($params)
{
$sign_date = $params['sign_date'];
$sign_time = $params['sign_time'];
$company_id = $params['company_id'];
$uuid = $params['uuid'];
$sign_type = $params['sign_type'];
$sign_date = date('Ymd',strtotime($sign_date));
$keySign = 'sign_' . $sign_date .':'. $company_id .'|'. $uuid .'|'. date('YmhHis') .'|'. $sign_type;        $signLogModel = new RedisSignService($keySign);
try{
/*格式:前缀_打卡⽇期:公司id|员⼯id|打卡时间|打卡⽅式
sign_20191011:265|125043|20191206101112|1
*/
$key = 'sign_' . $sign_date ; //sign_20191011
$hashKey = $uuid .'|'. date('His',strtotime($sign_time)); //125043|143705
$value = $company_id . '|' . $uuid .'|'. date('H:i:s',strtotime($sign_time)) .'|' .$sign_type;
//公司|⽤户uuid|打卡时间|打卡类型 265|125043|20191206101112|1
//写⼊redis数据
$res = $signLogModel->hSet($key,$hashKey,$value);
if(!$res){
return false;
}
}catch (\Exception $e){
return ['msg'=>$e->getMessage(),'code'=> $e->getCode()];
}
}
}
4.模拟并发情况

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。