Laravel 11 đếm view với cache redis và database
Sự kết hợp này làm giảm tải cho server database và tận dụng hệ thống cache redis của khách hàng
<?php
namespace App\Services;
use App\Models\Seo;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class ViewService
{
public string $store_cache;
public int $check_time_minutes, $count_update_db,$cache_name;
public function __construct()
{
$this->store_cache = 'redis';
$this->check_time_minutes = 60;
$this->count_update_db = 100;
}
// bảng database gồm seo_id và count
public function get(Seo $seo)
{
// Tên cache
$cache_name = 'cache_view_' . $seo->id;
// Lấy giá trị view từ database
$count_db = $seo->view->count ?? 0;
// Lấy giá trị cache, mặc định 0 nếu không có
$count_cache = Cache::store($this->store_cache)->get($cache_name, 0);
return $count_cache + $count_db;
}
public function add(Seo $seo, \Illuminate\Http\Request $request)
{
$fingerprint = $request->fingerprint();
$ip = $request->ip();
$sessionid = $request->session()->getId();
$useragent = $request->userAgent();
// kiểm tra xem cache thì bỏ qua ko thì chạy tiếp
$check_key = 'viewservice.' . $fingerprint . '.seoid.' . $seo->id;
if (Cache::store($this->store_cache)->has($check_key)) {
return null;
}
Cache::store($this->store_cache)->put($check_key, 1, Carbon::now()->addMinutes($this->check_time_minutes));
// lưu thông tin vào history
// Tên cache
$cache_name = 'cache_view_' . $seo->id;
// Nếu có cache
if (Cache::store($this->store_cache)->has($cache_name)) {
// Nếu cache lớn hơn 100 thì cộng vào database và xóa cache
if (Cache::store($this->store_cache)->get($cache_name) > $this->count_update_db) {
try {
DB::transaction(function () use ($cache_name, $seo) {
$seo->view()->updateOrCreate(['seo_id' => $seo->id], ['count' => DB::raw('count + ' . Cache::store($this->store_cache)->get($cache_name))]);
Cache::store($this->store_cache)->put($cache_name, 1);
});
} catch (\Exception $e) {
Log::info('lỗi cộng view');
Log::error($e->getMessage());
Log::info('hết lỗi cộng view');
}
} else {
Cache::store($this->store_cache)->increment($cache_name);
}
} else {
Cache::store($this->store_cache)->put($cache_name, 1);
}
}
}
Ở đây mình viết thành 1 service để các bạn dễ tùy chỉnh cho vào code của mình .Lưu ý có thể thêm vào historu người dùng