8

AbpVnext使用分布式IDistributedCache Redis缓存(自定义扩展方法)

 2 years ago
source link: https://www.cnblogs.com/Fengge518/p/15220246.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

AbpVnext使用分布式IDistributedCache Redis缓存(自定义扩展方法)

AbpVnext使用分布式IDistributedCache缓存from Redis(带自定义扩展方法)

首先搭好Docker中的Redis环境(个人测试环境):

 我的依赖包的主要版本以及Redis依赖如下

1:添加依赖

 <PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="3.0.5" />
 
 <ItemGroup>
    <PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
    <PackageReference Include="Microsoft.Extensions.PlatformAbstractions" Version="1.1.0" />
    <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.9.5" />
    <PackageReference Include="Serilog.Extensions.Hosting" Version="3.1.0" />
    <PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
    <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
    <PackageReference Include="Serilog.Sinks.Elasticsearch" Version="8.2.0" />
    <PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
    <PackageReference Include="SqlSugar.IOC" Version="1.4.0" />
    <PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.5.1" />
    <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUi" Version="5.5.1" />
    <PackageReference Include="Volo.Abp.AspNetCore" Version="3.0.5" />
    <PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" Version="3.0.5" />
    <PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared" Version="3.0.5" />
    <PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="3.0.5" />
    <PackageReference Include="Volo.Abp.Autofac" Version="3.0.5" />
    <PackageReference Include="Volo.Abp.UI.Navigation" Version="3.0.5" />
    //添加AbpVnext分布式redis缓存依赖包
    <PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="3.0.5" />
  </ItemGroup>

2:配置信息。默认在appsetting.json中配置即可,格式如下:

"Redis": { //Redis:Configuration
    "IsEnabled": "true",
  //该服务将会吧数据存储在DB7的数据库中
  "Configuration": "171.74.78.153:6379,password=9966686@,defaultdatabase=7" 
}

3:在hosting模块中添加依赖

using Volo.Abp.Caching.StackExchangeRedis;

namespace GDBS.MonitoringService.HttpApi.Hosting
{
    [DependsOn(
          typeof(AbpAutofacModule),
          typeof(AbpAspNetCoreMvcModule),
          typeof(AbpAspNetCoreAuthenticationJwtBearerModule)
         , typeof(IdentityEntityFrameworkCoreModule)
         , typeof(MonitoringHttpApiModule)
         , typeof(MonitoringApplicationContractsModule)
         , typeof(SharedToolKitsModule)
         , typeof(JketSharedDomainModule)
        , typeof(AbpCachingStackExchangeRedisModule)//这里新增依赖模块
     )]
    public class MonitoringHttpApiHostingModule : AbpModule
    {
      public override void ConfigureServices(ServiceConfigurationContext context)
          {
            //测试时下面配置了还出不来,写入没有效果??这里就直接在配置文件中处理了。
            //service.AddStackExchangeRedisCache(redisoptions =>
            //{
            //    redisoptions.Configuration = configuration["Redis:Configuration"];
            //    redisoptions.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions
            //    {
            //        ConnectTimeout = 10
            //        //EndPoints=new StackExchange.Redis.EndPointCollection { 
                       
            //        //}
            //    };
            //});
      }
    }

4:Controller中的主要代码

namespace GDBS.ProvincialLevelService.HttpApi.Controller
{
    /// <summary>
    /// ProvincialLevelService 省级服务
    /// </summary>
    [Authorize]
    [Area("ProvincialLevelService")]
    [Route("api/ProvincialLevelService/[Controller]")]
    public class ProvincialLevelDataInfoController : AbpController
    {
        private readonly IBridgeTestDataService _service;
        private readonly IBridgeTestDataService _service;
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly IHttpContextAccessor _httpContext;
        private readonly IFilesInfoService _filesInfoservice;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="service"></param>
        /// <param name="httpClientFactory"></param>
        /// <param name="httpContext"></param>
        public ProvincialLevelDataInfoController(IBridgeTestDataService service, IHttpClientFactory httpClientFactory, IHttpContextAccessor httpContext, IFilesInfoService filesInfoservice)
        {
            _service = service;
            _httpClientFactory = httpClientFactory;
            _httpContext = httpContext;
            _filesInfoservice = filesInfoservice;
        }


        /// <summary>
        /// TestRedisAddString
        /// </summary>
        /// <param name="key"></param>
        /// <param name="redisvalue"></param>
        /// <returns></returns>
        [HttpGet("TestRedisAddString")]
        [AllowAnonymous]
        public async Task<OutputDto> TestRedisAddString(string key, string redisvalue)
        {
            try
            {
                await _service.DoTestRedis(key, redisvalue);
                return OutputDto.ToResultSuccess(msg: "ok");
            }
            catch (Exception ex)
            {
                return OutputDto.ToResultFail(ex.Message);
            }
        }
  }
}

5:Application中,通常我们在这里来注入分布式接口

using Microsoft.Extensions.Caching.Distributed;
namespace GDBS.ProvincialLevelService.Application.AppService
{
    public class BridgeTestDataService : ApplicationService, IBridgeTestDataService
    {
        private readonly IDistributedCache _distributedCache;
        public BridgeTestDataService(IDistributedCache distributedCache)
        {
            _distributedCache = distributedCache;
        }

        public async Task<string> DoTestRedis(string key, string redisvalue)
        {
            try
            {
                await _distributedCache.SetStringAsync(key,redisvalue);
                return "ok";
            }
            catch (Exception ex)
            {
                return $"错误{ex.Message}";
            }
        }
    }
}

6:为了方便直接在Controller中注入测试,通常我们需要在Application中注入使用

     /// <summary>
     /// _cacheServer 通常我们在Application里面注册,这里只是测试
     /// </summary>
     private readonly IDistributedCache _cacheServer;
     public ProvincialLevelDataInfoController(IDistributedCache cacheServer)
     {
       _cacheServer = cacheServer;
     }
        /// <summary>
        /// TestRedisAddString
        /// </summary>
        /// <param name="key"></param>
        /// <param name="redisvalue"></param>
        /// <param name="ab_hd">true绝对过期,false:滑动过期</param>
        /// <returns></returns>
        [HttpGet("TestRedisAddString2")]
        [AllowAnonymous]
        public async Task<OutputDto> TestRedisAddString2(string key, string redisvalue, bool ab_hd = true)
        {
            try
            {
                await _cacheServer.SetStringAsync(key, redisvalue, RedisPolicyHelper.GetRedisProcily(ab_hd,60));
                return OutputDto.ToResultSuccess(msg: "ok");
            }
            catch (Exception ex)
            {
                return OutputDto.ToResultFail(ex.Message);
            }
        }

7:分布式缓存的策略,使用绝对还是滑动过期,不使用策略就默认为长期保存,可以使用控制方法

using Microsoft.Extensions.Caching.Distributed;
using System;
namespace GDBS.Shared.ToolKits.Tool
{
    public class RedisPolicyHelper
    {
        /// <summary>
        /// 使用绝对还是滑动过期,不使用策略就默认为长期保存
        /// </summary>
        /// <param name="ab_hd">true绝对过期; false:滑动过期</param>
        /// <param name="Seconds">默认60秒过期</param>
        /// <returns></returns>
        public static DistributedCacheEntryOptions GetRedisProcily(bool ab_hd, int Seconds = 60)
        {
            var policy = new DistributedCacheEntryOptions();
            Seconds = Seconds <= 1 ? 60 : Seconds;
            if (ab_hd)
                policy.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(Seconds);
            else
                policy.SlidingExpiration = TimeSpan.FromSeconds(Seconds);
            return policy;
        }
    }
}

8:自定义分布式缓存扩展方法

using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Microsoft.Extensions.Caching.Distributed;
namespace GDBS.Shared.ToolKits
{
    public static class RedisDistributeExtension
    {
        /// <summary>
        /// 自定义IDistribute 分布式扩展方法 jason 同步方法
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="cache"></param>
        /// <param name="key"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        public static TModel RedisGetOrCreate<TModel>(this IDistributedCache cache, string key, Func<DistributedCacheEntryOptions, TModel> handler)
        {
            TModel t;
            string vs = cache.GetString(key);
            if (string.IsNullOrEmpty(vs))
            {
                var options = new DistributedCacheEntryOptions();
                t = handler.Invoke(options);
                cache.SetString(key, JsonConvert.SerializeObject(t), options);
            }
            else
            {
                t = JsonConvert.DeserializeObject<TModel>(vs);
            }
            return t;
        }
        /// <summary>
        /// 自定义IDistribute 分布式扩展方法 jason 异步方法
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="cache"></param>
        /// <param name="key"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        public static async Task<TModel> RedisGetOrCreateAsync<TModel>(this IDistributedCache cache, string key, Func<DistributedCacheEntryOptions, Task<TModel>> handler)
        {
            TModel t;
            var vs = await cache.GetStringAsync(key);
            if (string.IsNullOrEmpty(vs))
            {
                var options = new DistributedCacheEntryOptions();
                t = await handler.Invoke(options);
                await cache.SetStringAsync(key, JsonConvert.SerializeObject(t), options);
            }
            else
            {
                t = JsonConvert.DeserializeObject<TModel>(vs);
            }
            return t;
        }
    }
}

9:测试自定义扩展方法,Controller中的主要code。

       /// <summary>
        /// 自定义分布式缓存的扩展方法,没有缓存就设置缓存,有就直接获取
        /// </summary>
        /// <param name="key"></param>
        /// <param name="redisvalue"></param>
        /// <param name="ab_hd"></param>
        /// <returns></returns>
        [HttpGet("TestRedisAddString3")]
        [AllowAnonymous]
        public async Task<OutputDto> TestRedisAddString3(string key, string redisvalue, bool ab_hd = true)
        {
            try
            {
                await _cacheServer.RedisGetOrCreateAsync<string>(key, (options) =>
                {
                    options.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(30);
                    return Task.Factory.StartNew(() =>
                    {
                        return $"_cacheServer.RedisGetOrCreateAsync获取或者设置缓存的方法:{redisvalue},时间:{DateTime.Now}";
                    });
                });
                return OutputDto.ToResultSuccess(msg: "ok");
            }
            catch (Exception ex)
            {
                return OutputDto.ToResultFail(ex.Message);
            }
        }

10:调用自定义分布式扩展方法

11:测试结果部分主要截图:

 12:公司一微服务系统中有多个服务,我们将不同的服务缓存数据将来存储在不同的Redis数据库中

 好了今天就先到这里,下次有时间再更新,自学AbpVnext过程中难免会有一些bug或者不合理的地方,欢迎大家多多指教留言!!!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK