- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
Web项目中很多网页资源比如html、js、css通常会做服务器端的缓存,加快网页的加载速度 。
一些周期性变化的API数据也可以做缓存,例如广告资源位数据,菜单数据,商品类目数据,商品详情数据,商品列表数据,公共配置数据等,这样就可以省去很多在服务端手动实现缓存的操作 。
最早资源缓存大部分都用Expires、Cache-Control或Etag实现的,我们可以在WebServer中统一设置响应头,或者指定规则单独设置 。
以上都是基于Http协议的缓存,如今很多WebServer,例如Nginx和阿里二次开发的Tengine,都是自己的一套缓存实现,通过独有的响应头参数(X-Accel-Expires)来识别控制缓存,优先级是大于Http协议那些的 。
通常Nginx都是作为代理服务器,反向代理多台源服务器,如果开启了缓存,二次请求到了Nginx就会直接响应给客户端了,能减轻源服务器的压力 。
本文主要是基于 X-Accel-Expires 来实现缓存的,前提是在Nginx中已经配置了Proxy Cache规则 。
。
1. 这是资源访问路径,通过Nginx反向代理多个源服务器,Nginx中配置了缓存,第二次访问到了Nginx就直接返回了,不会再到后面的源服务器 。
2. 常见的Http缓存响应头设置有以下几种,其中Etag和Last-Modified是组合使用的,X-Accel-Expires是Nginx独有的参数,优先级高于其他几个设置,值的单位是秒,0为不生效 。
Nginx缓存识别优先级如下 。
3. Nginx实现缓存的原理是把Url和相关参数,通过自定义组合作为Key,并使用MD5算法对Key进行哈希,把响应结果存到硬盘上的对应目录,支持通过命令清除缓存 。
具体可以参考以下文章,非常详细:
https://www.nginx.com/blog/nginx-high-performance-caching/ 。
https://czerasz.com/2015/03/30/nginx-caching-tutorial/ 。
。
以下是通过过滤器实现控制该参数,支持在Controller或Action上传入滑动时间,或者固定时间,灵活控制缓存时间 。
/// <summary>
/// 配合nginx缓存
/// </summary>
[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Method,AllowMultiple = false)]
public class NginxCacheFilterAttribute : Attribute, IAsyncActionFilter
{
/// <summary>
/// 构造函数
/// </summary>
public NginxCacheFilterAttribute() { }
/// <summary>
/// 固定时间格式正则,例如:00:00 、10:30
/// <summary>
static Regex reg = new Regex(@"^(\d{1,2}):(\d{1,2})$",RegexOptions.IgnoreCase);
/// <summary>
/// 缓存清除固定时间,new string[] { "00:00", "10:00", "14:00", "15:00" }
/// </summary>
public string[] MustCleanTimes { get; set; }
/// <summary>
/// 缓存清除滑动时间,默认 300 (5分钟)
/// </summary>
public int Period { get; set; } = 300;
/// <summary>
/// 请求头变量
/// </summary>
const string X_Accel_Expires = "X-Accel-Expires";
const string ETag = "ETag";
const string Cache_Control = "Cache-Control";
/// <summary>
/// 过滤器执行
/// </summary>
/// <param name="context"></param>
/// <param name="next"></param>
/// <returns></returns>
public Task OnActionExecutionAsync(ActionExecutingContext context,ActionExecutionDelegate next)
{
//非GET请求,不设置nginx缓存头
if (context.HttpContext.Request.Method.ToUpper() != "GET") {
return next.Invoke();
}
var response = context.HttpContext.Response;
//判断固定时间
if (MustCleanTimes != null && MustCleanTimes.Length > 0) {
var nowTime = DateTime.Now; //当前时间
var nowYmd = nowTime.ToString("yyyy-MM-dd"); //当前日期
List<DateTime> cleanTimes = new List<DateTime>();
foreach (var time in MustCleanTimes) {
if (reg.IsMatch(time) && DateTime.TryParse($"{nowYmd} {time}",out DateTime _date)) {
//已超时的推到第二天,例如设置的是00:00,刷新时间就应该是第二天的00:00
if (_date < nowTime)
cleanTimes.Add(_date.AddDays(1));
else
cleanTimes.Add(_date);
}
}
if (cleanTimes.Count > 0) {
var nextTime = cleanTimes.OrderBy(o => o).FirstOrDefault(); //下次刷新时间
var leftSeconds = nextTime.Subtract(nowTime).TotalSeconds; //下次刷新剩余秒数
if (leftSeconds >= 0 && leftSeconds < Period)
Period = (int)leftSeconds;
}
}
//添加X_Accel_Expires
if (response.Headers.ContainsKey(X_Accel_Expires)) {
response.Headers.Remove(X_Accel_Expires);
}
response.Headers.Add(X_Accel_Expires,Period.ToString());
//添加ETag
if (response.Headers.ContainsKey(ETag)) {
response.Headers.Remove(ETag);
}
response.Headers.Add(ETag,new System.Net.Http.Headers.EntityTagHeaderValue($"\"{DateTime.Now.Ticks.ToString()}\"",true).ToString());
//移除Cache-Control
response.Headers.Remove(Cache_Control);
return next.Invoke();
}
}
具体的使用方式如下:
1. 全局用法,全局Api都是设置的默认缓存时间,不需要缓存的Api在Controller或Action上单独设置Period=0即可 。
//在Stratup中全局添加过滤器
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(config => {
config.Filters.Add<NginxCacheFilterAttribute>();
});
}
/// <summary>
/// 设置滑动时间
/// Period=0为不生效
/// </summary>
/// <returns></returns>
[HttpGet]
[NginxCacheFilter(Period = 0)]
public HttpResponseMessage TestCache1()
{
return new HttpResponseMessage() { StatusCode = System.Net.HttpStatusCode.OK };
}
2. 局部用法 。
/// <summary>
/// 设置滑动时间
/// 30秒后自动过期
/// </summary>
/// <returns></returns>
[HttpGet]
[NginxCacheFilter(Period = 30)]
public HttpResponseMessage TestCache1()
{
return new HttpResponseMessage() { StatusCode = System.Net.HttpStatusCode.OK };
}
/// <summary>
/// 设置固定时间
/// 例如:9点第一次请求,一直缓存到10点失效,12点第一次请求,一直缓存到15点失效
/// </summary>
/// <returns></returns>
[HttpGet]
[NginxCacheFilter(MustCleanTimes = new[] { "10:00","15:00","22:00" })]
public HttpResponseMessage TestCache2()
{
return new HttpResponseMessage() { StatusCode = System.Net.HttpStatusCode.OK };
}
。
1. 我们第一次请求接口,返回200状态码,Nginx在响应头上会返回X-Cache:MISS,代表缓存未命中 。
2. 第二次请求,会返回304状态码,Nginx在响应头上会返回 X-Cache:HIT,代表已经命中缓存 。
3. 我们开启Chrome调试中的Disable Cache,这样所有请求的请求头中都会设置 Cache-Control: no-cache,再刷新下接口看下 。
发现接口返回200状态码,Nginx在响应头上会返回X-Cache:EXPIRED,说明缓存已过期,已从源服务器返回了数据,也说明通过请求头设置Cache-Control为no cache是可以跳过缓存的 。
更多含义:
。
proxy_cache_lock: 缓存锁 。
proxy_cache_lock_timeout: 缓存锁过期时间 。
如果给缓存规则设置了 proxy_cache_lock ,那么该规则下同时进来多个同一个Key的请求,只会有一个请求被转发到后面的源服务器,其余请求会被等待,直到源服务器的内容被成功缓存 。
可以配合设置 proxy_cache_lock_timeout ,设置一个缓存锁的过期时间,这样其余请求如果等待超时了,也会被释放请求到后面的源服务器 。
通过这两个参数的组合使用,可以有效避免同一个请求大量打入时,瞬间压垮后面的源服务器 。
。
原创作者:Harry 。
原文出处:https://www.cnblogs.com/simendancer/articles/17109964.html 。
最后此篇关于Asp.NetCore中利用过滤器控制Nginx的缓存时间的文章就讲到这里了,如果你想了解更多关于Asp.NetCore中利用过滤器控制Nginx的缓存时间的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
在一个新的 ASP.NET Core RC2 类库中,我有以下 project.json 文件,我试图在其中遵循 How to trim your package dependencies 上的文档.
我在本地提要上将 nuget 包从 2.2.x 更新到 3.1.0。 然后,在构建机器上尝试构建项目,但是: Project.csproj(0,0): Error NU1102: Unable to
什么是Kafka Apache Kafka是一个分布式流处理平台,由LinkedIn开发并开源,后来成为Apache软件基金会的顶级项目。Kafka主要用于构建实时数据管道和流式应用程序。
快递100的物流信息查询接口,官方提供了一些demo;还好官方提供的代码是.netcore版本写的,不过写的有点low;根据官方提供的代码,我按照.netcore 的风格重构了代码;核心代码如下:
1、docker介绍 docker是用go语言编写基于linux操作系统的一些特性开发的,其提供了操作系统级别的抽象,是一种容器管理技术,它隔离了应用程序对基础架构(操作系统等)的依赖。相较于虚
demo运行在windows的docker中,系统是win10,所以需要先下载docker for windows,安装完毕后系统会重启,然后桌面上可以找到docker for windows的快捷
NetCore WebSocket 即时通讯示例,供大家参考,具体内容如下 1.新建Netcore Web项目 2.创建简易通讯协议 ?
.NET Core:架构、特性和优势详解 在软件开发领域,保持领先地位至关重要。随着技术以指数级的速度发展,开发人员不断寻求高效、可扩展且多功能的解决方案来应对现代挑战。.NET Core 就是这样
需求场景: 我需要部署的项目是在Windows上开发的,目标框架为.net core 6.0 因此我们需要先在kylin上部署项目运行所需要的环境。 借助百
我正在 .NET Core 中重写一个调用外部 Web 服务的控制台应用程序。 我目前收到以下错误: One or more errors occurred. (The HTTP request is
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 6 年前。 Improve th
我有一组库,我想将其从 PCL 转移到 netcore。通过此举,我想简化 DI 系统并更新一些内部工作方式。 我想添加的其中一件事是内部对象的配置,就像在 Asp.Net Core 中一样(即 se
注:本文隶属于《理解ASP.NET Core》系列文章,请查看置顶博客或 点击此处查看全文目录 概述 在微服务化的架构设计中,网关扮演着重要的看门人角色,它所提供的功能之一
对于有多个应用系统的企业来说,每一个应用系统都有自己的用户体系,这就造成用户在切换不同应用系统时,就要多次输入账号密码,导致体验非常不好,也造成使用上非常不便。 针对这个问题,我们就可以采用单
就像 Web Api 接口可以对入参进行验证,避免用户传入非法的或者不符合我们预期的参数一样,选项也可以对配置源的内容进行验证,避免配置中的值与选项类中的属性不对应或者不满足预期,毕竟大部分配置
.NET Core 选项系统的主要实现在 Microsoft.Extensions.Options 和 Microsoft.Extensions.Options.ConfigurationExten
漏洞说明: 跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击
分布式缓存是由多个应用服务器共享的缓存,通常作为访问它的应用服务器的外部服务进行维护。 分布式缓存可以提高 ASP.NET Core 应用的性能和可伸缩性,尤其是当应用由云服务或服务器场托管时。
一个应用要运行起来,往往需要读取很多的预设好的配置信息,根据约定好的信息或方式执行一定的行为。 配置的本质就是软件运行的参数,在一个软件实现中需要的参数非常多,如果我们以 Hard Code(
2. 配置添加 配置系统可以读取到配置文件中的信息,那必然有某个地方可以将配置文件添加到配置系统中。之前的文章中讲到 ASP.NET Core 入口文件中,builder(WebApplica
我是一名优秀的程序员,十分优秀!