.Net Redis实战——使用Redis构建Web应用
示例介绍
示例1:借助Redis实现购物车功能
示例2:Redis实现网页缓存和数据缓存
借助Redis实现购物车功能
每个用户的购物车都是一个散列,散列存储了商品ID与商品订购数量之间的映射。订购商品时,对购物车进行更新:如果用户订购某件商品的数量大于0,那么将这件商品的ID以及用户订购该商品的数量添加到散列里面,如果用户购买的商品已经存在散列里面,那么新的订购数量会覆盖已有的订购数量;相反,如果用户订购某件商品数量不大于0,那么程序将从散列里面移除该条目。
由于整个示例分Controller和WebApi两部分,在不考虑封装Redis操作的情况下提取Redis连接字符串到appSetting.json中
"ConnectionStrings": {
"Redis": "localhost,abortConnect=false"
},
保存用户购物查数据示例代码:
[HttpGet("UpdateCart")]
public string UpdateCart(string token,string item,int count)
{
var key = $"cart:{token}";
using (var redis = ConnectionMultiplexer.Connect(redisConnectionStr))
{
var db = redis.GetDatabase();
//更新购物车数据
if (count <= 0)
{
db.HashDeleteAsync(key, item);
}
else
{
db.HashSetAsync(key, item,count);
}
}
return "更新购物车成功";
}
Redis实现网页缓存和数据缓存
针对不会频繁更新得动态网页或Ajax返回的数据可以缓存在Redis中,减少与数据库的交互提升系统效应效率。
该示例只是为了演示借助Reids实现页面缓存和数据缓存效果,实际使用中可通过ResponseCache特性实现缓存。
详细介绍:https://docs.microsoft.com/en-us/aspnet/core/performance/caching/response?view=aspnetcore-5.0
网页数据缓存
新建示例项目时为WebApi项目,修改Startup类添加Web Mvc支持。
ConfigureServices方法中修改services.AddControllers()为services.AddControllersWithViews()。
Configure方法中app.UseEndpoints修改为如下代码
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
定义中间件类RedisCacheMiddleware,用来缓存网页页面
public class RedisCacheMiddleware
{ private readonly RequestDelegate _next; public IConfiguration Configuration { get; } public RedisCacheMiddleware(RequestDelegate next, IConfiguration configuration)
{
_next = next;
Configuration = configuration;
} public async Task InvokeAsync(HttpContext context)
{ var path = context.Request.Path.Value.ToLower(); if (path == "/home" || path == "/home/index")
{ var responseContent = ""; //Copy a pointer to the original response body stream
var originalBodyStream = context.Response.Body; using (var redis = ConnectionMultiplexer.Connect(Configuration.GetConnectionString("Redis")))
{
var db = redis.GetDatabase();
if (db.KeyExists(path))
{
responseContent = db.StringGet(path);
await RespondWithIndexHtml(context.Response, responseContent);
return;
}
else
{
using (var responseBody = new MemoryStream())
{
//...and use that for the temporary response body
context.Response.Body = responseBody; //Continue down the Middleware pipeline, eventually returning to this class
await _next(context); //Format the response from the server
responseContent = await FormatResponse(context.Response); //Copy the contents of the new memory stream (which contains the response) to the original stream, which is then returned to the client.
await responseBody.CopyToAsync(originalBodyStream);
} db.StringSet(path, responseContent, expiry: TimeSpan.FromSeconds(30));
}
} } // Call the next delegate/middleware in the pipeline
await _next(context);
} private async Task RespondWithIndexHtml(HttpResponse response,string html)
{
response.StatusCode = 200;
response.ContentType = "text/html"; await response.WriteAsync(html, Encoding.UTF8);
} private async Task<string> FormatResponse(HttpResponse response)
{
//We need to read the response stream from the beginning...
response.Body.Seek(0, SeekOrigin.Begin); //...and copy it into a string
string text = await new StreamReader(response.Body).ReadToEndAsync(); //We need to reset the reader for the response so that the client can read it.
response.Body.Seek(0, SeekOrigin.Begin); //Return the string for the response
return text;
} }
添加中间件调用
app.UseMiddleware<RedisCacheMiddleware>();
运行效果如图:

