MVC之Session State性能
ASP.NET MVC之Session State性能问题(七)
前言
这一节翻译一篇有关Session State性能问题的文章,非一字一句翻译。
话题
不知道我们在真实环境中是否用到了Session State特性,它主要用来当在同一浏览器发出多个请求时来存储数据,在现在我们更多的为了避免整个页面刷新,Web应用程序更多倾向于利用高扩展性的Ajax,但是不知道我们是否注意到当我们使用Session数据多次请求MVC上的Action方法时产生的性能问题呢?
将Session放入上下文中(Put Session into the Context)
在进行代码演示时我们首先得知道Session的工作原理:当一个新请求第一次到达服务器时,显然在此之前Cookie中没有SessionId的,此时服务器将创建一个新的Session标识,通过如下:
System.Web.HttpContext.Current.Session.SessionID
但是并不意味着当有多个请求发送到服务器上时,服务器都会保存一个Session Cookie。只是在Session中保存具体请求的数据,换言之,ASP.NET Framework会首先会添加Session Cookie到响应流中,此时需要保存的数据将被保存在Session中。
因此,说到这里好像和我们要讲的主题半毛钱关系都没有,那跟我们的性能有什么关系呢?ASP.NET能够处理来自同一浏览器的多个请求,如下:

在上述图片中,当浏览器未发出请求时显然在服务器上不会存储任何Session数据,如果服务器存储了一些数据在Session中,此时将会添加一个Session Cookie到响应流中,接下来所有的子请求使用相同的Session Cookie,同时会以队列的形式依次等待被处理。

我们能够想象到一种很常见的场景,要是多个请求同时去读取或修改相同的Session值,此时则会造成不一致的数据。接下来进入我们话题演示时间。
代码演示
我们在控制器中给出如下代码:

[OutputCache(NoStore = true, Duration = 0)] //不缓存数据
public class HomeController : Controller
{
public List<string> boxes = new List<string>() { "red", "green", "blue", "black", "gray", "yellow", "orange" };
// GET: Home
public ActionResult Index()
{
return View();
} public string GetBox() //随机获取集合中颜色
{
System.Threading.Thread.Sleep(10);
Random rnd = new Random();
int index = rnd.Next(0, boxes.Count); return boxes[index];
} public ActionResult StartSession() //启动Session并存值
{
System.Web.HttpContext.Current.Session["Name"] = "Chris"; return RedirectToAction("Index");
}
}

接下来我们利用AngularJS在视图中发出Ajax请求以及其他操作,我们看看视图中代码:

<body ng-controller="asyncCtrl" ng-init="getBoxes()">
<nav role="navigation" class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" data-target="#navbarCollapse" data-toggle="collapse" class="navbar-toggle">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Collection of nav links and other content for toggling -->
<div id="navbarCollapse" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Performace testing</a></li>
<li>
@Html.ActionLink("Start Session", "StartSession")
</li>
<li>
<a class="links" ng-click="getBoxes()">Not resolved</a>
</li>
<li>
<a class="links" ng-click="getBoxes(true)">Resolved</a>
</li>
<li>
<form class="navbar-form">
<label class="checkbox" style="margin-top:5px">
@Html.CheckBox("isSessionNewChk", Session.IsNewSession, new { @disabled = "disabled" })
Is Session new
</label>
</form>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">{{boxes.length}} Boxes</a></li>
</ul>
</div>
</div>
</nav>
<br /><br /><br />
<div class="container">
<div class="row">
<div id="boxesContainer" ng-repeat="color in boxes track by $index">
<div class="box" ng-class="color" />
</div>
</div>
<br />
<div class="row">
<div id="timeOccured" ng-show="showResults" class="alert" ng-class="isResolved()" ng-bind="timeElapsed"></div>
</div>
</div>
<script src="~/Scripts/app.js"></script>
</body>

接下来我们看看 app.js

