在经历了阿里云上“黑色1秒”的空欢喜之后,我们“被迫”考虑实现.NET的跨平台,将Web服务器由Windows换成Linux。而这种“被迫”在一个存在已久的愿望下,变得水到渠成。这个愿望就是 —— “Mac上写.NET程序,Linux上跑.NET程序”。

既然水也到了,渠也成了,那我们还等什么,动身起程吧。

今天我们以我们迈出的第一步——一个部署在Linux上基于dnx/corefx/coreclr的非常简单的ASP.NET 5/MVC 6站点——宣布“.NET跨平台之旅”开启了!

这个基于跨平台.NET的站点已经上线,访问网址:http://about.cnblogs.com/

该站点部署在CentOS服务器上(部署步骤),服务器上只安装了dnx,没有安装mono,所以是完全基于.NET Core运行。后端Web服务器用的是Kestrel,也是目前跨平台.NET在非Windows平台上唯一能用的Web服务器。

CentOS服务器上运行情况如下:

[root@about-server AboutUs]# dnx . kestrel
Started

前端Web服务器用的是阿里云SLB(负载均衡),如果不用SLB,可以直接在CentOS上用nginx做反向代理。为什么要用前端Web服务器?因为Kestrel Web服务器实在太简陋了,连keep-alive与http compression的功能都没有。

该站点的ASP.NET 5程序是在Ubuntu服务器上用vim进行开发的。

项目文件结构如下:

.
├── Controllers
│   ├── AboutController.cs
│   └── HomeController.cs
├── Extensions
│   └── HtmlHelperExtensions.cs
├── project.json
├── project.lock.json
├── Startup.cs
├── Views
│   ├── About
│   │   ├── Ad.cshtml
│   │   ├── Contact.cshtml
│   │   ├── Intro.cshtml
│   │   └── Job.cshtml
│   ├── Shared
│   │   └── _Layout.cshtml
│   └── _ViewStart.cshtml
└── wwwroot
├── images
│   ├── about_cnbogs.gif
│   ├── icon_arrow.gif
│   └── icon_triangle.gif
└── styles
└── about.css

project.json文件中的配置:

{
"webroot": "wwwroot",
"exclude": ["wwwroot"],
"commands":{
"kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:8001"
},
"dependencies":{
"Kestrel": "1.0.0-*",
"Microsoft.AspNet.Mvc": "6.0.0-*",
"Microsoft.AspNet.StaticFiles": "1.0.0-*",
"Microsoft.AspNet.Diagnostics": "1.0.0-*"
},
"frameworks":{
"dnxcore50": {}
}
}

frameworks中只有dnxcore50,说明程序是完全基于.NET Core的。但由于基于coreclr的dnu restore功能目前无法使用,所以在开发环境中不得不安装mono,用基于mono的dnu retore安装nuget包包。

Startup.cs中的代码如下:

using Microsoft.AspNet.Builder;
using Microsoft.Framework.DependencyInjection; namespace CNBlogs.AbouUs.Web
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseErrorPage(); app.UseMvcWithDefaultRoute(); app.UseStaticFiles();
} public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
}
}

(注:project.json与Startup.cs中都没有多余的配置与代码)

程序非常简单,没有数据库操作,主要就是显示文字内容。稍微复杂些的就是一个HtmlHelpder扩展方法(代码是从现有项目中移植过来的),根据访问的URL自动高亮左侧的导航标签,代码如下:

using Microsoft.AspNet.Mvc.Razor;
using Microsoft.AspNet.Mvc.Rendering; namespace Microsoft.AspNet.Mvc.Rendering
{
public static class HtmlHelperExtensions
{
public static HtmlString TabLink(this IHtmlHelper htmlHelper, string linkText, string linkUrl, string viewName)
{
var view = htmlHelper.ViewContext.View as RazorView;
if (view != null && view.Path.IndexOf("/" + viewName + ".", System.StringComparison.OrdinalIgnoreCase) > -)
{
return htmlHelper.Raw(string.Format("<a href=\"{0}\" class=\"current\">{1}</a>", linkUrl, linkText));
}
else
{
return htmlHelper.Raw(string.Format("<a href=\"{0}\">{1}</a>", linkUrl, linkText));
}
}
}
}

这个ASP.NET 5程序的代码是一步一步从无到有用vim手写出来的(除了视图与HtmlHelperExtensions), 从中更深刻地了解了ASP.NET 5的一些工作原理,从而也得到了一个运行这个简单的ASP.NET 5程序所需的最小配置。

在开发过程中最痛苦的是修改代码后ASP.NET 5不会自动重新编译,需要重新用dnx运行程序;而且Kestrel目前有bug,无法退出,即使关闭ssh窗口,也照样运行,必须用非常规手段强制结束进程(ps all; kill -9 [PID])。但Kestrel的这个bug却带来一个让人惊喜的副作用,正因为它一启动就一直运行,怎么也不会退出,相当于以一种后台服务的方式运行,一下子解决了部署时如何后台运行ASP.NET 5站点的问题。

虽然只是一个非常简单的ASP.NET 5程序,虽然只是.NET跨平台之旅非常非常小的一步,但它却是重要的一步,因为它让我们实实在在地感受到了——.NET跨平台,路在脚下。

【更新】

