net core Webapi基礎工程搭建(五)——緩存機制


前言

作為WebApi接口工程,性能效率是必不可少的,每次的訪問請求,數據庫讀取,業務邏輯處理都或多或少耗費時間,偶爾再來個各種花式for循環,那就嗨翻天了,一些公有的數據,訪問頻繁且大致重復的數據,我們可以考慮通過緩存來放置內存存儲,以內存空間換取時間上的提升,至於緩存的方法,Cache,Session,Cookie等,為什么用等呢,因為還有很多緩存的方法,如Redis,具體后面用到了會專門介紹。

Cache

net core中沒有Cache,但是它有MemoryCache,其實,大差不差,畢竟都是Cache。

Cache在項目工程中使用的范圍還是挺廣泛的:

  • 在個人開發的時候,我一般會把系統字典做緩存,方便調用提高響應速度
  • 消息推送后,會把消息實體緩存
  • 其他,自己看着辦吧

首先,引入Microsoft.Extensions.Caching.Memory

Cache
這里我直接在Util引入,前面已經講了,一個工程引入第三方,其他工程引入項目工程即可使用對應第三方類庫。
引入完成后,我們就開始來使用這個MemoryCache吧。

	//實例化
	private static readonly MemoryCache Cache = new MemoryCache(new MemoryCacheOptions());
	/// <summary>
    /// 添加緩存
    /// </summary>
    /// <param name="key">緩存Key</param>
    /// <param name="value">緩存Value</param>
    /// <param name="expiresSliding">滑動過期時長(如果在過期時間內有操作,則以當前時間點延長過期時間)</param>
    /// <param name="expiressAbsoulte">絕對過期時長</param>
    /// <returns></returns>
    public static bool Set(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
    {
        if (key == null)
            throw new ArgumentNullException(nameof(key));
        if (value == null)
            throw new ArgumentNullException(nameof(value));

        Cache.Set(key, value,
            new MemoryCacheEntryOptions().SetSlidingExpiration(expiresSliding)
                .SetAbsoluteExpiration(expiressAbsoulte));
        return Exists(key);
    }

    /// <summary>
    /// 添加緩存
    /// </summary>
    /// <param name="key">緩存Key</param>
    /// <param name="value">緩存Value</param>
    /// <param name="expiresIn">緩存時長</param>
    /// <param name="isSliding">是否滑動過期(如果在過期時間內有操作,則以當前時間點延長過期時間)</param>
    /// <returns></returns>
    public static bool Set(string key, object value, TimeSpan expiresIn, bool isSliding = false)
    {
        if (key == null)
            throw new ArgumentNullException(nameof(key));
        if (value == null)
            throw new ArgumentNullException(nameof(value));

        Cache.Set(key, value,
            isSliding
                ? new MemoryCacheEntryOptions().SetSlidingExpiration(expiresIn)
                : new MemoryCacheEntryOptions().SetAbsoluteExpiration(expiresIn));

        return Exists(key);
    }

這個地方大致列下如何使用,其實對於第三方的包,我們封裝是為了減少其他開發人員的學習成本,后面的SqlSugar等類庫一樣,其實本身第三方已經做了一次封裝整合,而我們是因為實際開發需要來針對不同的業務功能做不同的封裝整合,接口開放等。

補個測試效果,寫到Session才想起來,唉,果然寫東西不能讓打斷,-,-||。

Values

Cache測試
注意觀察時間,一段時間后Cache過期銷毀。

Cache測試

Session

最初鼓搗net core的時候,我確實沒有過多關注Session這個會話模式,畢竟只有瀏覽器才能使用,之前跟別人談到Session多爽的時候,說道Session其實本質上類似Cookie(當然我也不清楚),因為用戶訪問后會有個SessionID,有狀態的訪問會留下Cookie也是情有可原的,如果用戶自己整個隱私模式訪問,那,再見(你就在登錄界面循環往復吧)。

在用戶登錄后,Session存儲用戶基本登錄信息這個是web端常用的手段,畢竟跟瀏覽器打交道Cookie少不了,對於無狀態訪問授權的JWT也是折騰過,不過還是理解不透徹,統一的授發token的方式還是挺可取的,如果是多服務,多應用,負載均衡的場景,單點登錄確實方便,但是我常規會自己生成token來通過Session或者Redis存儲,實際效果應該是差不多吧。
好了,廢話不多說,一樣是引入Microsoft.AspNetCore.Session

Session
引入完成后,在Startup.cs注冊Session服務。

        public void ConfigureServices(IServiceCollection services)
        {
            //…之前的代碼
            
            #region Session
            services.AddSession(options =>
            {
                options.Cookie.Name = "April.Session";
                options.IdleTimeout = TimeSpan.FromSeconds(2000);//設置session的過期時間
                options.Cookie.HttpOnly = true;//設置在瀏覽器不能通過js獲得該cookie的值,實際場景根據自身需要
            });
            #endregion
        }

注冊服務后,需要在ConfigConfigure使用,注意所有的Use要在UserMvc之前才能生效。

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            //…之前的代碼

            app.UseSession();//這里使用

            app.UseHttpsRedirection();
            app.UseMvc();
        }

在Util創建一個SessionUtil,來封裝Session方法,這里只簡單描述下如何使用,后續代碼開源后可查看源碼使用。

    public class SessionUtil
    {
        /// <summary>
        /// 設置Session
        /// </summary>
        /// <param name="key">鍵</param>
        /// <param name="value">值</param>
        public void SetSession(HttpContext content,string key, string value)
        {
            content.Session.SetString(key, value);
        }
        /// <summary>
        /// 獲取Session
        /// </summary>
        /// <param name="key">鍵</param>
        /// <returns>返回對應的值</returns>
        public string GetSession(HttpContext context, string key, string defaultValue = "")
        {
            string value = context.Session.GetString(key);
            if (string.IsNullOrEmpty(value))
            {
                value = defaultValue;
            }
            return value;
        }
    }

我們依然拿這個萬惡的ValuesController開刀。

Values
運行后,訪問這個Values/{id}接口,發現我們的Session值已經獲取到了。

數據

HttpContext這個對象,可以通過IServiceProvider來獲取,這樣方便調用統一維護。
新建AprilConfig類文件,代碼如下:

    public class AprilConfig
    {
        public static IServiceProvider _provider;

        public static HttpContext HttpCurrent
        {
            get
            {
                object factory = _provider.GetService(typeof(IHttpContextAccessor));
                HttpContext context = ((IHttpContextAccessor)factory).HttpContext;
                return context;
            }
        }
    }

寫好后我們需要回到Startup.cs,給IserviceProvider賦值。

Startup
SessionUtil代碼修改調整,不需要再傳HttpContext這個參數。

SessionUtil
這樣少傳一個是一個,后續用到HttpContext這個上下文的時候,也不用考慮啥了,直接AprilConfig.HttpCurrent走起。

Cookie在web開發使用的還是相當頻繁的,畢竟不占用服務器內存,跟服務器基本上沒半毛錢關系,客戶端的內存想咋折騰咋折騰,客戶端的資源想咋使用咋使用(ps:這就是為啥你的電腦越來越卡,軟件開發不考慮性能優化的種種結果)。

Cookie本身在net core中已經支持,所以不需要引入啥NuGet包。

新建CookieUtil(不要吐槽我的命名方法,習慣了)。

public class CookieUtil
    {
        /// <summary>
        /// 設置本地cookie
        /// </summary>
        /// <param name="key">鍵</param>
        /// <param name="value">值</param>  
        /// <param name="minutes">過期時長,單位:分鍾</param>      
        public static void SetCookies(string key, string value, int minutes = 10)
        {
            AprilConfig.HttpCurrent.Response.Cookies.Append(key, value, new CookieOptions
            {
                Expires = DateTime.Now.AddMinutes(minutes)
            });
        }
        /// <summary>
        /// 刪除指定的cookie
        /// </summary>
        /// <param name="key">鍵</param>
        public static void DeleteCookies(string key)
        {
            //這個地方想判斷就判斷下,不過內部封裝的方法應該是已經做過處理
            AprilConfig.HttpCurrent.Response.Cookies.Delete(key);
        }

        /// <summary>
        /// 獲取cookies
        /// </summary>
        /// <param name="key">鍵</param>
        /// <returns>返回對應的值</returns>
        public static string GetCookies(string key,string defaultValue="")
        {
            string value = string.Empty;
            AprilConfig.HttpCurrent.Request.Cookies.TryGetValue(key, out value);
            if (string.IsNullOrEmpty(value))
            {
                value = defaultValue;
            }
            return value;
        }
    }

寫好之后,老規矩ValuesController走一波。

Values
測試結果:

測試結果

小結

從創建工程到在線文檔,日志管理,緩存機制基本上走了一遍了,下一步,就是數據層的操作,一個工程管理肯定少不了數據的支撐,總不能每次都自己YY數據吧,下一節,數據庫操作

補充

針對Session.SetString的方法沒有問題,需要引入一個NuGet包,這個里面包含官方的擴展方法,Microsoft.AspNetCore.Http.Abstractions


免責聲明!

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



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