angular.module('asyncApp', [])
.value('mvcuri', 'http://localhost:49588/home/getbox')
.value('mvcurisessionresolved', 'http://localhost:49588/SessionResolved/getbox')
.controller('asyncCtrl', function ($http, $scope, mvcuri, mvcurisessionresolved) {
$scope.boxes = [];
$scope.showResults = false;
var uri;
$scope.getBoxes = function (resolved) {
var start = new Date();
var counter = 300;
if (resolved)
uri = mvcurisessionresolved;
else
uri = mvcuri;
// Init variables
$scope.boxes = [];
$scope.showResults = false;
$scope.timeElapsed = '';
for (var i = 0; i < 300; i++) {
$http.get(uri)
.success(function (data, status, headers, config) {
$scope.boxes.push(data);
counter--;
if (counter == 0) {
var time = new Date().getTime() - start.getTime();
$scope.timeElapsed = 'Time elapsed (ms): ' + time;
$scope.showResults = true;
}
})
.error(function (error) {
$scope.timeElapsed = error.Message;
}).finally(function () {
});
}
};
$scope.isResolved = function () {
return uri == mvcuri ? 'alert-danger' : 'alert-success';
}
});

上述AngularJS脚本比较简单就不叙述。接下来再创建一个控制器 SessionResolvedController 来进行比较。

[OutputCache(NoStore = true, Duration = 0)]
public class SessionResolvedController : Controller
{
public List<string> boxes = new List<string>() { "red", "green", "blue", "black", "gray", "yellow", "orange" }; public string GetBox()
{
try
{
System.Threading.Thread.Sleep(10);
Random rnd = new Random();
int index = rnd.Next(0, boxes.Count); return boxes[index];
}
catch(Exception ex)
{
return "red";
}
}
}

此时我们看看运行效果:

当我们运行程序时,此时复选框是勾上的,说明此时还未有添加数据到Session中,接下来我们点击 Start Session 看看效果:

上述我们是启动Start Session并控制整发出300个Ajax请求并返回随机颜色。我们看到花了8722毫秒。
接下来我们点击 Not resolved 看看耗时多少,如下:

耗时8166毫秒,看来和启动Session没什么区别可言。因为每个到服务器的请求都有一个Session Cookie,此时所有的请求将会被依次处理正如我们之前所描述的那样,所以接下来我们进行如下操作:
[SessionState(SessionStateBehavior.Disabled)]
public class SessionResolvedController : Controller
{.....}
我们禁用SessionState看看效果:

注意:上述程序运行建议在Release模式下进行演示,可能这样的效果更加明显。
参考
ASP.NET MVC Session state Performance Issue
结语
当有多个请求发送到服务器时此时若进行Session操作将会对性能产生一定影响。我们通过设置 [SessionState(SessionStateBehavior.Disabled)] 特性最终验证了这一观点。但是这样设置后我们将无法获取Session中的值。所以在请求数量较多的情况下,建议对于Ajax请求使用Web APi来完成,我们通过Web APi来接收Ajax请求,可以使用Session中的数据来渲染视图或者提交到数据或者参数到MVC控制器的Action方法上。
非常感谢您花时间读完这篇文章,如果您觉得此文不错,请点一下“推荐”按钮,您的“推荐”就是对我最大的鼓励以及不懈努力的肯定。
本文版权归作者和博客园所有,来源网址:http://www.cnblogs.com/CreateMyself/欢迎各位转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利以及小小的鄙视。


