• (五)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支持 实现了缓存拦截。所以有需要的小伙伴可以升个级试试看。

    关于缓存的连接  也是通过注册中心来检查它的健康状态。

    最后运行程序,得到结果

  • 相关阅读:
    .NET破解之太乐地图下载器【非暴破】
    DevExpress中透明玻璃效果
    mysql实时同步到mssql的解决方案
    求点云的边界的方法小结
    ArcEngine中License权限等级更改的问题
    汉化入门之ExplorerControls
    spring cloud ribbon和feign的区别
    IntelliJ IDEA 运行 Maven 项目
    Python中操作SQLAlchemy
    MySQL 可以用localhost 连接,但不能用IP连接的问题,局域网192.168.*.* 无法连接mysql
  • 原文地址:https://www.cnblogs.com/Jeely/p/10774648.html
Copyright © 2020-2023  润新知