异步session表统计信息改造 sessions信息使用memcached存储,统计类功能使用异步同步到其他存储中 ./include/common.inc.php **原代码***************************************************************************** if($sid) { if($discuz_uid) { $query = $db->query("SELECT s.sid, s.styleid, s.groupid='6' AS ipbanned, s.pageviews AS spageviews, s.lastolupdate, s.seccode, $membertablefields FROM {$tablepre}sessions s, {$tablepre}members m WHERE m.uid=s.uid AND s.sid='$sid' AND CONCAT_WS('.',s.ip1,s.ip2,s.ip3,s.ip4)='$onlineip' AND m.uid='$discuz_uid' AND m.password='$discuz_pw' AND m.secques='$discuz_secques'"); } else { $query = $db->query("SELECT sid, uid AS sessionuid, groupid, groupid='6' AS ipbanned, pageviews AS spageviews, styleid, lastolupdate, seccode FROM {$tablepre}sessions WHERE sid='$sid' AND CONCAT_WS('.',ip1,ip2,ip3,ip4)='$onlineip'"); } if($_DSESSION = $db->fetch_array($query)) { $sessionexists = 1; if(!empty($_DSESSION['sessionuid'])) { $_DSESSION = array_merge($_DSESSION, $db->fetch_first("SELECT $membertablefields FROM {$tablepre}members m WHERE uid='$_DSESSION[sessionuid]'")); } } else { if($_DSESSION = $db->fetch_first("SELECT sid, groupid, groupid='6' AS ipbanned, pageviews AS spageviews, styleid, lastolupdate, seccode FROM {$tablepre}sessions WHERE sid='$sid' AND CONCAT_WS('.',ip1,ip2,ip3,ip4)='$onlineip'")) { clearcookies(); $sessionexists = 1; } } } **修改后代码***************************************************************************** $memcache = memcache_connect('127.0.0.1', 11211); if($sid) { if( empty($_DCOOKIE['sessionverify']) || ( $_DCOOKIE['sessionverify']!=sessionverify( $sid ) ) ) { clearcookies(); } $sessions = $memcache->get( $sid ); if( $discuz_uid && ( empty( $sessions['discuz_uid'] ) || empty( $sessions['discuz_user'] ) ) ) { $sessions['uid'] = $sessions['discuz_uid'] = $discuz_uid; $sessions['sid'] = $sid; $sessions['onlineips'] = $onlineip; $sessionexists = 1; $_DSESSION = array_merge($sessions, $db->fetch_first("SELECT $membertablefields FROM {$tablepre}members m WHERE uid='$discuz_uid'")); print_r($_DSESSION); $memcache->set( $sid , $_DSESSION , true , $onlinehold ); $memcache->set( "discuz_user_".$discuz_uid , $sid , true , $onlinehold ); } else if( $discuz_uid && $sessions['uid'] > 0 ) { $_DSESSION = $sessions; $_DSESSION['ipbanned'] = $_DSESSION['groupid']==6 ? 6 :''; $_DSESSION['spageviews'] = $sessions['pageviews']; $sessionexists = 1; } else if( $discuz_uid == 0 ) { $sessionexists = 1; $_DSESSION = $sessions; } else { clearcookies(); $sessionexists = 1; } unset($_DSESSION['fid']); unset($_DSESSION['tid']); unset($_DSESSION['action']); unset($_DSESSION['bloguid']); unset($_DSESSION['username']); } ./include/global.func.php **原代码***************************************************************************** function updatesession() { if(!empty($GLOBALS['sessionupdated'])) { return TRUE; } global $db, $tablepre, $sessionexists, $sessionupdated, $sid, $onlineip, $discuz_uid, $discuz_user, $timestamp, $lastactivity, $seccode, $pvfrequence, $spageviews, $lastolupdate, $oltimespan, $onlinehold, $groupid, $styleid, $invisible, $discuz_action, $fid, $tid; $fid = intval($fid); $tid = intval($tid); if($oltimespan && $discuz_uid && $lastactivity && $timestamp - ($lastolupdate ? $lastolupdate : $lastactivity) > $oltimespan * 60) { $lastolupdate = $timestamp; $db->query("UPDATE {$tablepre}onlinetime SET total=total+'$oltimespan', thismonth=thismonth+'$oltimespan', lastupdate='$timestamp' WHERE uid='$discuz_uid' AND lastupdate<='".($timestamp - $oltimespan * 60)."'"); if(!$db->affected_rows()) { $db->query("INSERT INTO {$tablepre}onlinetime (uid, thismonth, total, lastupdate) VALUES ('$discuz_uid', '$oltimespan', '$oltimespan', '$timestamp')", 'SILENT'); } } else { $lastolupdate = intval($lastolupdate); } if($sessionexists == 1) { if($pvfrequence && $discuz_uid) { if($spageviews >= $pvfrequence) { $pageviewsadd = ', pageviews=\'0\''; $db->query("UPDATE {$tablepre}members SET pageviews=pageviews+'$spageviews' WHERE uid='$discuz_uid'", 'UNBUFFERED'); } else { $pageviewsadd = ', pageviews=pageviews+1'; } } else { $pageviewsadd = ''; } $db->query("UPDATE {$tablepre}sessions SET uid='$discuz_uid', username='$discuz_user', groupid='$groupid', styleid='$styleid', invisible='$invisible', action='$discuz_action', lastactivity='$timestamp', lastolupdate='$lastolupdate', seccode='$seccode', fid='$fid', tid='$tid' $pageviewsadd WHERE sid='$sid'"); } else { $ips = explode('.', $onlineip); $db->query("DELETE FROM {$tablepre}sessions WHERE sid='$sid' OR lastactivity<($timestamp-$onlinehold) OR ('$discuz_uid'<>'0' AND uid='$discuz_uid') OR (uid='0' AND ip1='$ips[0]' AND ip2='$ips[1]' AND ip3='$ips[2]' AND ip4='$ips[3]' AND lastactivity>$timestamp-60)"); $db->query("INSERT INTO {$tablepre}sessions (sid, ip1, ip2, ip3, ip4, uid, username, groupid, styleid, invisible, action, lastactivity, lastolupdate, seccode, fid, tid) VALUES ('$sid', '$ips[0]', '$ips[1]', '$ips[2]', '$ips[3]', '$discuz_uid', '$discuz_user', '$groupid', '$styleid', '$invisible', '$discuz_action', '$timestamp', '$lastolupdate', '$seccode', '$fid', '$tid')", 'SILENT'); if($discuz_uid && $timestamp - $lastactivity > 21600) { if($oltimespan && $timestamp - $lastactivity > 86400) { $query = $db->query("SELECT total FROM {$tablepre}onlinetime WHERE uid='$discuz_uid'"); $oltimeadd = ', oltime='.round(intval($db->result($query, 0)) / 60); } else { $oltimeadd = ''; } $db->query("UPDATE {$tablepre}members SET lastip='$onlineip', lastvisit=lastactivity, lastactivity='$timestamp' $oltimeadd WHERE uid='$discuz_uid'", 'UNBUFFERED'); } } $sessionupdated = 1; } **修改后代码***************************************************************************** function updatesession() { if(!empty($GLOBALS['sessionupdated'])) { return TRUE; } global $db, $tablepre, $sessionexists, $sessionupdated, $sid, $onlineip, $discuz_uid, $discuz_user, $timestamp, $lastactivity, $seccode, $pvfrequence, $spageviews, $lastolupdate, $oltimespan, $onlinehold, $groupid, $styleid, $invisible, $discuz_action, $fid, $tid, $memcache; $fid = intval($fid); $tid = intval($tid); if($oltimespan && $discuz_uid && $lastactivity && $timestamp - ($lastolupdate ? $lastolupdate : $lastactivity) > $oltimespan * 60) { $lastolupdate = $timestamp; $db->query("UPDATE {$tablepre}onlinetime SET total=total+'$oltimespan', thismonth=thismonth+'$oltimespan', lastupdate='$timestamp' WHERE uid='$discuz_uid' AND lastupdate<='".($timestamp - $oltimespan * 60)."'"); if(!$db->affected_rows()) { $db->query("INSERT INTO {$tablepre}onlinetime (uid, thismonth, total, lastupdate) VALUES ('$discuz_uid', '$oltimespan', '$oltimespan', '$timestamp')", 'SILENT'); } } else { $lastolupdate = intval($lastolupdate); } if($sessionexists == 1) { if($pvfrequence && $discuz_uid) { if($spageviews >= $pvfrequence) { $pageviewsadd = ', pageviews=\'0\''; $db->query("UPDATE {$tablepre}members SET pageviews=pageviews+'$spageviews' WHERE uid='$discuz_uid'", 'UNBUFFERED'); } else { $pageviewsadd = ', pageviews=pageviews+1'; $pageviewsadd_mem = true; } } else { $pageviewsadd = ''; } $sessions = $memcache->get( $sid ); $sessions['discuz_uid'] = $discuz_uid; $sessions['discuz_user'] = $discuz_user; $sessions['groupid'] = $groupid; $sessions['styleid'] = $styleid; $sessions['invisible'] = $invisible; $sessions['action'] = $action; $sessions['lastactivity'] = $timestamp; $sessions['lastolupdate'] = $lastolupdate; $sessions['seccode'] = $seccode; $sessions['fid'] = $fid; $sessions['tid'] = $tid; if( $pageviewsadd_mem ) { $sessions['pageviews'] = $sessions['pageviews']; } $memcache->set( $sid , $sessions , true , $onlinehold ); //session保存10分钟 if($discuz_uid) { $memcache->set( "discuz_user_".$discuz_uid , $sid , true , $onlinehold ); } } else { $ips = explode('.', $onlineip); $sessions = $memcache->get( $sid ); $sessions['sid'] = $sid; $sessions['onlineips'] = onlineip; $sessions['uid'] = $discuz_uid; $sessions['groupid'] = $groupid; $sessions['styleid'] = $styleid; $sessions['invisible'] = $invisible; $sessions['action'] = $action; $sessions['lastactivity'] = $timestamp; $sessions['lastolupdate'] = $lastolupdate; $sessions['seccode'] = $seccode; $sessions['fid'] = $fid; $sessions['tid'] = $tid; $memcache->set( $sid , $sessions , true , $onlinehold ); //session保存10分钟 if($discuz_uid && $timestamp - $lastactivity > 21600) { if($oltimespan && $timestamp - $lastactivity > 86400) { $query = $db->query("SELECT total FROM {$tablepre}onlinetime WHERE uid='$discuz_uid'"); $oltimeadd = ', oltime='.round(intval($db->result($query, 0)) / 60); } else { $oltimeadd = ''; } $db->query("UPDATE {$tablepre}members SET lastip='$onlineip', lastvisit=lastactivity, lastactivity='$timestamp' $oltimeadd WHERE uid='$discuz_uid'", 'UNBUFFERED'); } } $action = $discuz_action; $fid = $fid; $tid = $tid; $invisible = $invisible; $key = md5( $sid.$discuz_uid.$fid.$tid.$action.$invisible ); echo "\"\""; $sessionupdated = 1; } ./asynchronoussession.php 代码: query( "REPLACE INTO asynchronoussession SET uid = $discuz_uid , fid = $fid , tid = $tid , action = $action , invisible = $invisible , lastactivity = '".time()."' , sid = '$sid'" ); if(time()>filemtime($_SERVER['SCRIPT_FILENAME'])+300) { $db->query( "DELETE FROM {$tablepre}asynchronoussessions WHERE lastactivity + 300 < ".time() ); @touch($_SERVER['SCRIPT_FILENAME']); } ?> 表结构 -- -- 表的结构 `asynchronoussession` -- CREATE TABLE IF NOT EXISTS `asynchronoussession` ( `sid` bigint(20) NOT NULL, `uid` int(11) NOT NULL, `lastactivity` int(11) NOT NULL, `fid` int(10) NOT NULL, `tid` int(10) NOT NULL, `action` int(10) NOT NULL, `invisible` int(10) NOT NULL, UNIQUE KEY `sid` (`sid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='异步session状态表';