Easy-DotNET Easy-DotNET
🏠首页
  • 知识地图
  • 源码脑图

    • 总览
    • Program
    • WebApplication
    • Host主机
    • WebHost主机
    • 依赖注入
    • Autofac
    • Middleware中间件
    • RateLimiter限制速率
    • 响应缓存、请求解压缩
  • 设计初衷
  • 克隆
  • 类型转换
  • 日期时间
  • IO流
  • 工具类
  • 语言特性
  • 集合类
  • Codec编码
  • 文本操作
  • 数学
  • 图片
  • 网络
  • Emoji表情
  • C# 12
  • C# 11
  • C# 10
  • C# 9.0
  • C# 8.0
  • C# 早期版本
  • C# 教程
  • ORM
  • 定时任务
  • 日志
  • 认证与授权
  • Swagger
  • 对象映射
  • 熔断重试限流
  • 缓存
  • 注册发现
  • 网关
  • GraphQL
  • 更多
  • Docker

    • 简介
    • Adminer
    • Apisix
    • Apollo
    • Cassandra
    • Cerebro
    • ClickHouse
    • Consul
    • EasyMock
    • Elasticsearch
    • Emqx
    • FastDFS
    • Flink
    • Gitlab
    • Jenkins
    • Jrebel
    • MariaDB
    • MySQL
    • Percona
    • Phpmyadmin
    • PostgreSQL
    • Redis
  • Linux

    • 查看Linux系统信息
    • CentOS7调整磁盘分区
    • IO压测
    • 图形化监控工具Cockpit
  • 总览
  • 列表

    • 算法数据结构
    • API
    • 应用框架
    • 应用模板
    • 操作系统
    • 工作流
    • 入门套件
    • 示例
    • 人工智能
    • 程序集
    • Assets
    • 认证授权
    • Blazor
    • 区块链
    • 书籍
    • 自动构建
    • 报表
    • 缓存
    • 日历
    • 聊天
    • CLI
    • CLR
    • CMS
    • 代码分析和指标
    • 代码片段
    • 压缩
    • 持续集成
    • 密码学
    • 数据库
    • 数据库驱动
    • 日期时间
    • 反编译
    • 部署
    • DirectX
    • 分布式计算
    • DLR
    • 文档
    • 电商支付
    • 模拟器
    • 环境管理
    • ETL
    • 事件消息
    • Exception
    • 扩展
    • 函数式编程
    • 游戏引擎
    • GIS
    • Git工具
    • 绘图
    • GraphQL
    • GUI
    • HTML-CSS
    • HTTP
    • IDE
    • 图片处理
    • 安装工具
    • 交互式编程
    • 国际化
    • 互操作性
    • IoC
    • JS引擎
    • 日志
    • 机器学习和数据科学
    • Markdown
    • 邮件
    • 数学
    • 媒体
    • 指标
    • 微型框架
    • 最小化器
    • MVVM
    • 网络
    • 对象映射
    • Office
    • OpenAI
    • ORM
    • 包管理器
    • PDF
    • 性能分析工具
    • 协议
    • 推送通知
    • SQL构建器
    • 消息队列
    • RPC
    • 响应式编程
    • 实时通信
    • 正则表达式
    • 任务调度
    • SDK和API
    • 搜索引擎
    • 序列化
    • SMS
    • 状态机
    • 静态站点生成
    • 强命名
    • 风格指南
    • 模板引擎
    • 测试
    • 工具
    • 交易
    • UI自动测试
    • Visual Studio 插件
    • Web浏览器
    • Web框架
    • WebServers
    • WebSocket
    • Windows服务
    • WPF
    • 解析器
    • 源码生成
    • 其他
    • 资源
  • AspNetCore面试题
  • Elasticsearch面试题
  • MongoDB面试题
  • MySql面试题
  • Nginx面试题
  • RabbitMQ面试题
  • Redis面试题
  • 设计模式
  • 微服务
