1. 功能描述
-
2. 开发
2.1 项目背景
记录uv是用户端,使用easyswoole框架,原先已经有pv统计埋点接口。
-
2.2 开发思路
1. 方案1
需要记录7天内UV
-
2. 方案2
-
3. 方案3
固化用户最后一次访问系统的时间到数据表,同时做30秒最近操作redis记录(防止大并发记录最后一次访问时间)
4. 方案4
redis记录一天访问用户id(bitmap或hash)
- 定时脚本每天凌晨固化前一天用户访问到数据库
- 定时脚本取最近7天访问用户推送
2.3 开发落地
1. 方案1
用户端
在Csp类中添加一个记录用户UV的任务,可以并发(见:)的进行原有工作与当前7天uv统计。(采用redis存储,key是
sevenDaysUv:{$userId}) ```php <? function main() { $csp = new Csp(); /$csp->add(‘t1’, function () use ($spm, $browseTime, $unionId) { storeSPM($spm, $browseTime, $unionId); });/// 记录7天内访问过的用户 if ($unionId) { $csp->add(‘sevenDaysUv’, function () use ($unionId) {
saveUserSevenDaysUv($unionId);
}); }
$csp->exec(); }
function saveUserSevenDaysUv($userId) { $key = ‘sevenDaysUv:’ . $userId;
$redis = RedisPool::defer();$redis->set($key, 1, 7 * 24 * 3600);
}
- 服务端1. 通过redis的scan函数轮训扫描所有前缀是 `sevenDaysUv:` 的key,并过滤出userid。1. (需要特别注意的是redis的scan查询)(见:)1. 批量1000条一次推送到用户端```php<?phpnamespace console\controllers;use common\Manager\PushMessage\AliFacade\Live;use Yii;class PushMsgToSevenDaysVisitUserController extends ConsoleBaseController{private static $perSendLimit = 1000;private static $prefix = 'sevenDaysUv:';public function actionSendLiveMsg(){$week = date('w');$serverName = Live::$serverRemindWeekMap[$week]['serverName'];$progress = Live::$serverRemindWeekMap[$week]['progress'];$page = Live::$serverRemindWeekMap[$week]['page'];$aliUserIds = [];$liveMsgObj = new Live();$perArrCount = 0;$matchPattern = self::$prefix . '*';/** @var yii\redis\Connection $redis */$redis = Yii::$app->redis;// 迭代扫描游标$cursor = 0;while ($ret = $redis->scan($cursor, 'MATCH', $matchPattern, 'COUNT', self::$perSendLimit)) {$scanData = $ret[1] ?? [];if ($scanData) {foreach ($scanData as $datum) {$aliUserIds[] = substr($datum, strlen(self::$prefix));$perArrCount++;if ($perArrCount == self::$perSendLimit) {$liveMsgObj->serverRemind($aliUserIds, $serverName, $progress, '', $page);$aliUserIds = [];}}}$cursor = $ret[0] ?? 0;if ($cursor == 0) {break;}}if ($aliUserIds) {$liveMsgObj->serverRemind($aliUserIds, $serverName, $progress, '', $page);}}}
