当前位置: 首页 > 后端技术 > PHP

[php]如何实现高并发优化

时间:2023-03-29 23:13:11 PHP

在实际开发过程中,我们遇到过各种各样的活动,但是用户流量大的平台需要考虑高并发的问题,但是如何解决呢??我总结了几种解决方法,欢迎指正!1、什么是PV/UV/QPS?PV:页面访问量,即PageView,记录用户对网站的每次访问,用户多次访问同一个页面所累积的访问次数。(说白了就是用户的点击次数)UV:独立访客数:即UniqueVisitor,访问网站的电脑客户端就是访客。00:00-24:00内同一客户只计一次。(说白了就是每天访问的用户数)QPS:(queryratepersecond):每秒的请求数或查询数。在互联网领域,是指每秒响应请求数(指HTTP请求)。二、如何优化php级别的并发?1、redis级别:(1)使用redis加锁机制处理setnxkeyvalue:当且仅当key不存在时才将key的值设置为value。如果给定的键已经存在,SETNX什么都不做。SETNX是SETifNoteXists的缩写。_redis=newRedis();$this->_redis->connect('127.0.0.1');}publicstaticfunctiongetInstance(){if(self::$_instanceinstanceofself){returnself::$_instance;}returnself::$_instance=newself();}/***@functionlock*@param$key锁名*@param$expTime过期时间*/publicfunctionset($key,$expTime){//初步锁$isLock=$this->_redis->setnx($key,time()+$expTime);如果($isLock){返回真;}else{//如果加锁失败。判断锁是否已经存在,如果锁存在且已经过期,则删除锁。重新锁定$val=$this->_redis->get($key);如果($val&&$valdel($key);}返回$this->_redis->setnx($key,time()+$expTime);}}/***@param$keyunlock*/publicfunctiondel($key){$this->_redis->del($key);}}$pdo=newPDO('mysql:host=127.0.0.1;dbname=test','root','root');$lockObj=Lock::getInstance();//单例模式//可以加判断加锁成功if($lock=$lockObj->set('storage',10)){$sql="select`number`fromstoragewhereid=1limit1";$res=$pdo->query($sql)->fetch();$number=$res['number'];if($number>0){$sql="插入`order`VALUES(null,$number)";$order_id=$pdo->query($sql);if($order_id){$sql="更新存储集`number`=`number`-1WHEREid=1";$pdo->查询($sql);}}//解锁$lockObj->del('storage');}else{//锁不成功执行其他操作}?>(2)使用reids消息队列处理高并发:队列按照先进先出的顺序执行,需要lpop、rpush、llen等方法/***couponredis存储**/publicfunctionreload_quan(){$yhq_dom=Yhq_user_relation::i();$redis=Redis::i('redis');$redis->setOption(\Redis::OPT_SERIALIZER,\Redis::SERIALIZER_NONE);对于($i=0;$i<100;$i++){$date_time=date('Y-m-dH:i:s',time());$res=$yhq_dom->add(['hd_id'=>3,'yhq_id'=>19,'name'=>'full58minus20','create_time'=>$date_time,'price'=>58,'元宝'=>20]);if(!$res){$this->_error('添加'.$i.'优惠券失败');}//将数据保存到redis$redis->rPush('yhq_relation',"{$i}");$redis->expire('yhq_relation',1860);$this->_success('','优惠券入库成功');}/***领取优惠券**/publicfunctionget_quan(){$redis=Redis::i('re迪斯');$redis->setOption(\Redis::OPT_SERIALIZER,\Redis::SERIALIZER_NONE);$start_time=date('Y-m-d00:00:00',time());$stop_time=date('Y-m-d23:59:59',time());//判断是否在抢购时间内//$start_string=mktime(12,0,0,date('m'),date('d')-date('w')+5,date('是'));//$stop_string=mktime(23,59,59,date('m'),date('d')-date('w')+5,date('Y'));//$now_time=时间();//if($now_time<$start_string||$now_time>$stop_string){//$this->_error('抢券时间未到,请稍后再来~');//}$len=$redis->lLen('yhq_relation');if($len<1){$this->_error('优惠券已售完~');}else{//领取优惠券时判断用户是否实际领取优惠券$user_id=$this->_user_info()['accid'];$yhq_dom=Yhq_user_relation::i();$where=['accid'=>$user_id,'hd_id'=>3,'yhq_id'=>19,'create_time'=>['between'=>[$start_time,$stop_time]]];$结果t=$yhq_dom->where($where)->find();if($result){$this->_error('抱歉,您已经收到了~');}else{//用户领取优惠券$expire_time=date('Y-m-dH:i:s',(time()+259200));$sql="从yhq_user_relation中选择id,其中hd_id=3和yhq_id=19,create_time在'$start_time'和'$stop_time'之间,accid是NULLORDERbycreate_timeASC";$update_id=$yhq_dom->query($sql)[0]['id'];//已收到双判断if(!$update_id){$this->_error('优惠券已售完~');}$redis->lPop('yhq_relation');$res=$yhq_dom->update("id={$update_id}",['accid'=>$user_id,'expire_time'=>$expire_time]);if($res){$this->_success('','接收成功');}else{$this->_error('接收失败,请检查网络连接');}}}}2.数据库级别(暂未总结)