>  기사  >  백엔드 개발  >  PHP를 사용하여 온라인 사용자 수를 계산하는 네 가지 방법에 대한 자세한 설명

PHP를 사용하여 온라인 사용자 수를 계산하는 네 가지 방법에 대한 자세한 설명

WBOY
WBOY앞으로
2022-06-08 13:51:386635검색

이 글에서는 PHP에 대한 관련 지식을 소개합니다. 주로 온라인에서 인원수 계산 방법, redis 주문 세트 통계 사용, 통계용 하이퍼로그 로그 사용 방법 등을 소개합니다. , 모든 사람에게 도움이 되기를 바랍니다.

PHP를 사용하여 온라인 사용자 수를 계산하는 네 가지 방법에 대한 자세한 설명

추천 학습: "PHP 비디오 튜토리얼"

매일 비즈니스 시스템 웹사이트를 방문하는 사람은 몇 명이며 온라인에 접속하는 사람은 몇 명입니까? 이런 종류의 사업은 개발 중에 예약해야 하며, 그것도 우리의 설계 범위에 속합니다! 운영중인 웹사이트는 매일 통계를 사용하기 때문입니다.

온라인에서 인원수를 계산하는 방법에는 여러 가지 솔루션이 있습니다. 코드는 laravel 프레임워크를 사용합니다. 개발 시 참고 자료로 사용할 수 있습니다.

1 테이블 통계 사용

데이터 테이블을 사용하여 온라인 인원수를 계산할 수 있습니다. 이 방법은 동시성이 크지 않은 경우에만 사용할 수 있습니다.

먼저 새 테이블을 만듭니다: user_login

PHP를 사용하여 온라인 사용자 수를 계산하는 네 가지 방법에 대한 자세한 설명

Edit

user_login 테이블

사용자 로그인을 시뮬레이션하고, 존재하지 않는 경우 테이블에 사용자를 저장하고, 존재하는 경우 로그인 정보를 업데이트합니다

// 客户端唯一的识别码
$client_id = session()->getId();
//用户是否已存在
$user = DB::table('user_login')
    ->where('token', $client_id)
    ->first();
//不存在则插入数据
if (empty($user)) {
    $data = [
        'token' => $client_id,
        'username' => 'user_' . $client_id, // 模拟用户
        'uid' => mt_rand(10000000, 99999999),   //模拟用户id
        'create_time' => date('Y-m-d H:i:s'),
        'update_time' => date('Y-m-d H:i:s')
    ];
    DB::table('user_login')->insert($data);
} else {    
    // 存在则更新用户登录信息
    DB::table('user_login')
     ->where('token', $client_id)
     ->update([
          'update_time' => date('Y-m-d H:i:s')
      ]);
}

This 또한 아무런 작업 없이 정기적으로 청소해야 합니다. 사용자가 한 시간 이내에 아무 작업도 수행하지 않으면 잘못된 사용자로 기록될 수 있습니다.

코드는 다음과 같습니다.

// 客户端唯一的识别码
$client_id = session()->getId();
//用户是否已存在
$user = DB::table('user_login')
    ->where('token', $client_id)
    ->first();
//不存在则插入数据
if (empty($user)) {
    $data = [
        'token' => $client_id,
        'username' => 'user_' . $client_id, // 模拟用户
        'uid' => mt_rand(10000000, 99999999),   //模拟用户id
        'create_time' => date('Y-m-d H:i:s'),
        'update_time' => date('Y-m-d H:i:s')
    ];
    DB::table('user_login')->insert($data);
} else {    
    // 存在则更新用户登录信息
    DB::table('user_login')
     ->where('token', $client_id)
     ->update([
          'update_time' => date('Y-m-d H:i:s')
      ]);
}

구현할 수 있는 기능:

1 ) 현재 온라인 사용자 수

2) 특정 기간 내 온라인 사용자 수

3) 최신 온라인 사용자

4) 사용자가 온라인 상태인지 여부 지정

