ASP.NET Linux部署(2) - MS Owin + WebApi + Mono + Jexus

原文: ASP.NET Linux部署(2) - MS Owin + WebApi + Mono + Jexus

ASP.NET Linux部署(2) - MS Owin + WebApi + Mono + Jexus

本文承接個人上一篇博文: ASP.NET 5 Linux部署,那篇文章主要是針對最新的ASP.NET 5的,但在隨後的研究中,我對這種娛樂型的部署依然不是很是滿意,固然其主要緣由是由於ASP.NET 5 依然處於RC版本,並不十分紅熟. 但能夠預見到的是,就算本月ASP.NET 5 RTM版本如期推出,其在Linux上面的開發和部署前景依然不是很是明朗: 特別使人困惑的是,MS在Linux上至今僅僅推出了幾個以開發爲目的的簡單服務器實現,難以在其計劃中尋覓到相似IIS的完整部署環境,那麼所謂的ASP.NET 5的跨平臺開發是否只能停留在實驗室水平? 目前乃至從此很長一段時間內(直到ASP.NET 5徹底在Linux上站穩腳跟),咱們有沒有更好的選擇?下面我將給出我本身的想法.html

這裏首先聲明一點,ASP.NET Linux部署系列僅針對Linux部署環境,不涉及Windows部署環境.下面仍是先給出一些概念以便於你們更好的理解後續的內容.linux

ASP.NETjson

ASP.NET是.NET Framework的一部分,是一項微軟公司的技術,是一種使嵌入網頁中的腳本可由因特網服務器執行的服務器端腳本技術, 本月即將發佈的最新版本是版本5,又成爲vNext.api

Linux瀏覽器

Linux是一套無償使用和自由傳播的類Unix操做系統,是一個基於POSIX和UNIX的多用戶、多任務、支持多線程和多CPU的操做系統. 本文中的Linux主要以Ubuntu做爲樣例.緩存

Mono服務器

