前言:上篇文章介绍了.net core+Redis+IIS+nginx实现Session共享,本来打算直接说明后续填坑过程,但毕竟好多坑是用docker部署后出现的,原计划简单提一下.net core+Redis+docker实现Session共享,但是发现篇幅也不小,所以还是单独起草一篇,除了k8s部署docker,其它部分都有基本介绍。

1、环境准备

操作系统:Windows10

VS2019、本地Redis数据库、Windows docker

2、背景介绍

由于项目从asp.net MVC向.net core webapi迁移,一方面是技术方面的迁移,另一方面是从业务方面切割,向微服务模式转型,项目最后完成部署的结构大致如下:

总体上说,大家各自的项目有各自的部署方式,一旦做成分布式的,实现Session共享往往就不可避免了。

3、.net core+Redis+docker实现Session共享

如果你的项目是用IIS或其它方式部署,那么这部分你可以直接跳过了,因为代码部分跟上篇文章是一样的。无非是使用windows docker 命令进行部署。

(1)用VS2019新建一个Web Api项目(RedisSessionTest)

在Startup.cs文件中添加以下代码  

public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false; //这里要改为false,默认是true,true的时候session无效
options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.None;
}); services.AddDataProtection(configure =>
{
configure.ApplicationDiscriminator = "commonweb1";
})
.SetApplicationName("commonweb1")
.AddKeyManagementOptions(options =>
{
//配置自定义XmlRepository
options.XmlRepository = new SessionShare();
}); //services.AddSession();
#region 使用Redis保存Session
// 这里取连接字符串
services.AddDistributedRedisCache(option =>
{
//redis 连接字符串
option.Configuration = "";
//redis 实例名
option.InstanceName = "Test_Session";
}); //添加session 设置过期时长分钟
//var sessionOutTime = con.ConnectionConfig.ConnectionRedis.SessionTimeOut;
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromSeconds(Convert.ToDouble(3 * 60 * 60)); //session活期时间
options.Cookie.HttpOnly = true;//设为httponly
});
#endregion services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
} public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSession();
app.UseMiddleware<RequestMiddleware>();
app.UseCookiePolicy();
app.UseMvc();
}

  

为什么这么加请参考上篇文章,这里我只做一个简单的介绍:

services.Configure<CookiePolicyOptions>:配置可以读取cookie信息。

app.UseCookiePolicy():表示使用ConfigureServices中配置cookie策略

services.AddDataProtection:配置应用程序名称,自定义MachineKey,用于不同站点服务可以读取同一Session。

services.AddDistributedRedisCache:将Session保存到Redis数据库。

services.AddSession:配置Sesion策略。

app.UseMiddleware<RequestMiddleware>():使用自定义中间件。

(2)添加自定义中间件RequestMiddleware

public class RequestMiddleware
{
private readonly RequestDelegate _next; public RequestMiddleware(RequestDelegate next)
{
this._next = next;
} public Task Invoke(HttpContext context)
{
context.Request.EnableRewind(); //支持context.Request.Body重复读取,内部调用了EnableBuffering方法,否则在使用部分方法或属性时会报错误System.NotSupportedException: Specified method is not supported,例如context.Request.Body.Position
if (context.Request.ContentLength == null)
{
return this._next(context);
} string sessionPhone = context.Session.GetString("phone");
if (string.IsNullOrEmpty(sessionPhone))
{
context.Session.SetString("phone", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
}
return this._next(context);
}
}

  在中间件中保存当前时间到Session中。

(3)在ValuesController中添加测试接口

[HttpPost]
public string PostTest(dynamic @param)
{
string phone = HttpContext.Session.GetString("phone");
return JsonConvert.SerializeObject(@param) + phone;
}

  为了方便我把路由从api/[Controller]改成了[action]:

(4)添加dockerfile文件如下(如果用别的方式部署,后续步骤可直接跳过,如果想了解windows docker的安装和部署,可以点击;如果想深入了解docker,这里我也帮不了多少,自己还在进一步学习中):

(5)使用docker命令(windows版)部署测试项目

打开cmd命令,cd定位到项目路径

生成镜像(最后面的.不能去掉): docker build -f /Redis使用测试/RedisSessionTest/RedisSessionTest/Dockerfile -t testcore .

映射容器端口:docker run --name testweb -p 7001:80 -d testcore

利用fiddler模拟请求,调用步骤3中创建的PostTest接口,验证是否部署成功:

点击composer->输入接口地址->设置contentype头信息->添加参数为{"qqq":147},最后得到结果是: {"qqq":147}2020-01-13 09:16:58

特别留意下这个cookie信息,它将作为另外一个站点下,同http://xxxx:7001/PostTest接口共享Session的接口的请求头信息。

可以发现Session缓存的时间是2020-01-13 09:16:58,这里注意一下,docker容器所在linux系统中的时间比windows当前时间早了8个小时,也就是说我实际做测试的时间是2020-01-13 17:16:58,如果要解决这个问题,在dockerfile文件中加入时区设置:

#设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

(6)重复上面几个步骤,新增一个新的web api项目(RedisSessionTestNew)

在第(3)步的时候,将新增项目的接口action改为PostTestNew,用于区别RedisSessionTest项目,即代码如下:

[HttpPost]
public string PostTestNew(dynamic @param)
{
string phone = HttpContext.Session.GetString("phone");
return JsonConvert.SerializeObject(@param) + phone;
}

  

在第(5)步的时候,将新的项目映射为7002端口,我的测试项目部署如下:

生成镜像(最后面的.不能去掉): docker build -f /Redis使用测试/RedisSessionTest/RedisSessionTestNew/Dockerfile -t testnewcore .

映射容器端口:docker run --name testnewweb -p 7002:80 -d testnewcore

接下来再使用fiddler去调用7002站点下的PostTestNew接口,注意带上7001PostTest测试结果中的cookie信息,参数为{"qqq":258},结果如下:{"qqq":258}2020-01-13 09:16:58

4、分析测试结果

这里对比下两次请求结果:

http://XXXX:7001/PostTest:{"qqq":147}2020-01-13 09:16:58

http://XXXX:7002/PostTestNew:{"qqq":258}2020-01-13 09:16:58

7002/PostTestNew的结果中输出的请求参数值发生了变化,但是从Session中读取到的时间是7001/PostTest设置的Session值,而且访问Redis数据库,确实只保存了一个Session值,说明实现了Session共享。

最后尤其要注意,这里采用了cookie值作为id寻找Session值的方式,所以项目中需要保存第一次缓存Session产生的cookie值,在后面http请求的头中带上该cookie值;若是session值发生了变化,则将新的cookie值覆盖到原来的cookie值。

.Net Core Web Api实践(三).net core+Redis+docker实现Session共享的更多相关文章

