develope logs.

开发 ASP.NET vNext 续篇:云优化的概念、Entity Framework 7.0、简单吞吐量压力测试

继续上一篇《开发 ASP.NET vNext 初步总结(使用Visual Studio 2014 CTP1)》之后,

关于云优化和版本控制:

我本想做一下MAC和LINUX的self-host测试,但是官方说运行环境的MONO版本至少需要3.4.1,我去年买了个表,至本文发布为止,你让我下地狱去找3.4.1吗,硬着头皮用3.4.0搞了一晚上,MAC一直停留在 httpapi.dll出错,Ubuntu Server 12.0.4 是不认其中的几个DLL包,具体哪几个也忘了,过段时间有了稳定版本再弄吧。 

但是,我因此却大概了解了它所谓的“云优化“是什么概念,先来看看如何在非windows环境运行一个项目的完整步骤:

  1. 把生产环境代码部署到某个全新的平台上(*nix与MAC)之后,进入当前代码目录下
  2. 运行sudo kpm restore 命令
  3. k运行时环境会根据project.json中记录的各个命名空间,自动联网恢复当前整个项目所需的包
  4. 包保存到本地
  5. 运行 k web ,启动self-host模式,或者 k run ,启动nginx等第三方宿主模式。"web"和"run"参数对应project.json中的相应节点配置。 

在步骤3,不同的系统会得到不同的包,这就是所谓的云优化

如果以后需要更新包的版本,使用 kpm upgrade 来更新,依旧是手动,除了”.net 4.5 core“这个最核心的命名空间是从系统加载之外,其它的整个运行环境所需的全部包,都保存在你自己当前的目录下,从你自己的目录里面加载运行,相当于”绿色版“ASP.NET,举例来说,从前总有些功能是即使你把dll放到bin也没用的,必须是通过系统安装才可以使用,而现在,它可以100%的保证你所需的全部功能都可以通过把dll部署到bin目录来解决,这样做的实际意义是:aws和azure的linux主机不允许我们运行root用户,总有些东西是我们哪怕sudo也没法安装的,这只是其中一例,至此明白我的意思就好,进而的,我们可以把同一个应用程序的不同版本部署到不同的目录,绑定不同的域名,完全隔离它们的运行期上下文,这就是所谓的每个应用程序可以运行于不同的版本

 

关于从nuget加载包的担心

初次启动它不会自动去nuget加载,下次再怎么重启也更不会去nuget自动加载,一切涉及到nuget的行为都需要你自己手动控制,restore时只有100%成功加载后,你的应用程序才能够运行,否则回滚,upgrade也一样必须是100%成功,否则回滚,你把它想象成一个“事务”来理解就可以了,不会在“加载”这件事上对你的应用程序造成影响。

此nuget也非彼nuget,默认情况下它会到nuget官方服务器加载包,但是kpm restore 和 upgrade 可以指定不同的源地址,如果你愿意,你可以指定到127.0.0.1。所以到此为止,不需要在部署上有什么担心了。

 

关于VS2014:

根据微软向来的潜规则,某个组件还在测试版本阶段的时候,它的命名空间是:Microsoft.XXX.XXX,待到正式版本发布后,会变成System.XXX.XXX。目前很多包都是Microsoft名下。

我目前的VS2014 CTP1是在卸载掉本机的2013、2012、2010之后才顺利安装上的,但是也不知道是我卸载过程中卸错了东西还是VS2014 CTP1本身作怪,我系统上的SQLServer光荣牺牲掉了,重新安装一遍SQLServer就好(修复安装),虽然它说了不能与旧版本的VS共存于同一台机器,但是我后来再次安装上了VS2013.2,一切工作正常。(有风险,请勿仿效,本人不负责一切后果)

有时候你编辑着一个项目,一切风平浪静,但是当你保存,关闭vs2014,再次打开vs2014开启项目后,项目中的“引用列表”会一直停留在loading状态,重启几次后才好,鬼才知道是为什么。

 

凡事讲究门当户对,既然时代已经进入vNext,不用EF 7.0怎么对得起D和人民:

 

Entity Framework 7.0 :更加简洁,可恶的Migration终于离去

(Entity Framework 7.0可以独立于vNext,运行于MVC1~5.x)

创建好一个示范用的数据库之后,看看:

在过去,使用Migration的时候遇到的最大问题,不是Migration步骤本身,而是时不时出现:“已经存在相同的表或对象”,各种解法稀奇古怪,甚至需要去修改Migration自动生成的文件,自己玩玩的项目就算了,真正大规模实时生产环境里面你敢这么做?

在过去,Migration表中记录了每个数据表的结构Hash值,如果你手动修改了表结构,哪怕是实际已经保持了结构的一致性,但是Entity Framework依然会报错,因为Hash值不对,它只相信它自己的Migration,虽然可以通过应用程序初始化期间关闭数据结构检查来越过Migration步骤,但是依旧心慌慌的,出门和人吹牛也怕被因此抓到把柄。现在,Migration终于消失了,意味着你可以自己去手动修改表结构与Code First结构同步,它再也不会自作聪明来为难你了。