mono是指由Novell公司(由Xamarin發起,並由Miguel de lcaza領導的,一個致力於開創.NET在Linux上使用的開源工程. 就目前而言,在Linux上的.NET應用還必須基於Mono來運行.多線程

Jexus架構

Jexus 即 Jexus Web Server,簡稱JWS,是Linux平臺上的一款ASP.NET WEB服務器,是目前惟一可以支持企業級ASP.NET Linux部署的一種方案(其餘的服務器方案無相似定位).app

OWIN

OWIN在.NET Web Servers與Web Application之間定義了一套標準接口,OWIN的目標是用於解耦Web Server和Web Application。基於此標準,鼓勵開發者開發簡單、靈活的模塊,從而推動.NET Web Development開源生態系統的發展。

MS Owin

微軟開發的基於OWIN規範的底層實現,最新版本是3.0.1,其主項目名稱爲Kanata

ASP.NET WebApi

ASP.NET MVC 4 包含了 ASP.NET Web API, 這是一個建立能夠鏈接包括瀏覽器、移動設備等多種客戶端的 Http 服務的新框架, ASP.NET Web API 也是構建 RESTful 服務的理想平臺

RESTful

一種軟件架構風格,設計風格而不是標準,只是提供了一組設計原則和約束條件。它主要用於客戶端和服務器交互類的軟件。基於這個風格設計的軟件能夠更簡潔,更有層次,更易於實現緩存等機制。

NancyFx

Nancy 是一個基於 .NET 和 Mono 平臺用於構建輕量級基於 HTTP 的 Web 服務。基於 .NET 和 Mono 平臺,框架的目標是保持儘量多的方式,並提供一個super-duper-happy-path全部交互。官方網站 http://nancyfx.org/

 

三種選擇

就.NET路線的Web開發來看,無論何種方式,將來必然是基於OWIN開發的事實已經不可動搖了; 在這個基礎上, 我認爲目前在Linux上開發並部署.NET Web應用程序有3個路線能夠選擇:

  1. 底層Owin路線: 選擇MS的底層OWIN實現,配合其餘基於OWIN的獨立組件,造成以底層OWIN爲核心的自行搭配的輕型構架,這個方案目前已經能夠完美部署到Jexus.
  2. 三方構架路線: 選擇一樣基於OWIN標準的,非MS的三方構架實現, 目前最有潛力,名氣最大的是NancyFx, Nancy框架目前也一樣能較好的部署到Jexus上去.
  3. 正統vNext路線: 選擇MS正統的下一代ASP.NET 5 (vNext),該版本的底層基於OWIN實現(注意任何老的ASP.NET版本都不是基於OWIN的), 可謂是親兒子; 但目前尚未發佈正式版本,其將來不可預期, 最關鍵的一點是,在Linux上,包括Jexus在內,目前依然沒有完美的基於商業環境的部署服務器環境支持.

就這3個方案而言,我以爲各有利弊: 底層方案須要更多的自行選擇和組裝,可是與任何基於Owin的組件搭配自如; 三方方案面臨生態環境的問題,因爲大部分高端的組件都來自MS,可否真正無縫鏈接須要考驗,自身的生存能力也是問題; 正統方案內容完整,支持強大, 與MS各項技術融合度高,但卻面臨成熟週期問題(時不我待),另外我最不爽的一點是,vNext又一次搞成了鐵索連環船, 連WebApi都和MVC融合了,又給人一種整套推銷的感受, 有違當初Owin體系的初衷;而最根本的問題是,目前尚未任何方案給vNext提供一個Linux上的IIS級服務器,沒有好的載體,僅僅是把vNext的Linux部署定義爲娛樂這個顯然看不出太大的誠意.

 

綜上,我目前仍是傾向於使用底層Owin方案,目前商業化開發路線是: 基於MS Owin實現,根據須要加入各類MS穩定組件,好比Web API 2.2 OWIN 5.2.3, Identity Owin 2.2.1, SignalR OWIN 1.2.2, OAuth 3.0.1,和其餘全部的通用型組件,如EF, Logging, IoC等等; 最終經過Mono和 Jexus架設到Linux環境.

 

下面我建一步演示如何組裝MS Owin和Web API 2.2, 並把它們部署到Jexus上去.

開發環境VS 2013, Window 7或 8; 部署環境Ubuntu 15.

第一步: 創建項目

首先,在VS 2103中創建一個Class Library項目,注意只要Library項目,這裏能夠選擇Framework 4.5.2或者4.5.1. 這個項目假設命名爲OwinExample.

 

而後,咱們加入這個項目必須的組件,根據上面的描述,咱們須要2個組件: MS Owin的核心實現Microsoft Owin和ASP.NET WebApi 2.2 Owin

咱們先加入Microsoft Owin

 

而後加入ASP.NET WebApi 2.2 Owin

 

第二步: 創建Owin入口代碼

首先,Owin的傳統入口類登場:  Startup.cs

using Owin;
using System.Web.Http;
   public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            #region WebApi
            var httpConfig = new HttpConfiguration();
            httpConfig.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{action}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
            //強制設定目前的WebApi返回格式爲json
            httpConfig.Formatters.Remove(httpConfig.Formatters.XmlFormatter);
            //加載WebApi中間件
            app.UseWebApi(httpConfig);
            #endregion
        }
     }

幾個要點:

l  Startup中的Configuration寫成類成員方式,而不是靜態方式,是爲了和Jexus適配器配合,其實差別不大.

l  WebApi的配置寫法和MVC基本相似.

l  Startup和Configuration的命名並非固定的,只是預約俗成而已.

第三步: 創建WebApi代碼

創建DefaultController.cs 爲一個默認的WebApi,裏面包含一個最簡單的Hello函數.

 

   using System.Web.Http;
    [AllowAnonymous]
    public class DefaultController : ApiController
    {
        [HttpGet]
        public string Hello()
        {
            return "Hello Owin!";
        }
    }

 

自此,簡單的MS Owin + WebApi程序架設完畢. 在Owin體系下,咱們發現一切都變得很是簡單和清晰.

第四步: 創建Jexus適配器代碼

爲了把項目部署到Jexus上去,咱們還須要一個很是簡單的適配器類,在項目中加入這個類之後,就能無縫部署到Jexus服務器上去了, 咱們把這個代碼命名爲Adapter.cs:

/**************************************************************************************
 * 加載Microsoft.Owin.dll 進行owin編譯的適配器(插件)示例
 * ==================================================================================
 * 目的:
 *   演示如何將本身的處理方法(中間件)加入到 Microsoft.Owin.dll的處理環節中
 * 
 * 使用方法:
 * 將編譯獲得的dll連同Owin.dll、Microsoft.Owin.dll等文件一併放置到網站的bin文件夾中
 *************************************************************************************/

#region <USINGs>

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Owin.Builder;

#endregion

namespace OwinExample
{
    public class Adapter
    {
        static Func<IDictionary<string, object>, Task> _owinApp;

