详解Session分布式共享(.NETCORE版)
⼀、前⾔&回顾
在上篇⽂章中,好多同学留⾔问了我好多问题,其中印象深刻的有:nginx挂了怎么办?采⽤Redis的Session⽅案与微软Session⽅案相⽐,有什么优势呢?Cookie也可以取代Session的,采⽤Redis的Session⽅案优势在哪⾥?Nginx的iphash⽅式到底是什么?MachineKey有啥⽤?Net Core怎样实现?
那会⼉看到⼤家的提问,我的回答也只是从应⽤层⾯回答,基本上的回答可以总结为:“别⼈这么做了,解决了这个问题,我⽤这个⽅法也解决了这个问题,原理请看链接。”很惭愧的说,那时的我并没有完全理解他真正的优势在哪⾥,只是凭着直觉和经验知道这样做⽐较好,知道当⼀部分东西不可控时候,将其解耦、可视化、集就可以让⼀个系统更加健壮,但没有⼀个理论⽀撑。经过最近⼀段时间的查阅资料和阅读书籍,对此有了深刻理解,本⽂将从⽹站架构的可⽤性⾓度对这种Session共享进⾏分析和讲解,并⽤ core再次实现这种架构模式。(Session分布式共享的net core版,因为⼯作没有机会应⽤到⽣产环境,过往经验就更别提了,所以只是研究性的,请⼤家注意,但园⼦⾥早有⼤⽜写出了相关⽂章,本⽂结束会将相关⽂章贴出)
⼆、⽹站可⽤性--Session管理
可⽤性是⽹站架构中⾮常重要的⼀环,什么是可⽤性,说的简单些,就是⽤户随时随地打开这个⽹站,这个⽹站都能打开,并且⾥⾯的功能都能⽤。如果可⽤性不⾼会出现什么情况?⼤家想象⼀下春节在12306抢票的情景,⽹站各种崩溃,⼤家保准会想:要是有别的⽅式能买到票,我才不⽤12306这个破⽹站呢。这个例⼦有点极端,因为业务场景⽐较极端,当然,这种现象也不光是⽹站可⽤性这⼀环出了问题。但是⼀个⽹站三天两头打不开,要么是点开了⾥⾯的页⾯到处是报错页⾯和操作⽆反应,你还会⽤这个⽹站么?我相信我们在浏览⽹站时候,只要不像12306这种垄断业务的⽹站,出现不可⽤的情况,我们⼀定会离开寻其他类似的⽹站。
Session管理是⽹站可⽤性的内容之⼀,⼤家都知道Http是⽆状态请求,即⽆法追踪上次Http请求的相关信息,但是业务中⼤量需要将Http变为有状态请求,Session就随之产⽣了,可是在分布式⽹站设计中,⽆状态请求才能实现⽹站的横向拓展(增减应⽤服务器),因此⼜与Session相⽭盾,因为Session信息如果存储在⽹站应⽤服务器的缓存中,加台服务器就不能⽤了,因此将Session解耦是解决此问题的关键,下⾯介绍⽹站常见的Session管理⼿段。
1、Session复制
Session复制是最早企业应⽤系统使⽤较多的⼀种服务集Session管理机制,开启Session复制功能,即是在集中的⼏台服务器之间同步Session对象,Java中好像JBoss有这个功能,.Net暂不知道。
优势:Session信息读取快,实现简单。
缺点:集规模较⼤时,服务器之间Session复制会占⽤服务器资源和⽹络资源,最后系统会不堪重负。
2、Session绑定
Session绑定的⽅式,⼀般软/硬均衡负载服务器都会提供此功能,例如:上篇⽂章Nginx的IPhash⽅式,均衡负载服务器利⽤Hash算法将同⼀IP分配到同⼀台服务器上,即Session绑定在某台特定服务器上,保证Session总能在这台服务器上获得,⼜称作为会话黏滞。
缺点:如果某台服务器宕机,那么这台服务器上⾯的Session也就不存在了,⽤户请求切换到其他服务器上因为没有Session⽽出错。
3、利⽤Cookie记录Session
通过Cookie记录Session信息是⼤部分⽹站采⽤的⽅法,这种⽅式只要Cookie不滥⽤,也是⾮常好⾮常成熟的⽅案。Cookie记录Session就是把⼀些状态信息放到了客户端,每次请求都要传输到服务器。
优势:这种⽅法简单易实现,可⽤性⾼,⽀持服务器横向拓展,⽅案成熟
缺点:安全性问题,Cookie有⼤⼩限制,⽽且每次请求传输Cookie会影响性能
4、Session服务器
Session服务器的⽅式管理Session,是⼀种⾮常好的解决⽅案,因为Session是为了业务需要Http状态⽽产⽣,⽽分布式⽹站设计中提倡Http⽆状态,为了满⾜这⼀设计,Session服务器是将有状态的Session信息与⽆状态的应⽤服务器相分离,再针对不同服务器的不同特性进⾏设计。例如:我们将Session信息存⼊到Redis中,那么Redis的集配置、稳定性设置都有很多好的解决⽅案,如果将Session存⼊到Memcache,那么Memcache的集配置、稳定性设置也会有很多成熟案例。这样我们就将⼀些问题简单化,如果我们单独应⽤.Net的Session,我们需要了解更多.Net深层次的东西并加以改造来保证其可⽤和稳定,越深层的东西越需要时间和阅历,⽽如果将Session存储介质转移到Redis中,Redis集⽅案、管理⼯具都⾮常成熟,只需要配置配置就解决了Session 的问题,何乐⽽不为呢。
优势:可⽤性⾼、安全性⾼、伸缩性好、性能⾼、信息⼤⼩⽆限制
三、.Net Core+Redis+Nginx实现Session分布式共享
1、前期准备&环境
(1)Vs2017    (2).Net Core 1.1  (3) Win 7  (4)ubuntu 16.04
2、.Net Core简介
随着互联⽹的发展,在当今中国市场(外国不⼤清楚)开源、跨平台是衡量⼀门语⾔、技术好坏的重要指标之⼀,微软为了推动.Net开源及跨平台,.Net Core随之诞⽣。
详见⼤⽜的⽂章:
下⾯说说.Net Core给我的初步的感受:
1).Net Core并没有颠覆之前C#语法
通俗讲就是之前说中国话(C#),现在还是说中国话,只是说话的环境变了。
2).Net Core因为刚起步,API变了或者少了很多
通俗讲就是说话环境变了,⽽且⾥⾯有好多你没见过的东西,你不知道⽤什么官⽅词语来描述,因为官⽅正在相关词来描述这些新东西。
3)脱离IIS,跨平台
通俗讲就是微软⽼妈为了不让我们到了新环境饿着,怕离开现在这个环境(Windows+IIS)之后不知道怎么⽣存。于是,教会了我们语⾔(C#),给了我们挣钱的⼯具(.Net Core+Kestrel),说了⼀句“去吧孩⼦,⾃⼰奋⽃去吧,稍等,别忘了把这张Visa卡带上(.Net Core SDK),我会定期给你打钱的。”
4)NuGet越来越重要
NuGet经过⼏年的发展,越来越成熟,.Net Core开源组件获取的主要⽅法,通过NuGet可以下载各种中间件和组件,⽽且⽅便快捷(除了有时候断⽹,但是可以使⽤国内镜像),NuGet就像微软⽼妈给咱们的⼀个通讯录,并告诉咱们,如果你在某些⽅⾯需要帮助的时候,可以通过NuGet到你的七⼤姑⼋⼤姨来帮忙。
3、拓扑图
根据之前⽂章中成功的经验,简单改造⼀下,中间⼀个Windows系统和⼀个Ubuntu系统承载着.Net Core程序,有⼈会问Windows那个咋不来个IIS 啊,我要说的是.Net Core实⾏⾛出去的原则,基本脱离IIS,如果IIS上⾯想部署.Net Core程序的话,需要安装同样的应⽤程序,并且站点配置的应⽤程序池也要变成“⽆托管代码”。
4、开发.Net Core程序使⽤Session
4-1、创建⼀个Web程序
⽤Vs2017创建⼀个.Net Core的Web应⽤程序,且这个应⽤程序不包含⾝份验证信息
创建完如下
4-2、.Net Core调⽤Session
.Net Core使⽤Session,需要引⽤相关Session的NuGet包,⽹上⼀查,发现.Net Core的官⽅Session组件类似⼀个中间件,并且官⽅⽀持Redis。
注意:.Net Core的Mvc不能直接使⽤Session,如果你在程序⾥⾯写了个HttpContext.Session就会出现如下错误:Session has not been configured for this application or request.
4-2-1、Microsoft.AspNetCore.Session
.Net Core使⽤Session必须安装Microsoft.AspNetCore.Session,他的NuGet包安装如下图:
4-2-2、修改Startup.cs让Session可⽤
在相应位置加⼊⾼亮代码services.AddSession(); app.UseSession();
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.AddSession();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
4-2-3、Session写⼊和读取
Session的读取⽅式,与.Net有所不同,写法如下,并且Session的HttpContext.Session.SetString或者HttpContext.Session.Set⽅法分别⽀持字符串和Byte数组,所以复杂实体需要转化成Json存⼊Session中。
【Session 写⼊⽅法】
HttpContext.Session.SetString("key", "strValue");
【Session 读取⽅法】
HttpContext.Session.GetString("key")
5、Session存储介质更换为Redis
5-1、⾸先配置Redis
详细配置⽅式见:
redis-server f
详细配置⽅式见:
5-2、安装Microsoft.Extensions.Caching.Redis.Core
NuGet中搜索Microsoft.Extensions.Caching.Redis.Core并安装,此NuGet包是对Caching的拓展,即可以更换Caching存储介质
5-3、appsettings.json配置Redis连接字符串
appsettings.json配置Redis连接字符串(相当于fig⾥⾯配置appsetting节点),注意:添加位置要在Logging上⾯,否则读不到,添加代码为下⾯的⾼亮部分
{
"Data": "RedisConnection",
"ConnectionStrings": {
"RedisConnection": "192.168.8.138:6379"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
}
}
5-4、Startup.cs的ConfigureServices⽅法中添加引⽤
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.AddDistributedRedisCache(option =>
{
//redis 数据库连接字符串
option.Configuration = Configuration.GetConnectionString("RedisConnection" );
//redis 实例名
option.InstanceName = "master" ;
} );
services.AddSession();
}
页⾯运⾏HttpContext.Session.GetString("key"),然后⽤Redis管理⼯具RedisDesktopManager查询Session是否⼊库。
5-5、发布前指定IP和端⼝(重要)
如果你没有看这个步骤,继续下⾯发布步骤,等你发布时候,你会发现⼀个尴尬的问题,就是你⽤IP访问不了你的⽹站,⽤localhost可以访问,.Net Core默认是5000端⼝,端⼝占⽤也会让你的⽹站访问不了。
只需要在Program.cs中添加⾼亮代码即可,细⼼地⼈已经看到.UseUrls(new string[] { }) 传⼊的是个数组,那么这⾥定义多个⽹站,当你执⾏时候dotnet命令时候,多个⽹站都会启动。
public static void Main(string[] args)session如何设置和读取
{
var host = new WebHostBuilder()
//增加处,*号表⽰ip
.UseUrls(new string[] { "*:7201"  })
.UseKestrel()
.
UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
host.Run();
}
6、.Net Core 发布
6-1、Windows安装.Net Core发布环境[10.2.107.100]
1)安装,相当于IIS,注意安装时候请联⽹(好像是⾃动下载sdk,具体没仔细研究)。
2)输⼊dotnet命令验证,如果“报’dotnet’不是内部或者外部命令”请到“C:\Program Files\dotnet”⽂件
夹中的,⽤cmd来调⽤来运⾏,或者添加系统环境变量(window中cmd命令可以节省在编写命令时候可以.exe,即命令dotnet就是)
【坑1】
在win7下提⽰⼀下错误:Failed to load the dll from [C:\Program Files\dotnet\host\fxr\1.0.1\hostfxr.dll], HRESULT: 0x80070057
解决⽅法:
需要安装补丁:KB2533623
下载地址如下:
【坑2】
注意 Core版本,本⽂主要是⽤的 Core 1.1.1开发的,下⾯两个截图是版本按错了出的错误信息
6-2、Ubuntu安装.Net Core发布环境[10.2.107.46]
官⽅写的很详细了,照着做即可,千万别抵触Linux系统,抵触的话那就别⽤.Net Core了,如果不知道Ubuntu和Linux的关系的话请百度。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。