🧑‍💻.NET Blog
GitHub (opens new window)
🏠首页
  • 知识地图
  • 源码脑图

    • 总览
    • Program
    • WebApplication
    • Host主机
    • WebHost主机
    • 依赖注入
    • Autofac
    • Middleware中间件
    • RateLimiter限制速率
    • 响应缓存、请求解压缩
  • 设计初衷
  • 克隆
  • 类型转换
  • 日期时间
  • IO流
  • 工具类
  • 语言特性
  • 集合类
  • Codec编码
  • 文本操作
  • 数学
  • 图片
  • 网络
  • Emoji表情
  • C# 12
  • C# 11
  • C# 10
  • C# 9.0
  • C# 8.0
  • C# 早期版本
  • C# 教程
  • ORM
  • 定时任务
  • 日志
  • 认证与授权
  • Swagger
  • 对象映射
  • 熔断重试限流
  • 缓存
  • 注册发现
  • 网关
  • GraphQL
  • 更多
  • Docker

    • 简介
    • Adminer
    • Apisix
    • Apollo
    • Cassandra
    • Cerebro
    • ClickHouse
    • Consul
    • EasyMock
    • Elasticsearch
    • Emqx
    • FastDFS
    • Flink
    • Gitlab
    • Jenkins
    • Jrebel
    • MariaDB
    • MySQL
    • Percona
    • Phpmyadmin
    • PostgreSQL
    • Redis
  • Linux

    • 查看Linux系统信息
    • CentOS7调整磁盘分区
    • IO压测
    • 图形化监控工具Cockpit
  • 总览
  • 列表

    • 算法数据结构
    • API
    • 应用框架
    • 应用模板
    • 操作系统
    • 工作流
    • 入门套件
    • 示例
    • 人工智能
    • 程序集
    • Assets
    • 认证授权
    • Blazor
    • 区块链
    • 书籍
    • 自动构建
    • 报表
    • 缓存
    • 日历
    • 聊天
    • CLI
    • CLR
    • CMS
    • 代码分析和指标
    • 代码片段
    • 压缩
    • 持续集成
    • 密码学
    • 数据库
    • 数据库驱动
    • 日期时间
    • 反编译
    • 部署
    • DirectX
    • 分布式计算
    • DLR
    • 文档
    • 电商支付
    • 模拟器
    • 环境管理
    • ETL
    • 事件消息
    • Exception
    • 扩展
    • 函数式编程
    • 游戏引擎
    • GIS
    • Git工具
    • 绘图
    • GraphQL
    • GUI
    • HTML-CSS
    • HTTP
    • IDE
    • 图片处理
    • 安装工具
    • 交互式编程
    • 国际化
    • 互操作性
    • IoC
    • JS引擎
    • 日志
    • 机器学习和数据科学
    • Markdown
    • 邮件
    • 数学
    • 媒体
    • 指标
    • 微型框架
    • 最小化器
    • MVVM
    • 网络
    • 对象映射
    • Office
    • OpenAI
    • ORM
    • 包管理器
    • PDF
    • 性能分析工具
    • 协议
    • 推送通知
    • SQL构建器
    • 消息队列
    • RPC
    • 响应式编程
    • 实时通信
    • 正则表达式
    • 任务调度
    • SDK和API
    • 搜索引擎
    • 序列化
    • SMS
    • 状态机
    • 静态站点生成
    • 强命名
    • 风格指南
    • 模板引擎
    • 测试
    • 工具
    • 交易
    • UI自动测试
    • Visual Studio 插件
    • Web浏览器
    • Web框架
    • WebServers
    • WebSocket
    • Windows服务
    • WPF
    • 解析器
    • 源码生成
    • 其他
    • 资源
  • AspNetCore面试题
  • Elasticsearch面试题
  • MongoDB面试题
  • MySql面试题
  • Nginx面试题
  • RabbitMQ面试题
  • Redis面试题
  • 设计模式
  • 微服务
