Almacenamiento en caché de respuestas en ASP.NET Core
Por John Luo, Rick Andersony Steve Smith
Vea o descargue el código de ejemplo (cómo descargarlo)
El almacenamiento en caché de respuestas reduce el número de solicitudes que un cliente o proxy realiza a un servidor web. El almacenamiento en caché de respuestas también reduce la cantidad de trabajo que realiza el servidor web para generar una respuesta. El almacenamiento en caché de respuestas se controla mediante encabezados que especifican cómo desea que el cliente, el proxy y el middleware almacenarán en caché las respuestas.
El atributo ResponseCache participa en la configuración de encabezados de almacenamiento en caché de respuestas. Los clientes y los servidores proxy intermedios deben respetar los encabezados para almacenar en caché las respuestas en la especificación de almacenamiento en caché HTTP 1.1.
Para el almacenamiento en caché del lado servidor que sigue la especificación de almacenamiento en caché HTTP 1.1, use middleware de almacenamiento en caché de respuesta. El middleware puede usar las propiedades para influir en el comportamiento del almacenamiento ResponseCacheAttribute en caché del lado servidor.
Almacenamiento en caché de respuestas basado en HTTP
La especificación de almacenamiento en caché HTTP 1.1 describe cómo deben comportarse las cachés de Internet. El encabezado HTTP principal que se usa para almacenar en caché es Cache-Control, que se usa para especificar directivas de caché. Las directivas controlan el comportamiento del almacenamiento en caché a medida que las solicitudes se hacen camino de los clientes a los servidores y a medida que las respuestas se hacen camino de los servidores a los clientes. Las solicitudes y respuestas se mueven a través de servidores proxy, y los servidores proxy también deben cumplir la especificación de almacenamiento en caché HTTP 1.1.
Las Cache-Control directivas comunes se muestran en la tabla siguiente.
| Directiva | Acción |
|---|---|
| pública | Una caché puede almacenar la respuesta. |
| private | La respuesta no debe almacenarse en una memoria caché compartida. Una caché privada puede almacenar y reutilizar la respuesta. |
| max-age | El cliente no acepta una respuesta cuya antigüedad sea mayor que el número de segundos especificado. Ejemplos: max-age=60 (60 segundos), max-age=2592000 (1 mes) |
| no-cache | En las solicitudes: una caché no debe usar una respuesta almacenada para satisfacer la solicitud. El servidor de origen vuelve a generar la respuesta para el cliente y el middleware actualiza la respuesta almacenada en su caché. En respuestas: la respuesta no debe usarse para una solicitud posterior sin validación en el servidor de origen. |
| no-store | En las solicitudes: una caché no debe almacenar la solicitud. En respuestas: una memoria caché no debe almacenar ninguna parte de la respuesta. |
En la tabla siguiente se muestran otros encabezados de caché que desempeñan un papel en el almacenamiento en caché.
| Encabezado | Función |
|---|---|
| Age | Una estimación de la cantidad de tiempo en segundos desde que la respuesta se generó o validó correctamente en el servidor de origen. |
| Expira | Hora después de la cual la respuesta se considera obsoleta. |
| Pragma | Existe para la compatibilidad con versiones anteriores con cachés HTTP/1.0 para establecer el no-cache comportamiento. Si el Cache-Control encabezado está presente, Pragma se omite el encabezado. |
| Variar | Especifica que no se debe enviar una respuesta almacenada en caché a menos que todos los campos de encabezado coincidan tanto en la solicitud original de la respuesta almacenada en caché como Vary en la nueva solicitud. |
El almacenamiento en caché basado en HTTP respeta las directivas Cache-Control solicitudes
La especificación de almacenamiento en caché HTTP 1.1 para el encabezado Cache-Control requiere una memoria caché para respetar un encabezado válido enviado Cache-Control por el cliente. Un cliente puede realizar solicitudes con un valor de encabezado y forzar al no-cache servidor a generar una nueva respuesta para cada solicitud.
Respetar siempre los encabezados de solicitud de cliente tiene sentido si se tiene en cuenta Cache-Control el objetivo del almacenamiento en caché HTTP. Según la especificación oficial, el almacenamiento en caché está pensado para reducir la latencia y la sobrecarga de red de satisfacer las solicitudes en una red de clientes, servidores proxy y servidores. No es necesariamente una manera de controlar la carga en un servidor de origen.
No hay ningún control del desarrollador sobre este comportamiento de almacenamiento en caché cuando se usa el middleware de almacenamiento en caché de respuesta porque el middleware se adhiere a la especificación de almacenamiento en caché oficial. La compatibilidad con el almacenamiento en caché de salida para controlar mejor la carga del servidor es una propuesta de diseño para una futura versión de ASP.NET Core. Para obtener más información, vea Agregar compatibilidad con el almacenamiento en caché de salida (dotnet/aspnetcore #27387).
Otra tecnología de almacenamiento en caché en ASP.NET Core
Almacenamiento en caché en memoria
El almacenamiento en caché en memoria usa la memoria del servidor para almacenar los datos almacenados en caché. Este tipo de almacenamiento en caché es adecuado para un único servidor o varios servidores que usan sesiones permanentes. Las sesiones permanentes significan que las solicitudes de un cliente siempre se enruta al mismo servidor para su procesamiento.
Para más información, consulte Caché en memoria en ASP.NET Core.
Caché distribuida
Use una caché distribuida para almacenar datos en memoria cuando la aplicación se hospeda en una granja de servidores o en la nube. La memoria caché se comparte entre los servidores que procesan las solicitudes. Un cliente puede enviar una solicitud que controla cualquier servidor del grupo si los datos almacenados en caché del cliente están disponibles. ASP.NET Core funciona con cachés distribuidas SQL Server, Redisy NCache.
Para más información, consulte Almacenamiento en caché distribuido en ASP.NET Core.
Asistente de etiquetas de caché
Almacenar en caché el contenido de una vista mvc o Razor una página con el asistente de etiquetas de caché. El asistente de etiquetas de caché usa el almacenamiento en caché en memoria para almacenar datos.
Para más información, consulte Asistente de etiquetas de caché en ASP.NET Core MVC.
Asistente de etiquetas de caché distribuida
Almacenar en caché el contenido desde una vista mvc o una página en escenarios de nube distribuida o granja de servidores Razor web con el asistente de etiquetas de caché distribuida. El asistente de etiquetas de caché distribuida usa SQL Server, Rediso NCache para almacenar datos.
Para más información, consulte Asistente de etiquetas de caché distribuida en ASP.NET Core.
Atributo ResponseCache
especifica ResponseCacheAttribute los parámetros necesarios para establecer los encabezados adecuados en el almacenamiento en caché de respuestas.
Advertencia
Deshabilite el almacenamiento en caché para el contenido que contiene información para los clientes autenticados. El almacenamiento en caché solo debe habilitarse para contenido que no cambie en función de la identidad de un usuario o de si un usuario ha iniciado sesión.
VaryByQueryKeys varía la respuesta almacenada por los valores de la lista dada de claves de consulta. Cuando se proporciona un valor único de , el middleware varía las respuestas según todos los parámetros de cadena de * consulta de solicitud.
El middleware de almacenamiento en caché de respuestas debe estar habilitado para establecer la propiedad VaryByQueryKeys . De lo contrario, se produce una excepción en tiempo de ejecución. No hay un encabezado HTTP correspondiente para la VaryByQueryKeys propiedad . La propiedad es una característica HTTP que controla el middleware de almacenamiento en caché de respuestas. Para que el middleware sirva una respuesta almacenada en caché, la cadena de consulta y el valor de la cadena de consulta deben coincidir con una solicitud anterior. Por ejemplo, considere la secuencia de solicitudes y resultados que se muestra en la tabla siguiente.
| Solicitud | Resultado |
|---|---|
http://example.com?key1=value1 |
Devuelto desde el servidor. |
http://example.com?key1=value1 |
Se devuelve desde middleware. |
http://example.com?key1=value2 |
Devuelto desde el servidor. |
El servidor devuelve la primera solicitud y se almacena en caché en middleware. El middleware devuelve la segunda solicitud porque la cadena de consulta coincide con la solicitud anterior. La tercera solicitud no está en la caché de middleware porque el valor de la cadena de consulta no coincide con una solicitud anterior.
se ResponseCacheAttribute usa para configurar y crear (a través de ) un IFilterFactory Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter . realiza el trabajo de actualizar los encabezados HTTP adecuados ResponseCacheFilter y las características de la respuesta. El filtro:
- Quita los encabezados existentes
VaryparaCache-Control, yPragma. - Escribe los encabezados adecuados en función de las propiedades establecidas en ResponseCacheAttribute .
- Actualiza la característica HTTP de almacenamiento en caché de VaryByQueryKeys respuestas si está establecida.
Variar
Este encabezado solo se escribe cuando se VaryByHeader establece la propiedad . Propiedad establecida en el Vary valor de la propiedad. En el ejemplo siguiente se usa la VaryByHeader propiedad :
[ResponseCache(VaryByHeader = "User-Agent", Duration = 30)]
public class Cache1Model : PageModel
{
Con la aplicación de ejemplo, vea los encabezados de respuesta con las herramientas de red del explorador. Los siguientes encabezados de respuesta se envían con la respuesta de la página Cache1:
Cache-Control: public,max-age=30
Vary: User-Agent
NoStore y Location.None
NoStore invalida la mayoría de las demás propiedades. Cuando esta propiedad se establece en true , el encabezado se establece en Cache-Control no-store . Si Location se establece en None :
- El valor de
Cache-Controlestá establecido enno-store,no-cache. - El valor de
Pragmaestá establecido enno-cache.
Si NoStore es y es , y se establecen en false Location None Cache-Control Pragma no-cache .
NoStore normalmente se establece en para true las páginas de error. La página Cache2 de la aplicación de ejemplo genera encabezados de respuesta que indica al cliente que no almacene la respuesta.
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class Cache2Model : PageModel
{
La aplicación de ejemplo devuelve la página Cache2 con los encabezados siguientes:
Cache-Control: no-store,no-cache
Pragma: no-cache
Ubicación y duración
Para habilitar el almacenamiento en caché, debe establecerse en un valor positivo y debe Duration Location ser Any (el valor predeterminado) o Client . El marco establece el Cache-Control encabezado en el valor de ubicación seguido de de la max-age respuesta.
LocationLas opciones de y Any se Client traducen en Cache-Control valores de encabezado de y , public private respectivamente. Como se indicó en la sección NoStore y Location.None, establecer Location en establece los None Cache-Control Pragma encabezados y en no-cache .
Location.Any( establecido en ) indica que el cliente o cualquier proxy intermedio puede almacenar en caché el valor, incluido el Cache-Control middleware de almacenamiento en caché de public respuesta.
Location.Client ( Cache-Control establecido en ) indica que solo el cliente private puede almacenar en caché el valor. Ninguna caché intermedia debe almacenar en caché el valor, incluido el middleware de almacenamiento en caché de respuesta.
Los encabezados de control de caché simplemente proporcionan instrucciones a los clientes y a los servidores proxy intermedios cuando y cómo almacenar en caché las respuestas. No hay ninguna garantía de que los clientes y servidores proxy respetarán la especificación de almacenamiento en caché HTTP 1.1. El middleware de almacenamiento en caché de respuestas siempre sigue las reglas de almacenamiento en caché establecidas por la especificación .
En el ejemplo siguiente se muestra el modelo de página Cache3 de la aplicación de ejemplo y los encabezados generados al establecer Duration y dejar el valor Location predeterminado:
[ResponseCache(Duration = 10, Location = ResponseCacheLocation.Any, NoStore = false)]
public class Cache3Model : PageModel
{
La aplicación de ejemplo devuelve la página Cache3 con el siguiente encabezado:
Cache-Control: public,max-age=10
Perfiles de caché
En lugar de duplicar la configuración de caché de respuestas en muchos atributos de acción de controlador, los perfiles de caché se pueden configurar como opciones al configurar Razor MVC/Pages en Startup.ConfigureServices . Los valores encontrados en un perfil de caché al que se hace referencia se usan como valores predeterminados por y se reemplazan por cualquier ResponseCacheAttribute propiedad especificada en el atributo .
Configure un perfil de caché. En el ejemplo siguiente se muestra un perfil de caché de 30 segundos en la aplicación de ejemplo Startup.ConfigureServices :
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddMvc(options =>
{
options.CacheProfiles.Add("Default30",
new CacheProfile()
{
Duration = 30
});
});
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.CacheProfiles.Add("Default30",
new CacheProfile()
{
Duration = 30
});
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
El modelo de página Cache4 de la aplicación de ejemplo hace referencia al perfil Default30 de caché:
[ResponseCache(CacheProfileName = "Default30")]
public class Cache4Model : PageModel
{
se ResponseCacheAttribute puede aplicar a:
- Razor Páginas: los atributos no se pueden aplicar a los métodos de controlador.
- Controladores MVC.
- Métodos de acción de MVC: los atributos de nivel de método invalidan la configuración especificada en los atributos de nivel de clase.
Encabezado resultante aplicado a la respuesta de la página Cache4 por el perfil Default30 de caché:
Cache-Control: public,max-age=30
Recursos adicionales
- Almacenamiento de respuestas en cachés
- Cache-Control
- Caché en memoria en ASP.NET Core
- Almacenamiento en caché distribuido en ASP.NET Core
- Detección de cambios con tokens de cambio en ASP.NET Core
- Middleware de almacenamiento en caché de respuestas en ASP.NET Core
- Asistente de etiquetas de caché en ASP.NET Core MVC
- Asistente de etiquetas de caché distribuida en ASP.NET Core