6月29日15:35左右,出现异常造成kestrel退出,重新运行dnx之后恢复正常。异常信息如下:

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.AspNet.Server.Kestrel.Networking.UvShutdownReq.UvShutdownCb(IntPtr ptr, Int32 status)

6月30日凌晨3:18左右,kestrel挂掉1次。

6月30日18:19左右,因为dnx内存泄漏而挂掉(怀疑是kestrel引起的内存泄漏)。

从一个简单的ASP.NET 5站点开启.NET跨平台之旅的更多相关文章

  1. 开始一个简单的ASP.NET Web API 2 (C#)

    创建一个Web API 项目 在本教程中,你将使用ASP.NET Web API 来创建一个web API 并返回产品列表. 网页前端使用jQuery 显示结果. 选择ASP.NET Web Appl ...

  2. 一个简单的ASP.NET MVC异常处理模块

    一.前言 异常处理是每个系统必不可少的一个重要部分,它可以让我们的程序在发生错误时友好地提示.记录错误信息,更重要的是不破坏正常的数据和影响系统运行.异常处理应该是一个横切点,所谓横切点就是各个部分都 ...

  3. 用VS2015写一个简单的ASP.net网站

    第一步:打开VS2015,然后新建一个空的解决方案,其中解决方案的名称WebSiteTest可类似认为是本次网站的名称,系统会以该名称(WebSiteTest)生成一个文件夹,在WebSites文件夹 ...

  4. 一个简单的 ASP.NET MVC 例子演示如何在 Knockout JS 的配合下,使用 TypeScript 。

    前言 TypeScript 是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.安德斯·海尔斯伯格,C#的首席架 ...

  5. 创建一个简单的WCF程序2——手动开启/关闭WCF服务与动态调用WCF地址

    一.创建WCF服务器 1.创建WCF服务器的窗体应用程序 打开VS2010,选择文件→新建→项目菜单项,在打开的新建项目对话框中,依次选择Visual C#→Windows→Windows窗体应用程序 ...

  6. [ASP.NET Core 3框架揭秘] 跨平台开发体验: Mac OS

    除了微软自家的Windows平台, .NET Core针对Mac OS以及各种Linux Distribution(RHEL.Ubuntu.Debian.Fedora.CentOS和SUSE等)都提供 ...

  7. ASP.NET Aries 入门开发教程2:配置出一个简单的列表页面

    前言: 朋友们都期待我稳定地工作,但创业公司若要躺下,也非意念可控. 若人生注定了风雨飘摇,那就雨中前行了. 最机开始看聊新的工作机会,欢迎推荐,创业公司也可! 同时,趁着自由时间,抓紧把这系列教程给 ...

  8. 通过Knockout.js + ASP.NET Web API构建一个简单的CRUD应用

    REFERENCE FROM : http://www.cnblogs.com/artech/archive/2012/07/04/Knockout-web-api.html 较之面向最终消费者的网站 ...

  9. 推荐一个简单、轻量、功能非常强大的C#/ASP.NET定时任务执行管理器组件–FluentScheduler定时器

    在C#WINFORM或者是ASP.NET的WEB应用程序中,根据各种定时任务的需求,比如:每天的数据统计,每小时刷新系统缓存等等,这个时候我们得应用到定时器这个东东. .NET Framework有自 ...

随机推荐

  1. Vue.js 递归组件实现树形菜单

    最近看了 Vue.js 的递归组件,实现了一个最基本的树形菜单. 项目结构: main.js 作为入口,很简单: import Vue from 'vue' Vue.config.debug = tr ...

  2. iOS适配 旧项目工程在iOS9下不能正常显示

    在iOS开发中,很多时候会用到旧项目,比如版本的升级.使用Demo等等, iOS SDK正在不断的升级,不断的升级给iOS开发带来了新的活力. 然而在iOS SDK新的版本出来之后,旧项目可能会出现新 ...

  3. Set up Github Pages with Hexo, migrating from Jekyll

    Set up Github Pages with Hexo, migrating from Jekyll. 本文介绍用Hexo建立github pages, 其中包含了从Jekyll迁移过来的过程. ...

  4. [转]设计一款Android App总结

    开发工具的选择 开发工具我将选用Android Studio,它是Google官方指定的Android开发工具,目前是1.2.2稳定版,1.3的预览版也已经发布了.Android Studio的优点就 ...

  5. Android 学习心得 TextView 添加垂直滚动条

    XMl文件中: 添加android:scrollbars="vertical" 添加android:maxLines="10"  //设置一页最多显示10行 a ...

  6. 【代码笔记】iOS-下拉选项cell

    一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> //加入头文件 #import "ComboBo ...

  7. $是对string.Format的简化

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. JVM之方法区

     基本特性: 线程共享区域,存储被JVM加载的类信息.常量.静态变量.即时编译器编译的代码等 堆的逻辑部分,不限定方法去内的内存位置和编译代码的管理策略,不限定实现垃圾回收 容量可不定也可动态扩展,不 ...

  9. Java 6 JVM参数选项大全(中文版)

    原文来自: http://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm 本文是基于最新的SUN官方文档Java SE 6 Hotsp ...

  10. LLVM 笔记(三)—— 了解传统编译器设计

    ilocker:关注 Android 安全(新手) QQ: 2597294287 传统的静态编译器 (如大多数的 C 语言编译器) 通常将编译工作分为三个阶段,分别由三个组件来完成:前端.优化器和后端 ...