由此带来的另一个好处:省掉该功能后,同时也意味着省去很多开发与测试步骤,EF团队能够更专注于EF本身的核心功能,更快速更新/修复版本,第三方数据库开发商可以更快速地发行/更新与自己的数据库对应的Entity Framework框架。

你依然可以使用Migration,系统把这个功能分离出来放置在Microsoft.Data.Entity.Migration空间下,至于怎么去使用,我就没去研究了。

过去,在运行时,Entity Framework 会自动检查数据库是否存在,如果不存在,就自动创建一个数据库,并且创建对应的表等所有对应结构。现在这个功能需要我们手动去开启,并且“创建数据库”与“创建表”还是两码事,就像这样:

    /// <summary>
    /// 数据库操作类
    /// </summary>
    public class DBOperator : DbContext
    {
        public DBOperator() 
        {
            if (!Database.Exists())
            {
                Database.Create(); //创建数据库
                Database.CreateTables(); //创建表
            }
        }

        public DbSet<Customers> Customers { get; set; }

        protected override void OnConfiguring(DbContextOptions builder)
        {
            builder.UseSqlServer(@"Server=HP\SQLSERVER;Database=vNextTest;Trusted_Connection=True;MultipleActiveResultSets=true");
        }
    }

在1~6.x版本中,你可以把构造函数去掉,没问题,系统会自动创建数据库和表,但是现在不行了,如果你删掉上面代码例子中的构造函数,数据库不会在一开始得到创建,由此引发了这么一种思考: 在实际运行过程中,99.9999999999%的情况里是不需要去if (!Database.Exists())的,我们就可以通过构建一个多态结构来这么做,确保性能的最大化:

    public abstract class DBO : DbContext
    {
        public DbSet<Customers> Customers { get; set; }

        protected override void OnConfiguring(DbContextOptions builder)
        {
            builder.UseSqlServer(@"Server=HP\SQLSERVER;Database=vNextTest;Trusted_Connection=True;MultipleActiveResultSets=true");
        }
    }

    public sealed class DBOperator : DBO
    {
        //实际运行时使用这个类
        //省去不需要的判断
    }

    public sealed class FirstTime : DBO
    {
        public FirstTime() 
        {
            //系统第一次运行时使用这个类,把它放在Started.cs中执行一次就好了
            if (!Database.Exists())
            {
                Database.Create(); //创建数据库
                Database.CreateTables(); //创建表
            }
        }
    }

 设置project.json,启用Entity:

{
    "dependencies": {
        "Helios" : "0.1-alpha-build-0585",
        "Microsoft.AspNet.StaticFiles": "0.1-alpha-build-0443",
        "Microsoft.AspNet.Mvc": "0.1-alpha-build-1268",
        "Microsoft.AspNet.Server.WebListener": "0.1-alpha-build-0520",
        "Microsoft.Data.Entity": "0.1-alpha-build-*", //启用Entity
        "Microsoft.Data.Entity.SqlServer": "0.1-alpha-build-0863", //启用SQL Server
        "Microsoft.DataAnnotations": "0.1-alpha-build-0100", //启用DataAnnotations
        "Microsoft.Framework.ConfigurationModel": "0.1-alpha-build-0233" //启用配置文件操作
    },
    "configurations" : {
        "net45" : { },
        "k10" : { }
    }
}

 

其它的SaveChange、Add等操作和从前一样,就不说了。

同道中人们,从现在开始,请扔掉Migration。

 

 vNext运行于self-host模式和IIS模式,对比传统MVC 5.x

下面是使用AB对vNext做一个简单压力测试,主要是对吞吐量有个心理概念,controller中进行斐波那契序列30次迭代运算,View是空的,只输出简单HTML,客户端模拟1000个用户总共进行10000次访问。 每次测试前,都额外通过IE访问一次(消除初次启动)。

        public IActionResult Index()
        {
            var x = new int[30];
            var length = x.Length;

            for (int n = 0; n < 30; n++)
            {
                switch (n)
                {
                    case 0:
                        x[n] = 1;
                        break;
                    case 1:
                        x[n] = 1;
                        break;
                    default:
                        x[n] = x[n - 1] + x[n - 2];
                        break;
                }
                this.Context.Response.WriteAsync((x[n]).ToString() + "<br />");
            }

            return View();
        }

该说的都在图中说了,但愿正式版出来后情况会好一些。

 

目前尚未解决的问题

*nix环境下实在配置不来,如果有哪位师兄愿意折腾的话,请看他们的官方说明:https://github.com/aspnet/home

posted @ 2014-06-08 14:25  develope-logs  阅读(13963)  评论(40编辑  收藏  举报