🧑‍💻.NET Blog
GitHub (opens new window)
npm
  • 简介
  • ORM

    • EFCore
    • Dapper
    • FreeSql
    • SqlSugar
  • 任务调度

    • Hangfire
    • Quartz
    • FluentScheduler
    • Coravel
    • Quartzmin
  • 日志

    • Serilog
    • NLog
    • Log4Net
    • Stackdriver
    • ExceptionLess
  • 身份认证与授权

    • IdentityServer4
    • Identity
    • JWTBearer
    • Auth0
    • OpenIddict
  • Swagger文档

    • Swagger
    • Swashbuckle
    • NSwag
    • ReDoc
  • 对象映射

    • AutoMapper
    • EmitMapper
    • AgileMapper
    • Mapster
  • 消息传递

    • MediatR
    • MassTransit
    • Rebus
    • NServiceBus
  • 熔断重试限流

    • Polly
    • Resilience4j
    • AkkaNET
  • 缓存

    • CsRedis
    • FreeRedis
    • EasyCaching
    • StackExchangeRedis
    • CacheCow
      • 安装CacheCow
      • CacheCow的工作原理
      • 使用CacheCow
        • 配置CacheCow
        • 设置缓存控制标头
        • 缓存键
        • 缓存存储
        • 缓存控制标头
        • Cache-Control
        • ETag
        • Last-Modified
        • Vary
        • 高级用法
        • 自定义缓存策略
        • 缓存拦截器
      • 结论
    • NCache
    • Memory
  • 注册发现

    • Consul
    • Nacos
    • Apollo
  • 网关

    • Ocelot
    • Kong
    • Traefik
    • Zuul
  • GraphQL

    • GraphQLPlatform
    • GraphQLdotnet
  • 更多

    • NodaTime
    • FluentAssertions
    • Humanizer
    • 爬虫-AngleSharp
    • 邮件-MailKit
  • NET微服务
  • 缓存
一个大西瓜
2023-04-25
目录

CacheCow

开源地址

Github:https://github.com/StackExchange/StackExchange.Redis (opens new window)

CacheCow是一个.NET库,用于帮助应用程序轻松地利用HTTP缓存。它提供了一个HTTP缓存管理器,它可以与Web API一起使用,并可以通过自定义存储提供程序存储缓存。CacheCow支持HTTP协议中的所有缓存控制标头,并提供了一个易于使用的API来控制缓存行为。

# 安装CacheCow

可以通过NuGet包管理器或手动安装CacheCow。

使用NuGet包管理器:


Install-Package CacheCow.Server

# CacheCow的工作原理

当客户端请求资源时,服务器可以选择将资源缓存到本地,以便将来请求时可以直接使用缓存的版本。这不仅可以减少服务器负载,还可以加快响应时间,并在网络不稳定时提高应用程序的稳定性。当客户端请求缓存资源时,服务器可以直接响应缓存的版本,而无需再次计算或检索资源。

CacheCow管理HTTP缓存,它通过使用缓存控制标头来告诉客户端如何缓存响应,并在未来的请求中使用缓存的响应。当客户端请求缓存的资源时,CacheCow将检查缓存中是否存在响应,并在需要时返回缓存的响应。如果缓存中不存在响应,则CacheCow将在服务器上重新计算响应,并将其存储在缓存中以供将来使用。

# 使用CacheCow

# 配置CacheCow

要在应用程序中使用CacheCow,必须先在应用程序中配置它。在Web API应用程序中,可以在WebApiConfig.cs文件中配置CacheCow:


public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // 配置缓存
        var cacheHandler = new CachingHandler(config);
        config.MessageHandlers.Insert(0, cacheHandler);

        // 其他配置
        ...
    }
}

上面的代码创建了一个CachingHandler对象,并将其添加到Web API管道的消息处理程序列表中。这使得CacheCow可以拦截来自客户端的请求,并根据缓存控制标头处理它们。

# 设置缓存控制标头

要启用缓存控制,需要设置响应中的缓存控制标头。可以在Web API控制器中的操作方法中使用CacheControlHeaderValue类来设置标头。例如,以下代码将max-age设置为10秒:


[HttpGet]
public HttpResponseMessage Get()
{
    var response = Request.CreateResponse(HttpStatusCode.OK, "Hello World!");
    response.Headers.CacheControl = new CacheControlHeaderValue
    {
        Public = true,
        MaxAge = TimeSpan.FromSeconds(10)
    };
    return response;
}

此代码告诉客户端可以将响应缓存10秒,并在10秒内重用响应。

# 缓存键

当缓存响应时,CacheCow使用缓存键来标识响应。默认情况下,CacheCow使用请求的URI作为缓存键。如果您需要使用不同的缓存键,则可以使用ICacheKeyGenerator接口实现自定义缓存键生成器。

例如,以下代码将X-Api-Version标头的值作为缓存键:

public class ApiVersionCacheKeyGenerator : ICacheKeyGenerator
{
    public string Generate(HttpRequestMessage request)
    {
        var version = request.Headers.GetValues("X-Api-Version").FirstOrDefault();
        if (version == null)
        {
            return request.RequestUri.ToString();
        }
        else
        {
            return $"{request.RequestUri}#{version}";
        }
    }
}

