[php]如何做到高并发优化
在实际的开发过程中我们遇到过各种各样的活动,但像用户流量较大的平台就需要考虑高并发的问题,但是如何去解决呢?我总结了几种解决方案,欢迎大家指正!
一、什么是PV/UV/QPS?
PV:页面访问量,即PageView,用户每次对网站的访问均被记录,用户对同一页面的多次访问,访问量累计。(说白了就是用户的点击次数)
UV:独立访问用户数:即UniqueVisitor,访问网站的一台电脑客户端为一个访客。00:00-24:00内相同的客户端只被计算一次。(说白了就是每天访问的用户数)
QPS: (每秒查询率) : 每秒钟请求或者查询的数量,在互联网领域,指每秒响应请求数(指HTTP请求)
二、php层面如何优化高并发?
1.redis层面:
(1)利用redis加锁机制处理setnx key value:将 key 的值设为 value,当且仅当 key 不存在。 若给定的 key 已经存在,则 SETNX 不做任何动作。SETNX 是SET if Not eXists的简写。
<?php
class Lock
{
private static $_instance ;
private $_redis;
private function __construct()
{
$this->_redis = new Redis();
$this->_redis ->connect('127.0.0.1');
}
public static function getInstance()
{
if(self::$_instance instanceof self)
{
return self::$_instance;
}
return self::$_instance = new self();
}
/**
* @function 加锁
* @param $key 锁名称
* @param $expTime 过期时间
*/
public function set($key,$expTime)
{
//初步加锁
$isLock = $this->_redis->setnx($key,time()+$expTime);
if($isLock)
{
return true;
}
else
{
//加锁失败的情况下。判断锁是否已经存在,如果锁存在且已经过期,那么删除锁。进行重新加锁
$val = $this->_redis->get($key);
if($val&&$val<time())
{
$this->del($key);
}
return $this->_redis->setnx($key,time()+$expTime);
}
}
/**
* @param $key 解锁
*/
public function del($key)
{
$this->_redis->del($key);
}
}
$pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'root');
$lockObj = Lock::getInstance(); //单例模式
//判断是能加锁成功
if($lock = $lockObj->set('storage',10))
{
$sql="select `number` from storage where id=1 limit 1";
$res = $pdo->query($sql)->fetch();
$number = $res['number'];
if($number>0)
{
$sql ="insert into `order` VALUES (null,$number)";
$order_id = $pdo->query($sql);
if($order_id)
{
$sql="update storage set `number`=`number`-1 WHERE id=1";
$pdo->query($sql);
}
}
//解锁
$lockObj->del('storage');
}
else
{
//加锁不成功执行其他操作。
}
?>
(2)利用reids消息队列处理高并发:队列是按先进先出的顺序来执行,需要用到 lpop、rpush、llen等方法
/**
*优惠券redis入库
**/
public function reload_quan(){
$yhq_dom = Yhq_user_relation::i();
$redis = Redis::i('redis');
$redis->setOption( \Redis::OPT_SERIALIZER, \Redis::SERIALIZER_NONE );
for ($i=0;$i<100;$i++){
$date_time = date('Y-m-d H:i:s',time());
$res = $yhq_dom->add([
'hd_id' => 3,
'yhq_id'=> 19,
'name' => '满58减20',
'create_time' => $date_time,
'price' => 58,
'yuanbao' => 20
]);
if (!$res){
$this->_error('添加第'.$i.'张优惠券时失败');
}
//在redis中存入数据
$redis->rPush('yhq_relation',"{$i}");
}
$redis->expire('yhq_relation',1860);
$this->_success('','库内添加优惠券成功');
}
/**
*领取优惠券
**/
public function get_quan(){
$redis = Redis::i('redis');
$redis->setOption( \Redis::OPT_SERIALIZER, \Redis::SERIALIZER_NONE );
$start_time = date('Y-m-d 00:00:00',time());
$stop_time = date('Y-m-d 23:59:59',time());
//判断是否在抢购时间内
//$start_string = mktime(12,0,0,date('m'),date('d')-date('w')+5,date('Y'));
//$stop_string = mktime(23,59,59,date('m'),date('d')-date('w')+5,date('Y'));
//$now_time = 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]
]
];
$result = $yhq_dom->where($where)->find();
if($result){
$this->_error('对不起,您已经领取过了哦~');
}else{
//用户领取优惠券
$expire_time = date('Y-m-d H:i:s',(time()+259200));
$sql = "select id from yhq_user_relation where hd_id = 3 and yhq_id=19 and create_time between '$start_time' and '$stop_time' and accid is NULL ORDER by create_time ASC ";
$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.数据库层面(暂时没有总结好)
原文地址:https://segmentfault.com/a/1190000016573896
[php]如何做到高并发优化的更多相关文章
- 性能调优之MYSQL高并发优化
性能调优之MYSQL高并发优化 一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之 ...
- 【JAVA】高并发优化细节点
高并发优化细节点: 微服务化 如何发现系统瓶颈? 如何高效利用有限内存: 使用基本类型 使用数组,不用集合 自定义map与数据结构 Integer—>int, Set<Intege ...
- Java高并发秒杀API之高并发优化
---恢复内容开始--- 第1章 秒杀系统高并发优化分析 1.为什么要单独获得系统时间 访问cdn这些静态资源不用请求系统服务器 而CDN上没有系统时间,需要单独获取,获取系统时间不用优化,只是n ...
- Apache Tomcat 8.5 安全配置与高并发优化
通常我们在生产环境中,Tomcat的默认配置显然不能满足我们的产品需求,所以很多时候都需要对Tomcat的配置进行调优,以下综合我自己的经验来配置 Tomcat 安全与优化情况,如果你有更好的方案,请 ...
- MySQL MyISAM/InnoDB高并发优化经验
最近做的一个应用,功能要求非常简单,就是 key/value 形式的存储,简单的 INSERT/SELECT,没有任何复杂查询,唯一的问题是量非常大,如果目前投入使用,初期的单表 insert 频率约 ...
- 04 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之高并发优化
Github:https://github.com/nnngu 项目源代码:https://github.com/nnngu/nguSeckill 关于并发 并发性上不去是因为当多个线程同时访问一行数 ...
- SSM实战——秒杀系统之高并发优化
一:高并发点 高并发出现在秒杀详情页,主要可能出现高并发问题的地方有:秒杀地址暴露.执行秒杀操作. 二:静态资源访问(页面)优化——CDN CDN,内容分发网络.我们把静态的资源(html/css/j ...
- nginx php-fpm 高并发优化
PHP-php-fpm配置优化 前言: 1.少安装PHP模块, 费内存 2.调高linux内核打开文件数量,可以使用这些命令(必须是root帐号)(我是修改/etc/rc.local,加入ulimit ...
- SSM(Spring+SpringMVC+MyBatis)高并发优化思路
SSM(Spring+SpringMVC+MyBatis)框架集由Spring.MyBatis两个开源框架整合而成(SpringMVC是Spring中的部分内容).常作为数据源较简单的web项目的框架 ...
随机推荐
- [tyvj-1194]划分大理石 二进制优化多重背包
突然发现这个自己还不会... 其实也不难,就和快速幂感觉很像,把物品数量二进制拆分一下,01背包即可 我是咸鱼 #include <cstdio> #include <cstring ...
- 关于高校表白APP的用户模板和用户场景
用户模板一: 用户名 小明 性别,年龄 男,20岁 用户状况 单身,在校大学生 生活爱好 喜欢打篮球,唱歌 典型场景 希望找到一个心仪的可以走到最后的姑娘 典型描述 交友 用户比例 ? 用户场景一 ...
- 字符识别Python实现 图片验证码识别
字符型图片验证码识别完整过程及Python实现 1 摘要 验证码是目前互联网上非常常见也是非常重要的一个事物,充当着很多系统的 防火墙 功能,但是随时OCR技术的发展,验证码暴露出来的安全问题也越 ...
- Java压缩和解压缩文件工具
Java压缩和解压缩文件工具 学习了: https://www.oschina.net/code/snippet_1021818_48130 http://blog.csdn.net/gaowen_h ...
- POJ 3050 Hopscotch 水~
http://poj.org/problem?id=3050 题目大意: 在一个5*5的格子中走,每一个格子有个数值,每次能够往上下左右走一格,问走了5次后得到的6个数的序列一共同拥有多少种?(一開始 ...
- 调用imagemagick做响应图片
设计出图后经常需要改下尺寸放在别的项目上使用,每次都是设计手工处理,其实图片服务可以做更多事情,比如借助强大的im,可以通过url控制图片尺寸 var childProcess = require(' ...
- tapestry3创建自己定义组件
两种方法创建自己定义标签: 一.通过AbstractComponent父类渲染,此种方法直接在java类中编写页面脚本.然后输出. 1.编写java类com/ailk/ech/ecop/view/te ...
- 刚接触Joomla,写一下瞎折腾的初感受~
我这几天一直在苦苦寻找一款能够长期投靠的CMS产品,要求的是 1)必须支持命名空间 2)必须OOP + MVC分层 3)丰富分文档和使用群体,至少是出名的.免得哪一天他们解散了 4)-- 一開始我把目 ...
- CDH使用秘籍(一):Cloudera Manager和Managed Service的数据库
背景 从业务发展需求,大数据平台须要使用spark作为机器学习.数据挖掘.实时计算等工作,所以决定使用Cloudera Manager5.2.0版本号和CDH5. 曾经搭建过Cloudera Mana ...
- Bitcoin学习篇之---PPS和PPLNS挖矿模式介绍
PPS和PPLNS挖矿模式介绍 比特币每10分钟产生一个区块,会有千万人竞争.而这个区块终于仅仅归1个人全部.其他人都颗粒无收. 你或许要挖5年才干获得一个区块. 组队挖矿就是.一旦队伍里不论什么人获 ...