  1. .Net Core Web Api实践之中间件的使用(一)

    前言:从2019年年中入坑.net core已半年有余,总体上来说虽然感觉坑多,但是用起来还是比较香的.本来我是不怎么喜欢写这类实践分享或填坑记录的博客的,因为初步实践坑多,文章肯定也会有各种错误,跟 ...

  2. .Net Core Web Api实践(二).net core+Redis+IIS+nginx实现Session共享

    前言:虽说公司app后端使用的是.net core+Redis+docker+k8s部署的,但是微信公众号后端使用的是IIS部署的,虽说公众号并发量不大,但领导还是使用了负载均衡,所以在介绍docke ...

  3. .Net Core Web Api实践(四)填坑连接Redis时Timeout performing EVAL

    前言:前两篇文章.net core+Redis+IIS+nginx实现Session共享中,介绍了使用Microsoft.Extensions.Caching.Redis实现Session共享的方法, ...

  4. ASP.NET Core Web API 索引 (更新Identity Server 4 视频教程)

    GraphQL 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(上) 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(下) [视频] 使用ASP.NET C ...

  5. ASP.NET Core Web API

    1.简单介绍 ASP.NET Core Web API 是 ASP.NET Core MVC 的一个功能.ASP.NET Core MVC 包含了对 Web API 的支持.可以构建多种客户端的 HT ...

  6. .net core web api + Autofac + EFCore 个人实践

    1.背景 去年时候,写过一篇<Vue2.0 + Element-UI + WebAPI实践:简易个人记账系统>,采用Asp.net Web API + Element-UI.当时主要是为了 ...

  7. C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志

    C#实现多级子目录Zip压缩解压实例 参考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重点: 实现多级子目录的压缩, ...

  8. 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入

    使用react全家桶制作博客后台管理系统   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...

  9. 重温.NET下Assembly的加载过程 ASP.NET Core Web API下事件驱动型架构的实现(三):基于RabbitMQ的事件总线

    重温.NET下Assembly的加载过程   最近在工作中牵涉到了.NET下的一个古老的问题:Assembly的加载过程.虽然网上有很多文章介绍这部分内容,很多文章也是很久以前就已经出现了,但阅读之后 ...

随机推荐

  1. H3C LMI

  2. 立足GitHub学编程:13个不容错过的Java项目

    立足GitHub学编程:13个不容错过的Java项目 今天我们将整理一大波干货满满的Java示例代码与能力展示素材. GitHub可谓一座程序开发的大宝库,有些素材值得fork,有些则能帮助我们改进自 ...

  3. SpringData Jpa、Hibernate、Jpa 三者之间的关系

    JPA规范与ORM框架之间的关系是怎样的呢? JPA规范本质上就是一种ORM规范,注意不是ORM框架--因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服 ...

  4. 一次操作系统报错OutOfMemory Error的处理记录

    在启动公司内嵌的tomcat容器时出现报错, 如下: # There is insufficient memory for the Java Runtime Environment to contin ...

  5. win10 uwp 手把手教你使用 asp dotnet core 做 cs 程序

    本文是一个非常简单的博客,让大家知道如何使用 asp dot net core 做后台,使用 UWP 或 WPF 等做前台. 本文因为没有什么业务,也不想做管理系统,所以看到起来是很简单. Visua ...

  6. linux清理函数

    每个非试验性的模块也要求有一个清理函数, 它注销接口, 在模块被去除之前返回所有资 源给系统. 这个函数定义为: static void   exit cleanup_function(void) { ...

  7. ASP.NET MVC 实现页落网资源分享网站+充值管理+后台管理(15)之前台网站页面

    源码下载地址:http://www.yealuo.com/Sccnn/Detail?KeyValue=c891ffae-7441-4afb-9a75-c5fe000e3d1c 本项目主要是一个素材的分 ...

  8. vue 父组件中调用子组件函数

    2019/06/06 在父组件中调用子组件的方法:  1.给子组件定义一个ref属性.eg:ref="childItem"  2.在子组件的methods中声明一个函数.eg: u ...

  9. HBuilder如何与真机连接

    之前因为前端这边要做测试, 同时兼容ios和安卓方面. 但是因为一直苦恼无法仿真机连接测试,从而每次测试提出来一次,修改一次. 为了解决这个弊端,所以自己在这里分享一下连接的方法: 一:Android ...

  10. C#使用SmtpClient发送邮件解决授权码配置问题

    授权码,(新版邮箱在开启smtp权限设置时,会生成授权码)如果不做配置,客户端是不能发送邮件的 //指定邮箱账号和密码,需要注意的是,这个密码是你在QQ邮箱设置里开启服务的时候给你的那个授权码 Smt ...