网页上的时间会每30秒更新一次。
.Net Core提供的响应缓存中间件:https://docs.microsoft.com/zh-cn/aspnet/core/performance/caching/middleware?view=aspnetcore-5.0
Ajax数据缓存
本例只是简单的数据存储,实际使用中可编写单独的服务,让这个服务将指定的数据缓存到Redis里面,并不定期地对这些缓存进行更新。
示例代码
[HttpGet("GetDateTime")]
public string GetDateTime()
{
var dateTime = "";
var key = "data:datetime";
using (var redis = ConnectionMultiplexer.Connect(redisConnectionStr))
{
var db = redis.GetDatabase();
if (db.KeyExists(key))
{
dateTime = db.StringGet(key);
}
else
{
dateTime = DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss");
db.StringSet(key, dateTime,expiry:TimeSpan.FromSeconds(5));
}
}
return dateTime;
}
参考资料
Using Middleware in .NET 5.0 to Log Requests and Responses
Swashbuckle.AspNetCore.ReDoc/ReDocMiddleware.cs
.Net Redis实战——使用Redis构建Web应用的更多相关文章
- Redis实战之Redis + Jedis
用Memcached,对于缓存对象大小有要求,单个对象不得大于1MB,且不支持复杂的数据类型,譬如SET 等.基于这些限制,有必要考虑Redis! 相关链接: Redis实战 Redis实战之Redi ...
- Redis实战之Redis + Jedis[转]
http://blog.csdn.net/it_man/article/details/9730605 2013-08-03 11:01 1786人阅读 评论(0) 收藏 举报 目录(?)[-] ...
- Redis实战:如何构建类微博的亿级社交平台
微博及 Twitter 这两大社交平台都重度依赖 Redis 来承载海量用户访问.本文介绍如何使用 Redis 来设计一个社交系统,以及如何扩展 Redis 让其能够承载上亿用户的访问规模. 虽然单台 ...
- 实战案例--Grunt构建Web程序
GruntJS构建Web程序.使用Gruntjs来搭建一个前端项目,然后使用grunt合并,压缩JS文件,熟练了node.js安装和grunt.js安装后,接下来来实战一个案例,案例是根据snandy ...
- Redis实战总结-Redis的高可用性
在之前的博客<Redis实战总结-配置.持久化.复制>给出了一种Redis主从复制机制,简单地实现了Redis高可用.然后,如果Master服务器宕机,会导致整个Redis瘫痪,这种方式的 ...
- Redis 实战 —— 05. Redis 其他命令简介
发布与订阅 P52 Redis 实现了发布与订阅(publish/subscribe)模式,又称 pub/sub 模式(与设计模式中的观察者模式类似).订阅者负责订阅频道,发送者负责向频道发送二进制字 ...
- Redis 实战 —— 14. Redis 的 Lua 脚本编程
简介 Redis 从 2.6 版本开始引入使用 Lua 编程语言进行的服务器端脚本编程功能,这个功能可以让用户直接在 Redis 内部执行各种操作,从而达到简化代码并提高性能的作用. P248 在不编 ...
- 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)
本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...
- 分布式缓存技术redis系列(五)——redis实战(redis与spring整合,分布式锁实现)
本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...
随机推荐
- c协程库libco几点体会
https://www.cnblogs.com/dearplain/p/9820913.html 这里说的是Tencent开源的libco. libco的用途和依赖 主要还是c/c++服务端,相比li ...
- 「编程羽录」上线,程序员必备的这些技能你能get到嘛?
大家好,我是小羽. 好久不见,给大家带来个好消息,小羽的全新专题「编程羽录」系列正式上新,主要是介绍一些关于面试题和经验总结的文章. 会为大家提供一些技术栈之外,程序员还需要的其他方面硬核知识,做到全 ...
- hdu1337 水题
题意: 给你n个格子,每个格子初始状态都是1,然后这样变化1 2 3...n,2 4 6 ... n, 3 6 9 ....n ,...n;如果是1变成0,如果是0变成1,问经过n次变换之 ...
- hdu 1298 字典树 + DFS (模拟T9文本输入)
题意: 给你一些按键顺序,让你输出每一步中概率最大的那个单词,这里的概率计算方 法好好看看别弄错了,一开始就是因为弄错了,各种wa,比如 abc 1 ,ab 1,那么 ab 的概率就是2 ...
- POJ2983 查分约束系统
题意: 给你n个点,然后给你两种情况,P a b c,表明a在b的北边c那么远,V a b 表明a在b的北边(距离最少是1),问你这些条件是否冲突. 思路: 一开始想用带权并 ...
- POJ1178枚举三个地方(所有点都去同一个点)
题意: 有一个国王和很多骑士,他们都要到某一个点去集合,然后问所有人都到达某个终点的距离和最小是多少?过程中如果国王遇到了一个骑士的话,国王就可以和骑士一起按照骑士的走法走,这是两个人算一 ...
- Linux-鸟菜-6-文件与目录管理
Linux-鸟菜-6-文件与目录管理 这章主要是说一些对目录和文件的增删改查等等命令. . 代表当前目录 .. 代表前一个目录 / 的 . 和 .. 一样 - 代表前一个工作目录 ...
- [CTF]思维导向图
[CTF]思维导向图 ---------------来自大佬的CTF思维导向图 Angel_Kitty https://www.cnblogs.com/ECJTUACM-873284962/ 给信息安 ...
- Day003 变量、常量、作用域
变量 变量:就是可以变化的量 Java是一种强类型语言,每个变量都必须声明其类型. Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域 变量的定义 数据类型 变量名 = 值:可以 ...
- 【maven和jdk】报错:系统找不到指定的文件
创建一个maven项目出错 问题描述 在idea.log出现如下错误(系统找不到指定的文件,但是不知道指定文件是什么) com.intellij.execution.process.ProcessNo ...