1.服務跟客戶端初始化的時候需要添加緩存配置
1 var host = new ServiceHostBuilder() 2 .RegisterServices(builder => 3 { 4 builder.AddMicroService(option => 5 {
6 option .AddCache()//緩存初始化
28 });
29 }).Configure(build =>
47 build.AddCacheFile("cacheSettings.json", optional: false,reloadOnChange:true))
48 .UseStartup<Startup>()
52 .Build();
2.配置文件(服務端跟客戶端都需要)
{ "CachingSettings": [ { "Id": "ddlCache", "Class": "Surging.Core.Caching.RedisCache.RedisContext,Surging.Core.Caching", "InitMethod": "", "Maps": null, "Properties": [ { "Name": "appRuleFile", "Ref": "rule", "Value": "", "Maps": null }, { "Name": "dataContextPool", "Ref": "ddls_sample", "Value": "", "Maps": [ { "Name": "Redis",//redis配置 "Properties": [ { "Name": null, "Ref": null, "Value": ":你的密碼@你的ip:6379::1",//reids 內存數據庫連接字符串傳 后面的1 代表你當前連接的是哪個庫 "Maps": null } ] }, { "Name": "MemoryCache",//本機內存 "Properties": null } ] }, { "Name": "defaultExpireTime",//默認超時時間 "Ref": "", "Value": "120", "Maps": null }, { "Name": "connectTimeout",//連接超時時間 "Ref": "", "Value": "120", "Maps": null }, { "Name": "minSize", "Ref": "", "Value": "1", "Maps": null }, { "Name": "maxSize", "Ref": "", "Value": "10", "Maps": null } ] } ] }
3.服務端配置
[Command(RequestCacheEnabled = true)] [InterceptMethod(CachingMethod.Get, Key = "GetUser_id_{0}", CacheSectionType = SectionType.ddlCache, Mode = CacheTargetType.Redis, Time = 480)] Task<UserModel> GetUser(UserModel user);
(1)在容錯規則里面配置開啟緩存
(2)在緩存攔截器里面配置緩存的方法,key,類型,超時時間等等。。
(3)傳遞的方法參數如果是model類型,就需要設置 [CacheKey(1)]來標識緩存key, 比如傳遞UserModel,
設置UserId 為1,Name 為fanly, 設置的KEY為GetUserName_name_{1}
那么緩存的key就會生成GetUserName_name_fanly, key 如果設置為GetUserName_id_{0}
那么緩存的key就會生成GetUserName_id_1,傳遞的方法參數是string,int 類型就不需要設置 [CacheKey(1)]
(4)Remove模式下,移除的緩存是一個真個列表
public class UserModel { [CacheKey(1)] public int UserId { get; set; } [CacheKey(2)] public string Name { get; set; } public int Age { get; set; } }
4.客戶端調用配置
客戶端初始化的時候 需要添加.AddClientIntercepted(typeof(CacheProviderInterceptor)),其中CacheProviderInterceptor是作者給我們實現的一個實例,代碼如下:
public class CacheProviderInterceptor : CacheInterceptor { public override async Task Intercept(ICacheInvocation invocation) { var attribute = invocation.Attributes.Where(p => p is InterceptMethodAttribute) .Select(p => p as InterceptMethodAttribute).FirstOrDefault(); var cacheKey = invocation.CacheKey == null ? attribute.Key : string.Format(attribute.Key ?? "", invocation.CacheKey); await CacheIntercept(attribute, cacheKey, invocation); } private async Task CacheIntercept(InterceptMethodAttribute attribute, string key, ICacheInvocation invocation) { ICacheProvider cacheProvider = null; switch (attribute.Mode) { case CacheTargetType.Redis: { cacheProvider = CacheContainer.GetService<ICacheProvider>(string.Format("{0}.{1}", attribute.CacheSectionType.ToString(), CacheTargetType.Redis.ToString())); break; } case CacheTargetType.MemoryCache: { cacheProvider = CacheContainer.GetService<ICacheProvider>(CacheTargetType.MemoryCache.ToString()); break; } } if (cacheProvider != null) await Invoke(cacheProvider, attribute, key, invocation); } private async Task Invoke(ICacheProvider cacheProvider, InterceptMethodAttribute attribute, string key, ICacheInvocation invocation) { switch (attribute.Method) { case CachingMethod.Get: { var retrunValue = await cacheProvider.GetFromCacheFirst(key, async () => { await invocation.Proceed(); return invocation.ReturnValue; }, invocation.ReturnType, attribute.Time); invocation.ReturnValue = retrunValue; break; } default: { await invocation.Proceed(); var keys = attribute.CorrespondingKeys.Select(correspondingKey => string.Format(correspondingKey, invocation.CacheKey)).ToList(); keys.ForEach(cacheProvider.RemoveAsync); break; } } } }
找到InterceptMethodAttribute 的配置屬性根據配置的緩存類型 初始化ICacheProvider接口,這個接口是緩存的一些常用方法,(當然我們也直接可以在代碼中或者這個接口的實例,從而在緩存計算一些值)
然后在Invoke方法里面執行緩存的方法
5.其他
關於緩存攔截 我目前的版本是0.7.0.1 是只能在調用代理的時候用使用。因為在代理的時候才會根據容錯規則開啟緩存開關 來決定執行是否走緩存攔截。新版本的http支持 實現了緩存攔截。所以有需要的小伙伴可以升個級試試看。
關於緩存的連接 也是通過注冊中心來檢查它的健康狀態。
最后運行程序,得到結果