// 可实现功能一:当前总共在线人数
$c = DB::table('user_login')->count();
echo &#39;当前在线人数:&#39; . $c . &#39;<br />&#39;;
// 可实现功能二:某时间段内在线人数
$begin_date = &#39;2020-08-13 09:00:00&#39;;
$end_date = &#39;2020-08-13 18:00:00&#39;;
$c = DB::table(&#39;user_login&#39;)
    ->where(&#39;create_time&#39;, &#39;>=&#39;, $begin_date)
    ->where(&#39;create_time&#39;, &#39;<=&#39;, $end_date)
    ->count();
echo $begin_date . &#39;-&#39; . $end_date . &#39;在线人数:&#39; . $c . &#39;<br />&#39;;
// 可实现功能三:最新上线的用户
$newest = DB::table(&#39;user_login&#39;)
    ->orderBy(&#39;create_time&#39;, &#39;DESC&#39;)
    ->limit(10)
    ->get();
echo &#39;最新上线的用户有:&#39;;
foreach ($newest as $value) {
    echo $value->username . &#39; &#39;;
}
echo &#39;<br />&#39;;
// 可实现功能四:指定用户是否在线
$username = &#39;user_1111&#39;;
$online = DB::table(&#39;user_login&#39;)
    ->where(&#39;username&#39;, $username)
    ->exists();
echo $username . ($online ? &#39;在线&#39; : &#39;不在线&#39;);

2 redis 주문 컬렉션을 사용하여 온라인 숫자 계산 구현

메모리에 있기 때문에 매우 효율적이며 특정 기간 동안 온라인에 접속한 사람의 수를 셀 수 있고 다양한 집계 작업을 수행할 수 있습니다. 하지만 온라인에 사람이 많으면 메모리를 더 많이 차지하게 됩니다. 또 다른 점:

잘못된 사용자는 사용자 작업 시간을 통해 제거할 수 없습니다. 수동으로 로그아웃한 사용자만 컬렉션에서 삭제됩니다.

코드는 다음과 같습니다.

// 客户端唯一的识别码
$client_id = session()->getId();
echo $client_id . &#39;<br />&#39;;
// 按日期生成key
$day = date(&#39;Ymd&#39;);
$key = &#39;online:&#39; . $day;
// 是否在线
$is_online = Redis::zScore($key, $client_id);
if (empty($is_online)) {    // 不在线,加入当前客户端
    Redis::zAdd($key, time(), $client_id);
}
// 可实现功能一:当前总共在线人数
$c = Redis::zCard($key);
echo &#39;当前在线人数:&#39; . $c . &#39;<br />&#39;;
// 可实现功能二:某时间段内在线人数
$begin_date = &#39;2020-08-13 09:00:00&#39;;
$end_date = &#39;2020-08-13 18:00:00&#39;;
$c = Redis::zCount($key, strtotime($begin_date), strtotime($end_date));
echo $begin_date . &#39;-&#39; . $end_date . &#39;在线人数:&#39; . $c . &#39;<br />&#39;;
// 可实现功能三:最新上线的用户,时间从小到大排序
$newest = Redis::zRangeByScore($key, &#39;-inf&#39;, &#39;+inf&#39;, [&#39;limit&#39; => [0, 50]]);
echo &#39;最新上线的用户有:&#39;;
foreach ($newest as $value) {
    echo $value . &#39; &#39;;
}
echo &#39;<br />&#39;;
// 可实现功能四:指定用户是否在线
$username = $client_id;
$online = Redis::zScore($key, $client_id);;
echo $username . ($online ? &#39;在线&#39; : &#39;不在线&#39;) . &#39;<br />&#39;;
// 可实现功能五:昨天和今天都上线的客户
$yestoday = Carbon::yesterday()->toDateString();
$yes_key = str_replace(&#39;-&#39;, &#39;&#39;, $yestoday);
$members = [];
Redis::pipeline(function ($pipe) use ($key, $yes_key, &$members) {
    Redis::zinterstore(&#39;new_key&#39;, [$key, $yes_key], [&#39;aggregate&#39; => &#39;min&#39;]);
    $members = Redis::zRangeByScore(&#39;new_key&#39;, &#39;-inf&#39;, &#39;+inf&#39;, [&#39;limit&#39; => [0, 50]]);
    //dump($members);
});
echo &#39;昨天和今天都上线的用户有:&#39;;
foreach ($members as $value) {
    echo $value . &#39; &#39;;
}

3 통계에 hyperloglog 사용

주문한 설정 방법과 달리 hyperloglog는 공간을 매우 절약하지만 구현하는 기능도 매우 간단합니다. 다른 기능을 구현할 수 없습니다.

Redis HyperLogLog는 카디널리티 통계에 사용되는 알고리즘입니다. HyperLogLog의 장점은 입력 요소의 수나 양이 매우 클 때 카디널리티를 계산하는 데 필요한 공간이 항상 고정되어 매우 작다는 것입니다.

Redis에서 각 HyperLogLog 키에는 거의 2^64개 요소의 카디널리티를 계산하는 데 12KB의 메모리만 필요합니다. 이는 카디널리티를 계산할 때 더 많은 메모리를 소비하는 컬렉션과 뚜렷한 대조를 이룹니다. 요소가 많을수록 더 많은 메모리가 소비됩니다.

그러나 HyperLogLog는 입력 요소를 기반으로 카디널리티만 계산하고 입력 요소 자체를 저장하지 않기 때문에 HyperLogLog는 입력의 각 요소를 컬렉션처럼 반환할 수 없습니다.

// note HyperLogLog 只需要知道在线总人数
for ($i=0; $i < 6; $i++) {
    $online_user_num = mt_rand(10000000, 99999999);     //模拟在线人数
    var_dump($online_user_num);
    for ($j=1; $j < $online_user_num; $j++) { 
        $user_id = mt_rand(1, 100000000);
        $redis->pfadd(&#39;002|online_users_day_&#39;.$i, [$user_id]);
    }
}
$count = 0;
for ($i=0; $i < 3; $i++) { 
    $count += $redis->pfcount(&#39;002|online_users_day_&#39;.$i);
    print_r($redis->pfcount(&#39;002|online_users_day_&#39;.$i). "\n");
}
var_dump($count);
//note  3 days total online num
var_dump($redis->pfmerge(&#39;002|online_users_day_both_3&#39;, [&#39;002|online_users_day_0&#39;, &#39;002|online_users_day_1&#39;, &#39;002|online_users_day_2&#39;]));
var_dump($redis->pfcount(&#39;002|online_users_day_both_3&#39;));

이 솔루션은 특정 기간 동안 온라인 사용자의 총 수만 계산할 수 있으며 온라인 사용자 목록에 대해서는 아무것도 할 수 없지만 통계 데이터 요구 사항이 많지 않은 경우 이것을 고려할 수 있습니다. 일종의 계획.

4 비트맵 통계 사용

비트맵은 비트를 사용하여 요소에 해당하는 값이나 상태를 나타내며, 키는 해당 요소 자체입니다. 우리는 8비트가 바이트를 형성할 수 있다는 것을 알고 있으므로 비트맵 자체가 저장 공간을 크게 절약할 수 있습니다.

비트맵은 사용자 체크인, 활성 사용자, 온라인 사용자 등과 같은 기능에 일반적으로 사용됩니다.

코드는 다음과 같습니다

// 模拟当前用户
$uid = request(&#39;uid&#39;);
$key = &#39;online_bitmap_&#39; . date(&#39;Ymd&#39;);
// 设置当前用户在线
Redis::setBit($key, $uid, 1);
// 可实现功能1:在线人数
$c = Redis::bitCount($key);
echo &#39;在线人数:&#39; . $c . &#39;<br />&#39;;
// 可实现功能2:指定用户是否在线
$online = Redis::getBit($key, $uid);
echo $uid . ($online ? &#39;在线&#39; : &#39;不在线&#39;) . &#39;<br />&#39;;
// 可实现功能3:昨天和今天均上线的用户总数
$yestoday = Carbon::yesterday()->toDateString();
$yes_key = str_replace(&#39;-&#39;, &#39;&#39;, $yestoday);
$c = 0;
Redis::pipeline(function ($pipe) use ($key, $yes_key, &$c) {
    Redis::bitOp(&#39;AND&#39;, &#39;yest&#39;, $key, $yes_key);
    $c = Redis::bitCount(&#39;yest&#39;);
});
echo &#39;昨天和今天都上线的用户数量有:&#39; . $c . &#39;<br />&#39;;

bitmap은 메모리 공간을 많이 소모하지 않지만 많은 통계 정보를 제공하므로 이 솔루션을 추천할 가치가 있습니다.

추천 학습: "PHP 비디오 튜토리얼"

위 내용은 PHP를 사용하여 온라인 사용자 수를 계산하는 네 가지 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 learnku.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제