博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET MVC之Session State性能问题(七)
阅读量:5754 次
发布时间:2019-06-18

本文共 5804 字,大约阅读时间需要 19 分钟。

前言

这一节翻译一篇有关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
boxes = new List
() { "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请求以及其他操作,我们看看视图中代码:

    

接下来我们看看 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
boxes = new List
() { "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模式下进行演示,可能这样的效果更加明显。

参考

结语

当有多个请求发送到服务器时此时若进行Session操作将会对性能产生一定影响。我们通过设置 [SessionState(SessionStateBehavior.Disabled)] 特性最终验证了这一观点。但是这样设置后我们将无法获取Session中的值。所以在请求数量较多的情况下,建议对于Ajax请求使用Web APi来完成,我们通过Web APi来接收Ajax请求,可以使用Session中的数据来渲染视图或者提交到数据或者参数到MVC控制器的Action方法上。

本文转自Jeffcky博客园博客,原文链接:http://www.cnblogs.com/CreateMyself/p/5408400.html,如需转载请自行联系原作者

你可能感兴趣的文章
struts2用了哪几种模式
查看>>
replace函数结合正则表达式实现转化成驼峰与转化成连接字符串的方法
查看>>
ubuntu 初学常用命令
查看>>
WCF客户端与服务端通信简单入门教程
查看>>
判断是否含有中文
查看>>
android 资源种类及使用
查看>>
Explorer程序出错
查看>>
Centos7同时运行多个Tomcat
查看>>
使用CocoaPods过程中的几个问题
查看>>
我的友情链接
查看>>
mysql数据类型---数值型---int
查看>>
为eclipse安装maven插件
查看>>
公司新年第一次全员大会小记
查看>>
最懒的程序员
查看>>
JAVA8 Stream 浅析
查看>>
inner join on, left join on, right join on要详细点的介绍
查看>>
SAS vs SSD对比测试MySQL tpch性能
查看>>
Spring boot 整合CXF webservice 全部被拦截的问题
查看>>
Pinpoint跨节点统计失败
查看>>
【Canal源码分析】Canal Server的启动和停止过程
查看>>