上面的代码创建了一个ApiVersionCacheKeyGenerator类,并将其实现为ICacheKeyGenerator接口。该类将使用X-Api-Version标头的值作为缓存键,并在标头不存在时使用请求URI作为缓存键。

要使用此缓存键生成器,请在配置中注册它:


public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // 配置缓存
        var cacheHandler = new CachingHandler(config)
        {
            CacheKeyGenerator = new ApiVersionCacheKeyGenerator()
        };
        config.MessageHandlers.Insert(0, cacheHandler);

        // 其他配置
        ...
    }
}

# 缓存存储

CacheCow使用ICacheStore接口来存储缓存。默认情况下,CacheCow使用内存缓存存储缓存。但是,您可以通过实现ICacheStore接口来使用自定义缓存存储。

例如,以下代码创建了一个使用Redis作为缓存存储的RedisCacheStore类:


public class RedisCacheStore : ICacheStore
{
    private readonly IDatabase _redis;

    public RedisCacheStore()
    {
        var redis = ConnectionMultiplexer.Connect("localhost");
        _redis = redis.GetDatabase();
    }

    public bool TryGet(string key, out HttpResponseMessage response)
    {
        var value = _redis.StringGet(key);
        if (value.HasValue)
        {
            response = JsonConvert.DeserializeObject<HttpResponseMessage>(value);
            return true;
        }
        else
        {
            response = null;
            return false;
        }
    }

    public void AddOrUpdate(string key, HttpResponseMessage response, TimeSpan expirationTime)
    {
        var value = JsonConvert.SerializeObject(response);
        _redis.StringSet(key, value, expirationTime);
    }
}

上面的代码创建了一个RedisCacheStore类,并将其实现为ICacheStore接口。该类使用Redis作为缓存存储,并使用Json序列化HttpResponseMessage对象来存储响应。

要使用此缓存存储,请在配置中注册它:


public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // 配置缓存
        var cacheHandler = new CachingHandler(config)
        {
            CacheStore = new RedisCacheStore()
        };
        config.MessageHandlers.Insert(0, cacheHandler);

        // 其他配置
    }
}

# 缓存控制标头

CacheCow支持HTTP协议中的所有缓存控制标头,包括Cache-Control、ETag、Last-Modified和Vary。您可以使用以下方法之一来设置缓存控制标头:

# Cache-Control

Cache-Control标头用于控制客户端和代理如何缓存响应。可以使用以下属性设置Cache-Control标头:

  • Public - 指示响应可以被任何缓存存储和重用。
  • Private - 指示响应只能被单个用户缓存。
  • NoCache - 指示客户端和代理不应将响应缓存,但可以将响应存储在缓存中。
  • NoStore - 指示客户端和代理不应将响应存储在缓存中。
  • MaxAge - 指示响应可以被缓存的最长时间。
  • SharedMaxAge - 指示响应可以被所有共享缓存存储和重用的最长时间。
  • NoTransform - 指示代理不应修改响应的实体主体。
  • MustRevalidate - 指示客户端和代理必须验证缓存中的响应的状态,并在响应过期时重新获取响应。
  • ProxyRevalidate - 指示代理必须验证缓存中的响应的状态,并在响应过期时重新获取响应。

例如,以下代码设置了Cache-Control标头:

response.Headers.CacheControl = new CacheControlHeaderValue
{
    Public = true,
    MaxAge = TimeSpan.FromSeconds(60)
};

上面的代码将响应标记为可以由任何缓存存储和重用,并将其缓存60秒。

# ETag

ETag标头用于标识响应的实体标识符。客户端和代理可以使用此标头来验证缓存的响应是否仍然有效。可以使用以下方法设置ETag标头:


response.Headers.ETag = new EntityTagHeaderValue("\"123456\"");

上面的代码将响应标记为具有实体标识符为"123456"的实体。

# Last-Modified

Last-Modified标头用于指示响应的最后修改日期和时间。客户端和代理可以使用此标头来验证缓存的响应是否仍然有效。可以使用以下方法设置Last-Modified标头:


response.Content.Headers.LastModified = DateTimeOffset.UtcNow;

上面的代码将响应的最后修改日期和时间设置为当前UTC时间。

# Vary

Vary标头用于指示响应是否根据不同的请求头返回不同的响应。例如,如果响应根据Accept-Encoding标头返回不同的内容,则应在响应中包含Vary: Accept-Encoding标头。可以使用以下方法设置Vary标头:


