日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

【BCVP更新】StackExchange.Redis 的异步开发方式

發布時間:2023/12/4 数据库 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【BCVP更新】StackExchange.Redis 的异步开发方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

有哪些習慣

堅持

LESS IS MORE,SIMPLER IS BETTER THAN MORE

你一定會有很大的收獲

各種小問題?

如果你之前用過Redis的話,肯定會使用過StackExchange.Redis,我之前很久就用過,在.netfw的時候,當時并發還比較小,沒有什么問題,后來我就遷移到Blog.Core里了,但是有很多小伙伴,反饋高并發下,使用同步的方法會有問題,比如超時的問題,偶爾還會出現什么內存的問題,一直被很多網友所詬病。

一直說國內有一個組件很不錯,這個大家自己去使用吧,我也不多說什么,但是我想著StackExchange.Redis既然是官方推薦的不會這么菜吧,果然官方給的方案是,用異步的方式寫,會解決超時的問題。

那具體應該怎么寫呢,我還沒有來得及思考,正好這兩天研究微軟的微服務案例eShopOnContainers,我發現他就是用的StackExchange.Redis實現的購物車緩存的子服務邏輯,研究了下,遷移到Blog.Core項目中,當然我這里簡單測試了下,并發下沒有問題,大家還是可以自行測試,當然還是那句話,有問題了我會繼續修改,如果還是不行,那自己就換其他的組件吧。

設計異步方案

這個比較簡單的,設計思路和之前的是一樣的,只不過有一點,連接調制器的注入方式我做了調整(ConnectionMultiplexer),之前用的是雙if夾lock的方式,實現的單例,現在直接使用依賴注入AddSingleton的方式,更專業些,也沒那么幺蛾子:

/// <summary> /// Redis緩存 啟動服務 /// </summary> public static class RedisCacheSetup {public static void AddRedisCacheSetup(this IServiceCollection services){if (services == null) throw new ArgumentNullException(nameof(services));services.AddTransient<IRedisBasketRepository,?RedisBasketRepository>();services.AddSingleton<ConnectionMultiplexer>(sp =>{//獲取連接字符串string redisConfiguration = Appsettings.app(new string[] { "AppSettings", "RedisCachingAOP", "ConnectionString" });var?configuration?=?ConfigurationOptions.Parse(redisConfiguration,?true);configuration.ResolveDns?=?true;return ConnectionMultiplexer.Connect(configuration);});} }

這里是Redis依賴注入的擴展方法,需要在Startup里配置上,別忘記了:

services.AddRedisCacheSetup();

然后就是設計接口和實現類了,也很簡單,接口和之前的一樣,只不過都換成了異步:

/// <summary>/// Redis緩存接口/// </summary>public interface IRedisBasketRepository{//獲取 Reids 緩存值Task<string> GetValue(string key);//獲取值,并序列化Task<TEntity> Get<TEntity>(string key);//保存Task Set(string key, object value, TimeSpan cacheTime);//判斷是否存在Task<bool> Exist(string key);//移除某一個緩存值Task Remove(string key);//全部清除Task Clear();}

接口的名稱我為了紀念eShop項目,保持一致了,雖然比較怪,自己酌情修改吧。

然后實現類也很簡單,構造函數直接注入日志和連接調制器實例,不用寫復雜的單例模式了:

public class RedisBasketRepository : IRedisBasketRepository{private readonly ILogger<RedisBasketRepository> _logger;private readonly ConnectionMultiplexer _redis;private readonly IDatabase _database;public RedisBasketRepository(ILogger<RedisBasketRepository> logger, ConnectionMultiplexer redis){_logger = logger;_redis = redis;_database = redis.GetDatabase();}private IServer GetServer(){var endpoint = _redis.GetEndPoints();return _redis.GetServer(endpoint.First());}public async Task Clear(){foreach (var endPoint in _redis.GetEndPoints()){var server = GetServer();foreach (var key in server.Keys()){await _database.KeyDeleteAsync(key);}}}public async Task<bool> Exist(string key){return await _database.KeyExistsAsync(key);}public async Task<string> GetValue(string key){return await _database.StringGetAsync(key);}public async Task Remove(string key){await _database.KeyDeleteAsync(key);}public async Task Set(string key, object value, TimeSpan cacheTime){if (value != null){//序列化,將object值生成RedisValueawait _database.StringSetAsync(key, SerializeHelper.Serialize(value), cacheTime);}}public async Task<TEntity> Get<TEntity>(string key){var value = await _database.StringGetAsync(key);if (value.HasValue){//需要用的反序列化,將Redis存儲的Byte[],進行反序列化return SerializeHelper.Deserialize<TEntity>(value);}else{return default(TEntity);}}}

相應的邏輯也很簡單,我詳細基本都能看得懂。

最后就是在BlogRedisCacheAOP.cs中,也要修改下,畢竟改成了異步,還是要注意的:

寫到最后

九月馬上就要到了,新的一年也快結束了,準備好迎接125天的2021年了么!希望新的一年,一起都好起來,大家也要趁著時間好好學學知識,因為我相信到時候肯定會有很多崗位,機會總是會留給有準備的人,相信我,相信你自己。

生活の藝術

總結

以上是生活随笔為你收集整理的【BCVP更新】StackExchange.Redis 的异步开发方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。