本案例是用memcache挡掉高并发来缓解数据库并发的压力。
memcache的windows环境的安装见我另外的一篇文章:http://blog.youkuaiyun.com/u010620626/article/details/43937961
memcache的配置:
$memcache_servers = array(
array('host'=>'127.0.0.1', 'port'=>11211, 'weight'=>100)
);
define('EXPIRE', 3600 * 24);
ecshop初始化的时候会载入lib_common.php文件 在其中添加:
function create_memcache($servers) {
$mem = new memcache;
foreach ($servers as $server) {
$mem->addServer($server['host'], $server['port'], false, $server['weight']);
}
return $mem;
}
调用该函数即可创建memcache的连接 该连接采用连接池连接 节约系统的开销 便于日后集群扩展
主要逻辑的代码:
<?php
define('IN_ECS', true);
require(dirname(__FILE__) . '/includes/init.php');
define('COUNT', 6);
if ($_POST['captcha']) {
/* 检查验证码 */
include_once('includes/cls_captcha.php');
$validator = new captcha();
if ($validator->check_word($_POST['captcha'])) {
$res['err_msg'] = '';
} else {
$res['err_msg'] = '验证码错误!';
}
include('includes/cls_json.php');
$json = new JSON;
die($json->encode($res));
}
$mem = create_memcache($memcache_servers);
$process_flag = $mem->get('process_flag');
$cur_date = local_date('Y-m-d');
if ($process_flag != $cur_date) {
$date = getdate();
$start_time = local_mktime(12, 0, 0, $date['mon'], $date['mday'], $date['year']);
$end_time = local_mktime(12, 5, 0, $date['mon'], $date['mday'], $date['year']);
$sql = 'update '.$ecs->table('favourable_activity').' set start_time='.$start_time.',end_time='.$end_time.' where act_type=2 and act_range=3 and act_name like \'秒杀%折\'';
$db->query($sql);
$sql = 'select act_range_ext from '.$ecs->table('favourable_activity').' where act_type=2 and act_range=3 and act_name like \'秒杀%折\'';
$rows = $db->getCol($sql);
$goods_id_in = array();
foreach ($rows AS $ids) {
$goods_id_in = array_merge($goods_id_in, explode(',', $ids));
}
shuffle($goods_id_in);
$goods_id_in = array_slice($goods_id_in, 0, COUNT);
$sql = 'select goods_id,goods_number div 2+1 as goods_number,goods_name,goods_thumb,round(shop_price*act_type_ext/100,2) shop_price,market_price,floor(act_type_ext/10) discount,start_time,end_time from '.$ecs->table('goods').' left join '.$ecs->table('favourable_activity').' on FIND_IN_SET(goods_id,act_range_ext) where goods_id '.db_create_in($goods_id_in).' and goods_number>0 and act_type=2 and act_range=3 and act_name like \'秒杀%折\'';
$rows = $db->getAll($sql);
$mem->set('seckill_goods', $rows, 0, EXPIRE);
foreach ($rows AS $key => $value) {
$mem->set($value['goods_id'], $value['goods_number'], 0, EXPIRE);
}
$mem->set('process_flag', $cur_date);
}
$count = count($mem->get('seckill_goods'));
//clear_all_files();
$cache_id = sprintf('%X', crc32($_SESSION['user_rank'] . '-' . $_CFG['lang'] . '-'. $cur_date . '-'. $count));
if (!$smarty->is_cached('favour.dwt', $cache_id)) {
assign_template();
$position = assign_ur_here('', '惠乐仓');
$smarty->assign('page_title', $position['title']); // 页面标题
$smarty->assign('ur_here', $position['ur_here']); // 当前位置
$smarty->assign('helps', get_shop_help()); // 网店帮助
$smarty->assign('promotion_goods', get_promote_goods()); // 抢购商品
$smarty->assign('seckill_goods', $mem->get('seckill_goods')); // 秒杀商品
$smarty->assign('enabled_login_captcha', 1);
$smarty->assign('rand', mt_rand());
}
$smarty->display('favour.dwt', $cache_id);
前台倒计时代码:
<div class="startLine" id="leftTime{$key}" onclick = "if (this.className == 'endLine') {document.getElementById('light').style.display='block';document.getElementById('fade').style.display='block';document.getElementById('captcha').focus();document.getElementById('goods_id').value='{$item.goods_id}';}">
{$lang.please_waiting}
</div>
</li>
<script>
Tday[{$key}] = new Date({$item.start_time}*1000);
endtime[{$key}] = new Date({$item.end_time}*1000);
ids[{$key}] = '{$item.goods_id}';
window.setInterval(function()
{clock({$key});}, 1000);
</script>
倒计时js文件:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!-- {if $promotion_goods} -->
<script >
var Tday = new Array();
var endtime = new Array();
var ids = new Array();
var daysms = 24 * 60 * 60 * 1000
var hoursms = 60 * 60 * 1000
var Secondms = 60 * 1000
var microsecond = 1000
var DifferHour = -1
var DifferMinute = -1
var DifferSecond = -1
function clock(key) {
var time = new Date()
if (time.getTime()<Tday[key].getTime() || time.getTime()>endtime[key].getTime()) {//疑问
var convertHour = DifferHour
var convertMinute = DifferMinute
var convertSecond = DifferSecond
var Diffms = Tday[key].getTime() - time.getTime()
DifferHour = Math.floor(Diffms / daysms)
Diffms -= DifferHour * daysms
DifferMinute = Math.floor(Diffms / hoursms)
Diffms -= DifferMinute * hoursms
DifferSecond = Math.floor(Diffms / Secondms)
Diffms -= DifferSecond * Secondms
var dSecs = Math.floor(Diffms / microsecond)
if(convertHour != DifferHour) a="<font color=red>"+DifferHour+"</font>天";
if(convertMinute != DifferMinute) b="<font color=red>"+DifferMinute+"</font>时";
if(convertSecond != DifferSecond) c="<font color=red>"+DifferSecond+"</font>分"
d="<font color=red>"+dSecs+"</font>秒"
if (DifferHour<=0) a='';
document.getElementById("leftTime"+key).className = 'startLine';
document.getElementById("leftTime"+key).innerHTML = a + b + c + d; //显示倒计时信息
} else {
document.getElementById("leftTime"+key).className = 'endLine';
document.getElementById("leftTime"+key).innerHTML = '点击秒杀';
}
}
</script>
<!-- {/if} -->