四月 2016
周一
周二
周三
周四
周五
周六
周日
搜索
随笔分类
- AccumulateKnowledge(2)
- AngularJS(2)
- ASP.NET Boilerplate Project(ABP)
- ASP.NET MVC(8)
- ASP.NET SignalR
- Autofac
- AutoMapper
- C#(9)
- Design Patterns
- Domain Driven Design(DDD)
- EntityFramework 6.x(13)
- EntityFramework Core(1)
- EPPlus
- JavaScript Definitive Guide(9)
- JQuery
- LINQ(1)
- Log4Net
- NLog
- NPOI
- ProgramLife(2)
- Python
- Ruby(3)
- SQL Server
- UnitTest(1)
- Unity
- Visual Studio(3)
- WCF
- Web APi(17)
- Web Service
- Windows Service
积分与排名
- 积分 - 75551
- 排名 - 2831
最新评论
- 1. Re:ASP.NET MVC之Session State性能问题(七)
- 谢谢分享
- --沈赟
- 2. Re:ASP.NET MVC之JsonResult(六)
- 谢谢分享
- --沈赟
- 3. Re:EntityFramework 7.0之初探【基于VS 2015】(十)
- 我在使用 ef core 最新版时 一直 链接不了 数据库!之后在 EFDbContext 类里面 重写 OnConfiguring 方法 加入链接字符串,正常了!于是 查看 官网 DBContext......
- --eclipghc
- 4. Re:ASP.NET MVC之Unobtrusive Ajax(五)
- 标记标记
- --JaneEyre
- 5. Re:ASP.NET MVC之视图生成URL(二)
- @Dic4000是的,首先匹配这个!...
- --Recluse_Xpy
阅读排行榜
- 1. Web APi之认证(Authentication)两种实现方式【二】(十三)(5315)
- 2. EntityFramework之原始查询及性能优化(六)(5224)
- 3. EntityFramework之你不知道的那些事(七)(4490)
- 4. EntityFramework 7.0之初探【基于VS 2015】(十)(4203)
- 5. EntityFramework之异步、事务及性能优化(九)(4080)
- 6. EntityFramework之Log(五)(3655)
- 7. Web APi之HttpClient注意事项以及建议(四)(3189)
- 8. EntityFramework之数据库以及表基本创建(一)(2968)
- 9. Web APi入门之移除XML格式(一)(2934)
- 10. VS2015 Enterprise 安装之惊险及收获(2249)
评论排行榜
- 1. EntityFramework之Log(五)(68)
- 2. EntityFramework之原始查询及性能优化(六)(61)
- 3. EntityFramework之异步、事务及性能优化(九)(57)
- 4. 记一次ASP.NET MVC性能优化(实际项目中)(44)
- 5. EntityFramework 7.0之初探【基于VS 2015】(十)(43)
- 6. EntityFramework之数据库以及表基本创建(一)(37)
- 7. Web APi入门之移除XML格式(一)(32)
- 8. Web APi之认证(Authentication)两种实现方式【二】(十三)(30)
- 9. Web APi之HttpClient注意事项以及建议(四)(29)
- 10. EntityFramework之你不知道的那些事(七)(28)
推荐排行榜
- 1. EntityFramework之原始查询及性能优化(六)(71)
- 2. Web APi之认证(Authentication)两种实现方式【二】(十三)(57)
- 3. EntityFramework之异步、事务及性能优化(九)(41)
- 4. EntityFramework 7.0之初探【基于VS 2015】(十)(36)
- 5. EntityFramework之Log(五)(36)
- 6. EntityFramework之你不知道的那些事(七)(27)
- 7. EntityFramework之数据库以及表基本创建(一)(20)
- 8. Web APi入门之移除XML格式(一)(19)
- 9. 记一次ASP.NET MVC性能优化(实际项目中)(18)
- 10. EntityFramework之DetectChanges's Secrets(三)(我为EF正名)(17)
MVC之Session State性能的更多相关文章
- ASP.NET MVC之Session State性能问题(七)
前言 这一节翻译一篇有关Session State性能问题的文章,非一字一句翻译. 话题 不知道我们在真实环境中是否用到了Session State特性,它主要用来当在同一浏览器发出多个请求时来存储数 ...
- 关于ASP.NET Session State Server
最近公司开发的一个网站因为访问量增大,需要添加多台Web Server来进行负载均衡. 但是在做负载均衡前需要将一些原来固定存储在单台机器上的东西分离出来,使之能单独存在在一个独立的机器上,其中就有S ...
- 转载ASP.NET MVC中Session的处理机制
本文章转载自 http://www.cnblogs.com/darrenji/p/3951065.html ASP.NET MVC中的Session以及处理方式 最近在ASP.NET MVC项目中 ...
- easyui datagrid 禁止选中行 EF的增删改查(转载) C# 获取用户IP地址(转载) MVC EF 执行SQL语句(转载) 在EF中执行SQL语句(转载) EF中使用SQL语句或存储过程 .net MVC使用Session验证用户登录 PowerDesigner 参照完整性约束(转载)
easyui datagrid 禁止选中行 没有找到可以直接禁止的属性,但是找到两个间接禁止的方式. 方式一: //onClickRow: function (rowIndex, rowData) ...
- Session State Pattern会话状态模式
Client Session State 客户会话状态. 在Client端保存会话状态. 运行机制 Client在每次请求时会把所有的会话数据传给Server,Server在响应时把所有的会话状态传给 ...
- 实现Asp.net Mvc分布式Session Redis群集
Redis群集实现Asp.net Mvc分布式Session Session的缺点 众所周知Asp.net Session默认存储在IIS中,IIS的重启会导致Session丢失. 如果你的网站使用了 ...
- Spring MVC中Session的正确用法<转>
Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...
- Unable to make the session state request to the session state server处理
Server Error in '/' Application. Unable to make the session state request to the session state serve ...
- 【转】Spring MVC中Session的正确用法之我见
Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...
随机推荐
- ASM丢失disk header导致ORA-15032、ORA-15040、ORA-15042 Diskgroup无法mount
SQL> select * from v$version; BANNER --------------------------– Oracle Database 11g Enterprise E ...
- Oracle基础知识笔记(10) 约束
表尽管建立完毕了,可是表中的数据是否合法并不能有所检查,而假设要想针对于表中的数据做一些过滤的话,则能够通过约束完毕,约束的主要功能是保证表中的数据合法性,依照约束的分类,一共同拥有五种约束:非空约束 ...
- c# 调用外部exe程序
c#调用外部exe程序,首先要 using System.Diagnostics; 然后开启一个新process System.Diagnostics.ProcessStartInfo p=null; ...
- java内存管理简析
作为java程序员,因为有虚拟机的自动内存管理,所以不需要再向C和C++程序员那样灾区写delete和free方法,但是java中是不是就不存在内存泄露问题呢,答案是否定的,java中一样存在内存泄漏 ...
- Windows Azure 安全最佳实践 - 第 3 部分:确定安全框架
构建云应用程序时,安全始终是计划和执行Windows Azure的首要核心因素.第 1 部分提出安全是一项共同责任,Windows Azure为您的应用程序提供超出内部部署应用程序需求的强大安全功能. ...
- hibernate解决oracle的id自增?
以前做SSH项目时,涉及到的数据库是mySQL,只需将bean的配置文件id设为native 就可以实现表id的自增. 现在用到了Oracle,当然知道这样是不行的啦,那么用序列自增? 我在网络上搜索 ...
- 利用ScktSrvr打造多功能Socket服务器
Socket服务端编程中最重要的也是最难处理的工作便是客户请求的处理和数据的接收和发送,如果每一个Socket服务器应用程序的开发都要从头到尾处理这些事情的话,人将会很累,也会浪费大量时间.试想,如果 ...
- Fedora Linux 下安装配置C开发环境Code::Blocks
一.提前的话要说C语言和Linux的关系大家应该都不会陌生,Linux系统内核就是用C语言开发的,所以所有的Linux系统下面 都会有C的编译调试工具,不过这些工具都是命令式的,正式开发的话会很不方便 ...
- 被忽视的TWaver功能(1)
应客户需求写个Demo,Demo中包括一些经常使用的功能.包括解析JSON数据生成TWaver中的网元和连线.网元右下角带上不同标识的小图标,连线须要是二次曲线.弹出菜单和信息板.跟大家分享下.先上图 ...
- js中静态函数与变量
一 私有变量和函数 js中没有概念上的私有,公有也没有静态和非静态相关概念,有的只能是通过作用于来模仿 函数的块级作用域使得函数内部成员可以不被外部所访问,比如我们使用块级作用于定义一个类 //定义一 ...




