(五)surging 微服務框架使用系列之緩存-reids


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支持 實現了緩存攔截。所以有需要的小伙伴可以升個級試試看。

關於緩存的連接  也是通過注冊中心來檢查它的健康狀態。

最后運行程序,得到結果

 


免責聲明!

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



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