首页 > 数据库 >dotnet aspnet redis 缓存 分布式缓存

dotnet aspnet redis 缓存 分布式缓存

时间:2024-02-13 16:22:06浏览次数:35  
标签:缓存 string distCache redis cacheKey dotnet using options

分布式缓存\appsettings.Development.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

分布式缓存\appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

分布式缓存\DistributedCacheHelper.cs

using Microsoft.Extensions.Caching.Distributed;
using System;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace Zack.ASPNETCore
{
    public class DistributedCacheHelper : IDistributedCacheHelper
    {
        private readonly IDistributedCache distCache;

        public DistributedCacheHelper(IDistributedCache distCache)
        {
            this.distCache = distCache;
        }

        private static DistributedCacheEntryOptions CreateOptions(int baseExpireSeconds)
        {
            //过期时间.Random.Shared 是.NET6新增的
            double sec = Random.Shared.Next(baseExpireSeconds, baseExpireSeconds * 2);
            TimeSpan expiration = TimeSpan.FromSeconds(sec);
            DistributedCacheEntryOptions options = new DistributedCacheEntryOptions();
            options.AbsoluteExpirationRelativeToNow = expiration;
            return options;
        }

        public TResult? GetOrCreate<TResult>(string cacheKey, Func<DistributedCacheEntryOptions, TResult?> valueFactory, int expireSeconds = 60)
        {
            string jsonStr = distCache.GetString(cacheKey);
            //缓存中不存在
            if (string.IsNullOrEmpty(jsonStr))
            {
                var options = CreateOptions(expireSeconds);
                TResult? result = valueFactory(options);//如果数据源中也没有查到,可能会返回null
                //null会被json序列化为字符串"null",所以可以防范“缓存穿透”
                string jsonOfResult = JsonSerializer.Serialize(result,
                    typeof(TResult));
                distCache.SetString(cacheKey, jsonOfResult, options);
                return result;
            }
            else
            {
                //"null"会被反序列化为null
                //TResult如果是引用类型,就有为null的可能性;如果TResult是值类型
                //在写入的时候肯定写入的是0、1之类的值,反序列化出来不会是null
                //所以如果obj这里为null,那么存进去的时候一定是引用类型
                distCache.Refresh(cacheKey);//刷新,以便于滑动过期时间延期
                return JsonSerializer.Deserialize<TResult>(jsonStr)!;
            }
        }


        public async Task<TResult?> GetOrCreateAsync<TResult>(string cacheKey, Func<DistributedCacheEntryOptions, Task<TResult?>> valueFactory, int expireSeconds = 60)
        {
            string jsonStr = await distCache.GetStringAsync(cacheKey);
            if (string.IsNullOrEmpty(jsonStr))
            {
                var options = CreateOptions(expireSeconds);
                TResult? result = await valueFactory(options);
                string jsonOfResult = JsonSerializer.Serialize(result,typeof(TResult));
                await distCache.SetStringAsync(cacheKey, jsonOfResult, options);
                return result;
            }
            else
            {
                await distCache.RefreshAsync(cacheKey);
                return JsonSerializer.Deserialize<TResult>(jsonStr)!;
            }
        }


        public void Remove(string cacheKey)
        {
            distCache.Remove(cacheKey);
        }

        public Task RemoveAsync(string cacheKey)
        {
            return distCache.RemoveAsync(cacheKey);
        }
    }
}

分布式缓存\IDistributedCacheHelper.cs

using Microsoft.Extensions.Caching.Distributed;
using System;
using System.Threading.Tasks;

namespace Zack.ASPNETCore
{
    public interface IDistributedCacheHelper
    {
        TResult? GetOrCreate<TResult>(string cacheKey, Func<DistributedCacheEntryOptions, TResult?> valueFactory, int expireSeconds = 60);

        Task<TResult?> GetOrCreateAsync<TResult>(string cacheKey, Func<DistributedCacheEntryOptions, Task<TResult?>> valueFactory, int expireSeconds = 60);

        void Remove(string cacheKey);
        Task RemoveAsync(string cacheKey);
    }
}

分布式缓存\Program.cs

using Zack.ASPNETCore;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "localhost:6379";
    options.InstanceName = "pre_";
});
builder.Services.AddScoped<IDistributedCacheHelper, DistributedCacheHelper>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();


分布式缓存\分布式缓存.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.0" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
  </ItemGroup>

</Project>

分布式缓存\Controllers\Test1Controller.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Zack.ASPNETCore;

