Redis應用(一)實時在線用戶


前言

本系列教程是在學習《Redis實戰》同時,利用 Redis 解決實際的業務問題。

問題

項目里有一個功能是實時數據看板,其中有一項數據是實時在線用戶數。

解決方案

常見的解決方案有三種:

  1. 列表
  2. 數據庫
  3. Redis

列表

使用編程語言里的列表,比如 C#List 或者 JavaArrayList,保存到內存里。

  • 好處:讀寫快,訪問內存快。
  • 壞處:程序內無法共享,比如在 api 層記錄用戶狀態,在后台顯示數據。

數據庫

把用戶的狀態保存到數據庫里,讀取時也從數據庫查詢。

  • 好處:連接上數據庫的應用都能訪問。
  • 壞處:並發高時,數據庫會出現性能問題。

Redis

以上兩種方法,都存在各自的問題,而 Redis 有以上兩種方法的好處,沒有它們的壞處。

Redis 基於內存進行讀寫的,性能比數據庫要高很多,支持分布式訪問,其他應用都能夠使用。

解決步驟:

  1. 記錄用戶狀態(api)。使用有序列表保存用戶狀態,並且設置一個過期時間作為 Score
  2. 獲取實時在線用戶數(api)。直接通過有序列表獲取長度,例如 StackExchange.Redis 里的 SortedSetLength
  3. 定時清理過期的在線用戶(后台服務)。例如 StackExchange.Redis 里的 SortedSetRemoveRangeByScore
using System;
using System.Diagnostics;
using System.Threading;
using StackExchange.Redis;

namespace RealtimeOnlineUser
{
    class Program
    {
        static void Main(string[] args)
        {
            var redis = new RedisHelper("localhost:6379", "", 15);
            new Program(redis.GetDatabase()).TestOnlineUser();
        }

        private IDatabase _db;
        private string _key = "online";

        public Program(IDatabase db)
        {
            this._db = db;
        }

        public void TestOnlineUser()
        {
            Console.WriteLine("------ TestOnlineUser ------");

            Console.WriteLine("Add user per 10s.");
            var tokens = new string[] { "1", "2", "3", "4", "5" };
            foreach (var token in tokens)
            {
                Thread.Sleep(10 * 1000); // 每10s添加一用戶
                Console.WriteLine($"{token} Logined.");
                SetToken(token);
            }

            Console.WriteLine("Waiting for 35s.");
            Thread.Sleep(35 * 1000);
            Console.WriteLine("Clean overdue user.");
            Clean();

            var count = _db.SortedSetLength(_key);
            Console.WriteLine($"Online user count: {count}.");

            Debug.Assert(count == 3);
        }

        private void SetToken(string token)
        {
            long timestamp = GetCurrentMilliseconds() + 60 * 1000; // 緩存60s

            _db.SortedSetAdd(_key, token, timestamp);
        }

        private void Clean()
        {
            // 清空過期的用戶
            long timestamp = GetCurrentMilliseconds();
            _db.SortedSetRemoveRangeByScore(_key, 0, timestamp);
        }

        private long GetCurrentMilliseconds()
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 當地時區
            long timestamp = (long) (DateTime.Now - startTime).TotalMilliseconds; // 相差秒數
            return timestamp;
        }
    }
}

總結

上面通過 Redis 來實現實時在線用戶數功能。其他類似的數據也可以通過 Redis 來實現,比如最多訪問URL top10、用戶區域分布等等。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM