[toc]web
做爲WebApi接口工程,性能效率是必不可少的,每次的訪問請求,數據庫讀取,業務邏輯處理都或多或少耗費時間,偶爾再來個各類花式for循環,那就嗨翻天了,一些公有的數據,訪問頻繁且大體重複的數據,咱們能夠考慮經過緩存來放置內存存儲,之內存空間換取時間上的提高,至於緩存的方法,Cache,Session,Cookie等,爲何用等呢,由於還有不少緩存的方法,如Redis,具體後面用到了會專門介紹。數據庫
net core中沒有Cache,可是它有MemoryCache,其實,大差不差,畢竟都是Cache。瀏覽器
Cache在項目工程中使用的範圍仍是挺普遍的:緩存
首先,引入Microsoft.Extensions.Caching.Memory性能優化
這裏我直接在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等類庫同樣,其實自己第三方已經作了一次封裝整合,而咱們是由於實際開發須要來針對不一樣的業務功能作不一樣的封裝整合,接口開放等。cookie
補個測試效果,寫到Session纔想起來,唉,果真寫東西不能讓打斷,-,-||。session
注意觀察時間,一段時間後Cache過時銷燬。app
最初鼓搗net core的時候,我確實沒有過多關注Session這個會話模式,畢竟只有瀏覽器才能使用,以前跟別人談到Session多爽的時候,說道Session其實本質上相似Cookie(固然我也不清楚),由於用戶訪問後會有個SessionID,有狀態的訪問會留下Cookie也是情有可原的,若是用戶本身整個隱私模式訪問,那,再見(你就在登陸界面循環往復吧)。負載均衡
在用戶登陸後,Session存儲用戶基本登陸信息這個是web端經常使用的手段,畢竟跟瀏覽器打交道Cookie少不了,對於無狀態訪問受權的JWT也是折騰過,不過仍是理解不透徹,統一的授發token的方式仍是挺可取的,若是是多服務,多應用,負載均衡的場景,單點登陸確實方便,可是我常規會本身生成token來經過Session或者Redis存儲,實際效果應該是差很少吧。 好了,廢話很少說,同樣是引入Microsoft.AspNetCore.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/接口,發現咱們的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賦值。
SessionUtil代碼修改調整,不須要再傳HttpContext這個參數。
這樣少傳一個是一個,後續用到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走一波。
測試結果:
從建立工程到在線文檔,日誌管理,緩存機制基本上走了一遍了,下一步,就是數據層的操做,一個工程管理確定少不了數據的支撐,總不能每次都本身YY數據吧,下一節,數據庫操做。
針對Session.SetString的方法沒有問題,須要引入一個NuGet包,這個裏面包含官方的擴展方法,Microsoft.AspNetCore.Http.Abstractions。