namespace 分布式缓存.Controllers
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class Test1Controller : ControllerBase
    {
		private readonly IDistributedCache distCache;
		private readonly IDistributedCacheHelper helper;
        public Test1Controller(IDistributedCache distCache, IDistributedCacheHelper helper)
        {
            this.distCache = distCache;
            this.helper = helper;
        }
        [HttpGet]
		public string Now()
		{
			string s = distCache.GetString("Now");
			if (s == null)
			{
				s = DateTime.Now.ToString();
				var opt = new DistributedCacheEntryOptions();
				opt.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(180);
				distCache.SetString("Now", s, opt);
			}
			return s;
		}

		[HttpGet]
		public Task<string?> Now2()
        {
			return helper.GetOrCreateAsync<string>("Now2", async e => DateTime.Now.ToString());
        }

	}
}

标签:缓存,string,distCache,redis,cacheKey,dotnet,using,options
From: https://www.cnblogs.com/zhuoss/p/18014634

相关文章

  • 力扣链表 哈希表 之 146. LRU 缓存
    请你设计并实现一个满足 LRU(最近最少使用)缓存约束的数据结构。实现LRUCache类:LRUCache(intcapacity)以正整数作为容量 capacity初始化LRU缓存intget(intkey)如果关键字key存在于缓存中,则返回关键字的值,否则返回-1。voidput(intkey,intvalue) ......
  • springboot整合redis报错:链接失败;org.springframework.data.redis.RedisConnectionFai
    错误原因:开启了保护模式解决方案:关闭保护模式和防火墙具体步骤:1、打开你的redis配置文件,做出如下修改2.开启进程守护yes代表开启守护进程模式。在该模式下,redis会在后台运行,并将进程pid号写入至redis.conf选项pidfile设置的文件中,此时redis将一直运行,除非手动kill该进程。3.......
  • Mac电脑安装RedisCluster集群(非Docker模式)
    第1步,新建redis.confredis.conf内容如下:port7021cluster-enabledyes              //启用集群模式cluster-config-filenodes.conf     //集群的配置文件cluster-node-timeout5000appendonlyyesdaemonizeyesbind0.0.0.0   ......
  • dotnet_sqlite_sqlhelper_数据库连接_数据库依赖注入
    DI魅力渐显_依赖注入\Program.csservices.AddScoped<IDbConnection>(sp=>{stringconnStr="DataSource=test.db";varconn=newSqliteConnection(connStr);conn.Open();returnconn;});DI魅力渐显_依赖注入\UserDAO.csprivatereadonly......
  • 7.读写配置文件和添加缓存
    感觉没什么好总结的,直接上代码吧:配置文件:1添加一个枚举///<summary>///配置键名///</summary>publicenumConfigKey{///<summary>///系统配置///</summary>SystemConfig,///<summary>......
  • dotnet logAddConsole方法
    AddConsole方法//Summary://Addsaconsoleloggernamed'Console'tothefactory.////Parameters://builder://TheMicrosoft.Extensions.Logging.ILoggingBuildertouse.[UnconditionalSuppressMessage("ReflectionAnalysis",&......
  • dotnet 接口的扩展方法 logger
    AddLogging的使用services.AddLogging(logBuilder=>{logBuilder.AddConsole();});AddLogging的实现publicstaticIServiceCollectionAddLogging(thisIServiceCollectionservices,Action<ILoggingBuilder>configure){//...}实现ILoggingBuilder的AddCo......
  • dotnet 依赖注入 注入方式
    依赖注入的基本使用1/Program.csusingMicrosoft.Extensions.DependencyInjection;ServiceCollectionservices=newServiceCollection();//AddTransient的两种方式//services.AddTransient<ITestService,TestServiceImpl>();//services.AddTransient(typeof(ITestSer......
  • dotnet 依赖注入 服务定位器
    依赖注入的基本使用1/Program.csusingMicrosoft.Extensions.DependencyInjection;ServiceCollectionservices=newServiceCollection();//瞬态服务services.AddTransient<TestServiceImpl>();//=>false//作用域服务//services.AddScoped<TestServiceImpl>();......
  • SpringBoot 报错无法连接到Redis (Unable to connect to Redis)
    UnabletoconnecttoRedisSpringBoot3.1.2报错:UnabletoconnecttoRedis背景在搭建项目开发环境的时候,进行Redis相关的单元测试时发现无法连接到远程的Redis服务器。并且报错UnabletoconnecttoRedisRedis所在服务器UbuntuService64位20.04.06问题排查:检查基......