response.Headers.Vary.Add("Accept-Encoding");

上面的代码将响应标记为根据Accept-Encoding标头返回不同的响应。

# 高级用法

除了基本用法之外,CacheCow还提供了一些高级用法。

# 自定义缓存策略

默认情况下,CacheCow使用以下规则来决定是否从缓存中返回响应:

  1. 如果请求包含Cache-Control: no-cache标头,则不从缓存中返回响应。
  2. 如果请求包含Cache-Control: no-store标头,则不缓存响应。
  3. 如果响应包含Cache-Control: no-store标头,则不从缓存中返回响应。
  4. 如果响应包含Cache-Control: no-cache标头,则不从缓存中返回响应,并且缓存的响应被标记为过期。
  5. 如果响应包含Cache-Control: must-revalidate标头,则在过期时验证缓存中的响应。
  6. 如果响应包含ETag标头,则客户端可以使用If-None-Match标头验证缓存中的响应是否仍然有效。
  7. 如果响应包含Last-Modified标头,则客户端可以使用If-Modified-Since标头验证缓存中的响应是否仍然有效。

您可以使用ICacheValidationPolicy接口来自定义缓存策略。例如,以下代码创建了一个将响应标记为永久缓存的缓存策略:


public class PermanentCacheValidationPolicy : ICacheValidationPolicy
{
    public CacheValidationResult Validate(HttpRequestMessage request, HttpResponseMessage response)
    {
        return new CacheValidationResult(true, null, TimeSpan.MaxValue);
    }
}

上面的代码创建了一个PermanentCacheValidationPolicy类,并将其实现为ICacheValidationPolicy接口。该类将所有响应标记为永久缓存,并在缓存过期时重新获取响应。

要使用此缓存策略,请在配置中注册它:


public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // 配置缓存
        var cacheHandler = new CachingHandler(config)
        {
            CacheValidationPolicy = new PermanentCacheValidationPolicy()
        };
        config.MessageHandlers.Insert(0, cacheHandler);

        // 其他配置
        ...
    }
}

# 缓存拦截器

CacheCow提供了一个ICacheInterceptor接口,您可以使用它来在缓存请求之前或之后执行自定义操作。例如,您可以使用缓存拦截器记录缓存命中率或在缓存命中时向响应中添加标头。以下是一个将缓存命中率记录到日志中的示例缓存拦截器:


public class LoggingCacheInterceptor : ICacheInterceptor
{
    private readonly ILogger _logger;

    public LoggingCacheInterceptor(ILogger logger)
    {
        _logger = logger;
    }

    public void OnCacheHit(HttpRequestMessage request, HttpResponseMessage response)
    {
        _logger.LogInformation($"Cache hit for {request.RequestUri}");
    }

    public void OnCacheMiss(HttpRequestMessage request)
    {
        _logger.LogInformation($"Cache miss for {request.RequestUri}");
    }

    public void OnStore(HttpRequestMessage request, HttpResponseMessage response)
    {
        // do nothing
    }
}

上面的代码创建了一个LoggingCacheInterceptor类,并将其实现为ICacheInterceptor接口。该类在缓存命中时记录日志,并在缓存未命中时记录日志。

要使用此缓存拦截器,请在配置中注册它:


public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // 配置缓存
        var cacheHandler = new CachingHandler(config)
        {
            CacheInterceptor = new LoggingCacheInterceptor(LoggerFactory.Create(builder => builder.AddConsole()))
        };
        config.MessageHandlers.Insert(0, cacheHandler);

        // 其他配置
        ...
    }
}

上面的代码将LoggingCacheInterceptor作为缓存拦截器注册到CacheCow中,并使用ASP.NET Core日志记录框架记录日志。

# 结论

HTTP缓存是提高Web应用程序性能的关键技术之一。CacheCow是一个.NET库,可以轻松地管理HTTP缓存,并为开发人员提供了一个易于使用的API来控制缓存行为。通过使用CacheCow,您可以减少服务器负载,加快响应时间,并提高应用程序的稳定性。

上次更新: 2023/04/26, 22:10:06
StackExchangeRedis
NCache

← StackExchangeRedis NCache→

Theme by Vdoing | Copyright © 2019-2024 一个大西瓜 | MIT License | 苏ICP备2023013501号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式