        /// <summary>
        /// 默認構造函數
        /// </summary>
        public Adapter()
        {
            //建立默認的AppBuilder
            var builder = new AppBuilder();
            
            //建立用戶定義的 Startup類
            //這個類中必須有「Configuration」方法
            var startup = new Startup();

            //調用Configuration方法,把本身的處理函數註冊處處理流程中
            startup.Configuration(builder);

            //生成OWIN「入口」函數
            _owinApp = builder.Build();
        }

        /// <summary>
        /// *** JWS所須要的關鍵函數 ***
        /// <para>每一個請求到來,JWS都把請求打包成字典,經過這個函數交給使用者</para>
        /// </summary>
        /// <param name="env">新請求的環境字典,具體內容參見OWIN標準</param>
        /// <returns>返回一個正在運行或已經完成的任務</returns>
        public Task OwinMain(IDictionary<string, object> env)
        {
            if (_owinApp == null) return null;

            // 將請求交給Microsoft.Owin對這個請求進行處理
            //(你的處理方法已經在本類的構造函數中加入到它的處理序列中了)
            return _owinApp(env);
        }
    }
}

這裏再次感謝Jexus做者宇內流雲提供的代碼, 出於對原做者的敬意這個代碼除了命名空間之外我一個字母也沒有改,其實也不須要改. 其實你們能夠看的出來,這麼變態的註釋應該不是我故意去寫的.

自此咱們的基於MS Owin和WebApi的迷你版應用開發完成,改成Release模式編譯,咱們能夠獲得以下圖所示的一系列DLL:

 

就這些DLL就能造成一個WebApi應用嗎?事實就是如此,並且這個應用能很好的部署到Linux環境上去.

第五步: 安裝Jexus環境

這裏先聲明下,基於我的的能力所限,只能先給出Ubuntu最新版本的一個部署方案,使用其餘版本Linux的兄弟只能麻煩大家自尋門路了.

 

首先,咱們再Ubuntu上面安裝Mono最新版本. 能夠參考下面超鏈文章的指引:

http://www.linuxdot.net/bbsfile-3090

 

而後咱們安裝Jexus最新版本. (一樣請參考下面的超鏈)

http://www.linuxdot.net/bbsfile-3500

 

第六步: 部署到Jexus

部署Jexus網站的常規指導信息,你們能夠移步這裏:

http://www.linuxdot.net/bbsfile-3084

 下面說下咱們的特殊部署步驟 (具體Linux命令我就不列舉了):

  1. 創建網站目錄 /var/www/owinexample, 而後在這個目錄下再創建一個bin目錄.
  2. 經過各類方式把上面本身開發產生的dll拷貝網站目錄的bin目錄下.
  3. 創建Jexus網站的配置文件,假設咱們命名爲 owinexample

其重要內容應該包括如下設置:

 

# For owinexample

 port=88

root=/ /var/www/owinexample

hosts=*    # or  your.com,*.your.com

OwinMain=OwinExample.dll,OwinExample.Adapter

 

特別強調的是OwinMain這個必需配置,而且須要對應正確的DLL文件名和Apdater類. 根據前面的描述,咱們能夠知道咱們應用的配置應該是OwinExample.dll, OwinExample.Adapter.

另外, Web.Config文件和其餘任何文件在這種構架裏面不是必須的.

  1. 重啓 Jexus 服務
  2. 打開你的瀏覽器,輸入 http://linuxserverip:88/api/default/hello 就能夠看到結果.

注意linuxserverip爲部署服務器的IP, 88爲咱們再Jexus配置中設置的端口, api/default/hello對應咱們WebApi的路徑映射,Controller類名和方法名.

 

結束語

最後仍是說下咱們這種模式的優點,劣勢和意義:

優點: 基於Owin底層,簡單明瞭穩定,能夠融合任何基於Owin的相關技術,擴展性強,能夠和Mono, Jexus完美結合,性能最高.

劣勢: 至關於自行組建構架,搭建工做量大, 因爲目前沒有獨立的MVC組件,在MVC開發方面缺少支持(Nancy的一部分MVC構架好比Razor引擎能夠獨立移入,但這個方案有待驗證).

這個方案的最終意義在於,結合目前.NET和Linux方向上最具有穩定性和表明性的MONO, MS Owin和 Jexus, 在ASP.NET vNext最終能完美部署到Linux以前,這是最接近於商業生產環境的方案之一.

 最後拖一句,這個方案的開發環境能夠考慮用TinyFox或者MS Owin Self Host來作宿主. 均可以無縫鏈接,代碼不須要修改.

相關文章
相關標籤/搜索