PHP数据库操作之高并发实例

最近,写了一个微信签到的接口,正好简单让大家了解一下怎样处理高并发的操作!

设计思路:1.对于一个接口,需要防止同一个人在很短的时间内,多次请求借口;

2.需要防止,大量的用户,同时请求该接口

数据库下载:http://pan.baidu.com/s/1dDk4WRv

方便阅读且格式良好的代码(点击图片可放大阅读):

屏幕快照 2015-07-22 下午4.39.17

源码分享(可复制):

<?php
//本文在新浪SAE环境下测试运行
//使用PDO方式链接数据库,如果在非SAE环境下,请修改以下参数!SAE_MYSQL_DB:数据库名,SAE_MYSQL_PORT:端口号,SAE_MYSQL_HOST_M:数据库地址
//SAE_MYSQL_USER:用户名,SAE_MYSQL_PASS:密码
$dsn="mysql:dbname=".SAE_MYSQL_DB.";port=".SAE_MYSQL_PORT.";host=".SAE_MYSQL_HOST_M;
$db_user=SAE_MYSQL_USER;
$db_pass=SAE_MYSQL_PASS;
try{
$pdo=new PDO($dsn,$db_user,$db_pass);
}catch(PDOException $e){
echo '数据库连接失败'.$e->getMessage();
exit();
}
//获取IP地址
$ip_address = $_SERVER["REMOTE_ADDR"];
//初始化memcache
$mmc=memcache_init();

//查询缓存中,是否已经有数据码,有则直接获取后返回
if(memcache_get($mmc,"code_".$ip_address)){
$result = memcache_get($mmc,"code_".$ip_address);
}else{
//缓存中没有数据码,则查询本周是否已经领取数据码
$sql="select last_time,numbers from sign where ip_address ='".$ip_address ."' ORDER BY last_time desc limit 1";
$res=$pdo->query($sql);

//本周一0点的时间戳
$monday_date = strtotime(date('Y-m-d',time()-86400*(date('w',time()))+(date('w',time())>0?86400:-6*86400)));
//本周已经领取数据码,则写入缓存,同时返回数据码
foreach($res as $row){
if($row['last_time'] > $monday_date){
$result = $row['numbers'];
memcache_set($mmc, "code_".$ip_address, $result);
break;
}
}
//本周未领取数据码
if(!isset($result)){
//查询一个未使用过的数据码,如果在得到新数据码的同时,查询缓存,礼品码已被使用,则再次查询新数据码
do{
$sql="select numbers from sign where is_use=0 limit 1";
$res=$pdo->query($sql);

foreach($res as $row){
$result = $row['numbers'];
break;
}
}while(memcache_get($mmc, $result));

//睡眠,有利于同一IP地址,重复刷新页面,进行高并发测试
sleep(10);
//更新数据库
$sql="update sign set is_use=1,ip_address='".$ip_address."',last_time=".time().",times=times+1 where numbers='".$row['numbers']."'";
$res=$pdo->exec($sql);

//更新成功后,同时写入缓存该码已被使用,以及写入缓存该IP已得到数据码
if($res > 0){
memcache_set($mmc, $result, 1);
memcache_set($mmc, "code_".$ip_address, $result);
}
}
}
//以json格式返回数据码
echo json_encode($result);

缓存清除代码:

<?php
$mmc=memcache_init();
//清除某个缓存
memcache_set($mmc, "code_".$ip_address, '');
//清除所有缓存
memcache_flush($mmc);

PHPthinking欢迎大家,一起交流开发经验!

打赏此文

如果您觉得本站的内容对您有所帮助,您可以扫描下面的二维码小额支付请我喝杯茶,感谢!打赏记录
支付宝
微信
承诺:凡打赏捐助的朋友,留言备注自己的邮箱,在打赏捐助时间点的6个月内,本站会每周邮件推送原创专业技术博文,供大家学习和参考!

1 条评论

  1. 不能够啊柳师傅说道:

    在查询一条未使用的数据码时不需要for update加锁吗?
    不太清楚使用sleep()会不会防止高并发的出现

留下评论

All fields marked (*) are required