ASP.NET 開發人員不必擔心 Node 的五大理由

jopen 10年前發布 | 57K 次閱讀 ASP.NET .NET開發

我把我上一篇博文獻給了討論為什么 ASP.NET 開發者需要了解 Node.js 。就像高中辯論賽那樣,因為沒有任何技術抉擇(或者提議)可以憑空存在,我想試試看翻盤,于是我決定從對立面重新想幾個 ASP.NET 開發者應該離 Node 遠點的理由 (最起碼我深思熟慮之后再做決定)。

哦別誤會……我真的很喜歡 Node,而且我覺得它提出的概念和模式將在很長一段時間內,對服務端 Web 編程產生深遠的影響。即使隨著時間的推移 Node 過氣了,我們肯定可以從下一個牛逼玩意身上或多或少的感覺到它的影響(不管好的和/或壞的)。而在這期間,我們中很多人都會選擇它,幸福的在一起,生產。

不過條條大路通羅馬,雖然現在 Node 可能是"當紅炸子雞",不過這不意味著在Web 服務器上沒它不行。每天都有大批的實際有效的產品交貨,用那些巨無聊的老框架,比如說 ASP.NET, Java EE, Rails, PHP(!)還有數不清的各種。好吧,甚至還有些瘋嘿用 COBOL 搭起了 HTTP 服務! COBOL 的 MVC … diao炸了。我給320個贊(不過千萬別讓我去干這事)。  ASP.NET 開發人員不必擔心 Node 的五大理由

對于在這個行業呆了近二十年有點看破紅塵的我來說(攤手),好處就是… Node 提出了一個比較新的有意思的方式來解決那些比較老的無聊的問題。這不是貶低Node。只是說,它不是唯一,昨天不是今天不是明天也不會是。

綜上……如果你是個 ASP.NET 程序員然后辭了職找 Node 的工作,來啊!給我發 email 或者 tweet,讓我知道你能干啥 (要么干脆直接發簡歷……我們有在招聘哦!)。不過你如果還很迷茫,糾結于那些 Node-fanboy-love 的反對言論的話……繼續讀下去。

1. Node最好的功能(異步I/O)在.NET中已經存在了

對Node最大的論據之一:Node通過使用異步非阻塞模型來處理那些潛在的長時間運行的I/O操作。這意味著大多數在你web應用的服務器端運行的工作(數據庫查詢、外部請求web service和其他的網絡資源、訪問文件等等)不會在你處理請求的主線程中發生,可以放心的繼續處理其他對本站的HTTP請求。出于這個目的,Node會維護一個線程池,那些工作將被專門調度給一個可用的線程。你可以定義一個回調函數,當其中一個需要長時間運行的操作完成并返回時,Node將為你調用這個函數。這里有一個使用mongoose.js API來查詢MongoDB的例子。注意回調函數的參數以及調用‘findOne’時缺乏返回值分配。

var query = Kitten.where({ color: 'white' });

// findOne()唯一的參數是一個當findOne()執行完成后被調用的函數 // 回調函數中包括錯誤處理以及查詢結果(可以為null)的處理

query.findOne(function (err, kitten) {   if (err) return handleError(err);   if (kitten) {     console.log(kitten);   } });</pre>

這類“連續傳遞”的編程風格有的時候對缺乏經驗的人來說很難把握,特別是當你的代碼嵌套了很多層的時候。 但對于我們熟悉的順序風格(同步)來說還是有很大優勢的:它為你的執行框架提供了一個自然點來做其他事情,而不是(在這個例子里)等待query.findOne()返回 。對Node來說,總有一些別的東西在處理發來的請求。確實, Node最初的設計目的就是因為典型web服務器端的生產瓶頸就是等待I/O的完成。Node的設計正是根據對這一點的觀察,提供了很多性能的優勢和擴展能力。

這里是對于Node的高級設計的描述:

ASP.NET 開發人員不必擔心 Node 的五大理由

所以如果你正在用Node,這很棒。不過有趣的是你在今天的ASP.NET中也可以使用相同的模式!可能許多人熟悉最初由C#5.0引入的async和await關鍵字。在.NET的web應用中使用它們再配合其他輔助框架比如ASP.NET,Entity Framework等同樣可以取得像Node一樣的非阻塞執行風格。

這里有一個簡單的ASP.NET MVC控制器向Entity Framework進行查詢的實現(這個模式換成Web API同樣可行):

private DataContext db = new DataContext();

// GET: /Employee/ public async Task<ActionResult> Index() {     return View(await db.Employees.ToListAsync()); }

// GET: /Employee/Details/5 public async Task<ActionResult> Details(int? id) {     if (id == null)     {         return new HttpStatusCodeResult(HttpStatusCode.BadRequest);     }

    Employee employee = await db.Employees.FindAsync(id);

    if (employee == null)     {         return HttpNotFound();     }

    return View(employee); }</pre>

有沒有發現每個方法是如何使用async/await來返回Task<ActionResult>而不是ActionResult?這個模式在語義上確保了和Node同樣的連續執行風格。await關鍵字表明了執行暫停的位置(并且當前線程可以先去處理其他請求),此時EF查詢在ASP.NET進程外執行。當EF查詢返回時,另一個線程用于立即恢復位于'await'后面代碼的執行。在ASP.NET中暫停/恢復給了我們如同Node中回調函數般的語義。實現雖然有差異,但基本原理是相同的,寶貴的服務器端資源不能浪費在等待昂貴I/O操作的完成。 

一個警告:Node的支持者會告訴你Node的優勢在于它的設計帶領你直接進入“成功的坑”。異步是Node的默認模式,這對于Node來說非常容易,而同時你也可以在像ASP.NET這樣的框架中使用異步,許多.NET開發者不這么認為,但這無疑是正確的。 雖然Node應用和ASP.NET應用比起來可能會更加“異步”,但不能理解成自身擁有更好的吞吐量或者更好的擴展性。應用的擴展性并不取決于你使用的框架,而在于你的應用本身是否有良好的擴展性。如果你現在在做APS.NET,在你覺得“ASP.NET缺乏擴展性”之前,花一些時間來學習并應用異步模型 。


2. Node簡化的應用模型同樣在.NET中可用

另一個Node帶來的好處是它簡化的編程模型以及自主的步調,你可以了解并選擇一些更強大、更復雜的功能并將其引入。要構建一個“真正”的應用,Node需要掌握比ASP.NET更少的概念,這其實并不一定正確,但它確實給人這種感覺。這是主觀的理解,但許多Node的初學者認為這是正確的。 

與之相比,ASP.NET MVC需要一系列連鎖的概念:HttpApplication、global.asax、web.config、模型、視圖、控制器、路由、行為、束等等。作為一名有經驗的ASP.NET開發者,我們認為理所當然 。但想象一下19歲的人準備著手做web開發,給他選擇到底是進入奇特的global.asax和web.config還是簡單地查找幾行Javascript,Node會受到青睞并不奇怪。每一代人都會無意識地帶著自豪進行挖掘:“昨天我們用一個馬拉的犁和一個干草叉,以及一些進取心,架設了HTTP服務,我們喜歡它!” 并且每一代人都有另外一代的年輕人緊隨其后,轉著它們的眼睛然后向前進,使用新的工具和技術。 

額...但是再一次我們看到ASP.NET學到了一些新招數和進步。在近幾年,微軟致力于對.NET開發者社區定義的OWIN(.NET的開放Web接口)規范的限制。 它的基本思想是從服務器端的基礎設施對.NET的web應用解耦,為.NET的web桟(主機,服務器,中間件和應用)定義一個正式的抽象層,同時也定義了相鄰層之間交互的接口,這增進了多個web主機間的可移植性。它同時也作為Katana項目的基礎,Katana項目是微軟對OWIN的實現,旨在通過傳統的ASP.NET管道、HttpListener、IIS、主機以及其他更多東西來處理HTTP請求。

OWIN和Katana借鑒了Node和其他許多輕量級框架,所以編程模型簡單親切。記得在Node里"hello world"有多簡單嗎?看看Katana:

public class Startup
{
   public void Configuration(IAppBuilder app)
   {
      app.Run(context =>
      {
         context.Response.ContentType = "text/plain";
         return context.Response.WriteAsync("Hello World!");
      });
   }
}

很容易吧!為任何給定的終結點簡單定義行為(上面的代碼使用的簡單行為為這個應用的所有終結點所共用)。注意代碼默認是異步的,就像Node一樣。誰說老狗不能學新招數!

明確地講,上面的代碼在任何Katana主機上都可以運行:IIS,OWIN.exe(一個微軟提供的控制臺host,類似于node.exe),或是你自定義的host實現。可以在多臺主機和服務器端運行同樣的代碼是Katana非常有用的功能,而Node沒有提供。

等等,還有!Katana有一個在常用IIS+ASP.NET服務器基礎設施中的弱點,它依賴于System.Web,它不僅包括ASP.NET管道中的類型(HttpApplication,HttpContext,IHttpModule,IHttpHandler等),它還包括一些Web Forms的編程模型(pages,contorls,view state等)。你真的想把這些都帶到你現代的輕量級Katana應用程序域中?是的,ASP.NET團隊不認為你會使用其中任何一個。 

所以他們創建了Helios項目。Helios是一個雛形項目,旨在具體化使用IIS(利用IIS的安全性、緩存、進程生命周期管理等)host的OWIN應用不需要將System.Web拖入你的應用程序域。 Helios是一個pre-alpha版本,所以我們需要小心比較。然而,相比ASP.NET host的應用,Helios確實證明可以明顯減少請求錢的內存消耗,它預示了.NET的web桟在未來將更加簡潔,更具擴展性。這對于ASP.NET開發者而言是好事,你可以現在著手研究OWIN和Katana。最終,讓ASP.NET團隊知道你需要一個官方完整支持、類似于Helios的應用桟!


3. Node的"到處都是Javascript"很棒!除非它不是 

Node的其中一個論據是在你整個應用桟中你可以只使用Javascript。這確實有很多優勢。 

除非你所在的團隊里沒有專職的的JavaScript程序員。除非你愿意花錢去招聘一些目前市場上高需求的科技人才。或者除非你愿意用JavaScript重寫你的整個應用程序(或者你正從零開始……在這種情況下,你興許沒有重寫的問題,但你肯定有“我到哪可以找到專職JavaScript開發者”這個問題)。

對一個從更傳統的面向對象語言如C#人來說,掌握(或精通JavaScript是件難事。原型繼承非常強大,但也很容易繞住你。變量的范圍“規則”,嗯,也很有趣。強制類型轉換,有時需要,貌似很隨機typeof NaN === ‘number’。相信我,還會遇到更多。沒有什么是不可逾越的,JavaScript的生產力是不僅此而已。像TypeScript這類的東西很有幫助,尤其對從C#轉移到JS。只是不要指望一夜之間就能成功。

這是原因的一部分,對所有時興的技術,Node對企業級來說仍然是新的。當然,一些喜歡嘗鮮的人已使用多年(企業中也有人員在嘗試時髦的應用框架)。但在短期內,如果你在Bigcorp.com上尋找能引入Node的人才,你可能需要付出一些努力。這并不意味著你可以不在乎Node……但要把握實際期望值。

另外,注意到客戶端JavaScript開發與服務器端開發相同卻又截然不同很重要。語言的差別并不那么大(確實不大),但概念和模式只有少量的重疊。你需要的人不僅要了解JavaScript,也要明白網絡延遲、異步、服務器的安全、規模縮放、云測試和部署以及高效的數據訪問,等等。即使是一個優秀的客戶端js開發者也未必完全理解這些。反過來,如果你的公司剛開始做.NET開發,我敢打賭你團隊中也有幾個人知道這些東西。他們也許不了解Node (目前還不),但他們仍有你可以利用的知識。

到這里,我們看到了一方面問題。不管JavaScript和Node目前多火。重要的是它們是否適用于你的具體情況。是的,想一些未來的技術趨勢和“人才市場”走向是很重要的……但你對你掌握的東西有多大的信心?我們可以接受一些培訓來猜測明天……但就是他們所做的,猜測而已。一個全新的區域……C#可能不“酷”了,但它仍不會很快消失。

更多的在下面。所以,如果你喜歡Node那為它而興奮吧,了解下它看看是否適合你和你的團隊。但你要首先專注于今天的需求,適當少關心你將采取的下一個閃光的新東西。當你準備好時它就會出現閃光。

4.如何你的ASP.NET應用程序規模不大但反應緩慢,也許這個問題在于你的設計

這種差異將阻礙你使用Node重寫你的Web應用以修復你當前在ASP.NET的實現中所存在問題。用Node重寫不會有顯著幫助,很可能沒有任何幫助。

這就像在Ye Ole軟件協會中的穆哈咖啡加入印度茶必然會導致溢出一樣。因此轉向Node不會簡單的解決你的問題.....這些問題的根源在于你,而不是微軟。

詢問你自己(坦誠的)適合下列描述的那種:

1.你和你的團隊富有遠見,卓越的軟件工程師將利用時間盡可能識別出ASP.NET中最佳的軟件工程實踐并將他們應用于你的項目。你的設計是 SOLID。你可以對何模塊進行單元測試。你知道你的的代碼測試覆蓋標準,并且你知道他為什么不是100%。你冷靜的分析 Entity Framework,、NHibernate,原生ADO.NET和百萬級 micro-ORMs 框架的優缺點并且基于你項目的限制做出合理的選擇。你經過長時間的艱難思考決定你如何聚集于你客戶端和服務器端應用程序的業務邏輯,考慮接下來的技術、工 具、生產力和性能等等如何影響你的決策。你與合作伙伴勤奮的模擬現實世界的用例和情節,甚至在項目早期設置性能層級和加載測試場景,所以你在那時就擁有關 于性能和規模的圖表。你可以無數次自由的描繪你的應用和數據訪問權限,你也可以修改他們或者去掉那些沒有任何差別的附加功能。管理人員理解這些事情需要時間,然而你需要交出高質量的代碼。

2. 你和你的團隊目光短淺,非理性的“開發者”干著沒有能力勝任的工作并且不顧一切保住工作。 根據定義,你從來沒有讀過關于ASP.NET 最佳實踐的書或者文章(如果你正在讀這篇文章,你可以在Stack Overflow上通過鏈接找到最佳實踐的資料,搜索GDD或者Google-driven development)。 你的設計原則是,“solid”。 曾在你團隊里待過的開發者寫了一些單元測試用例,當一些代碼改變時,你把它們注釋了,這些用例永遠不會再編譯(盡管你的項目經理在給CTO的代碼質量周報中仍然引用這些用例)。 有一次,你從換過三次工作的同事那里聽說實體框架“很爛”,NHibernate“太復雜”,因此你編寫自己的DAL拼裝內存中的SQL語句(通過請求...沒有緩存),并保證你的動態數據庫字段(ExtraColumn1,ExtraColumn2,…ExtraColumn25)都讀取到適當位置,在一個記錄的基礎上(或者…你從另一個同事那里聽說實體框架EF“很棒”,因此整個服務器端架構你采用EF對象圖的操作深層次結構,EF對象圖映射由一個從未見過7張表關聯的“數據庫架構師”設計的兼容第五范式的數據庫)。  你不知道分析器是什么東西。 “SQL執行計劃”對你而言,聽起來像是要進監獄的事情。 你“測試”系統好幾個月了,卻從未嘗試并發用戶請求,你的可擴展性就是“買更多的硬件”。 等等。

3. 介于第 1 和第 2 種情況之間.

老實說, 我們當中很多團隊既不屬于第 1 種也不屬于第 2 種, 而是介于 1 和 2 之間. 這很正常, 這世上沒有完美無缺的項目, 也沒有完美無缺的團隊. 所以, 如果你比較傾向于上面提到的第 1 中情況, 而且在提高 ASP.NET 的性能和擴展性方面, 你已經竭盡所能, 做了你能做的, 結果依然不盡如人意, 那么, 也許是時候改用其他框架了.

只有無能的人才會把自己的過錯推給工具. 自己的程序有問題怨 ASP.NET 這就是現代版的在編譯器中找 bug. 拉不出屎, 別怪茅坑… 問題可能來至你的團隊. 當然, 我不是說 ASP.NET 很完美, 一點問題也沒有 (事實上, ASP.NET 本身也有很多不足). 它不過是個工具, 一個有用的工具, 一個成千上萬的網站每天都在正常使用的工具. 其中一些網站(甚至是大部分的網站), 其復雜程度, 訪問量要比你的高的多. 像這樣一個身經百戰, 被使用多年的框架, 不能滿足你的項目開發需求的可能性, 坦白講, 不大.

基于對“更好”一詞不同的定義,以上幾點并不是說Node比ASP.NET 更好或更糟。 它是說如果你計劃由ASP.NET 轉向Node,這很好,但是不要批評ASP.NET 在性能和可擴展性方面的問題。在“自由地申請更多可擴展性”方面,Node并不是神奇的魔法粉。 Node 只是一個類似于ASP.NET 的工具…使用得當,它的效果很好。 草率地使用并且沒有清楚地理解它的優缺點,就像花了大量的時間和金錢重寫Node,最終會回到原點,就是你今天所處的位置。

我的朋友,這就像一聲相當可悲的低音號


5. 孩子,“微軟正在消亡!/破產!/邪惡!/無聊!/土里土氣!/等等。”絕不可能孕育一個科技戰略

現在,正如你讀到的,由于一點不理性、毫無緣由的討厭微軟,一些在企業級軟件領域工作的人正在由 ASP.NET 轉向 Node。 這些人在他們的組織內部是值得信賴的決策者。 他們對商業上能夠產生很大下游影響(正面或負面)的技術決策負有責任。 當你跳過他們 PPT摘要頁、第一頁或者第二頁查看后面的內容時,站不住腳的理由消失了,他們的說法幾乎可以歸結為“我不喜歡微軟,我不喜歡 ASP.NET,我想做年輕人正在做的比較酷的事情”。

截至2013年12月31日,《金融時報》(FT)全球500強指數中微軟市值排名第四。 在同一季度,微軟收入創紀錄地達到245億美元。 微軟還沒有破產,遠非如此。 微軟Azure充滿活力,它為企業持續遷移到云提供良好的定位,在這一領域,它富有競爭力,而且這一領域我們目前僅僅發展到初期階段。 相對于傳統的Office辦公軟件,Office 365已成為一個可行的基于云計算的替代產品。 和其它公司一樣,微軟持續地大量地投資于研發領域(這怎么會“無聊”呢?)。 微軟“土里土氣”嗎? 如果你基于企業級IT解決方案的定義而問這個問題,你是不是發現自己已經錯了?

不要誤會 … 在一個大的全新的項目開始,有很多理由選擇使用其它產品而非微軟的產品。 前期的許可費用可能難以接受,尤其相比于各種開源的軟件(盡管有 方法減輕那些費用)。 在這一點上,至少微軟一些 核心技術的長期生存能力是不穩定的。 基于 Satya Nadella升職為 CEO及他所有快樂的公開演講,我們仍然不知道他是否有能力利用好微軟 已有的優勢,并解決微軟面臨的問題。

然而,如果你已經投入巨資并顯著地建立了一個技術優勢,拋棄它重新開始通常是一個錯誤。 100年前Joel這樣寫到。 以我的經驗,這通常是一個主觀上的決定,而不是一個客觀上的決定…不管討論哪種技術。

如果你是一個 CTO,面對遺留的 ASP.NET 代碼這座大山,你認為用 Node 重寫將會解決所有的問題,你這在給你的公司、你的董事會、你的客戶幫倒忙。 他們給你工資不是為了讓你在流行技術中換來換去。 他們給你工資也不是為了讓你表達對微軟肥皂劇故事“本周流行哪個技術?”的討厭。“他們給你工資是為了實現商業價值 … 可預見的經濟上的價值,并且產品要有高質量。 當開始做的時候,研發技術的選擇比我們想要別人認可的選擇要少的多。 在一個軟件項目中,大部分可變性是以人為中心。 但是當我們能夠批評自己的缺點時,事情卻變得容易得多,”每個人都知道 ASP.NET 不能形成規模“。

讓我們假設你是一個基于ASP的網絡商店,但是你有點擔心過度依賴單一的供應商。你有什么方案能超越“重寫所有Node”? 首先,你可以標識部分你的架構,它可能得益于各種開源的替代方案,用它們變更盒子中的ASP.NET。對于.NET來說,過去幾年生機勃勃的開源生態系統使得其更加地優雅的重要原因(主要原因?)。整個框架是偉大的,但是你也可以考慮像 Massive或者 Simple.Data那樣的替代方案?也許你的數據訪問策略需要一個改頭換面,使用 NoSQL數據庫MongoDB 或者 RavenDB,您的應用程序會受益?也許,你建立了一個適當的服務層,可以利用新形式,像 responsive UI那樣直接的方式。這些類型的架構更改絕非易事,他們不被認為是輕量級的,但是他們可能需要解決具體的問題,卻面臨著沒有更大的預算去拋掉風險,重新開始。

其次,考慮更多激進的想法,比如在Mono平臺上運行,選擇自己的主機操作系統。 現在ASP.NET和MVC在Mono上運行得相當好。 如果你對云技術感興趣,但是不想使用Azure,你有其它的平臺運行ASP.NET… AWS EC2(亞馬遜可擴展的云托管)虛擬機AWS Elastic Beanstalk (亞馬遜的PaaS服務),小型的云計算空間供應商如AppHarbor,還有最近發布的支持.NET的紅帽OpenShift(云計算服務平臺)

最后,在決定選擇哪個技術和平臺前,確定你已經找到選擇的理由。 除了前面提到的許可費用,還有很多需要考慮的東西。 所有權的總花費并不只有前期費用,也有使用時的費用 … 其中一些費用不容易進行量化。 使用 Node進行重寫,你的團隊能夠按時完成的機會成本是多少? ASP.NET應用開發遇到問題時,你可以 24*7打電話尋求技術支持而不是隨便在一個 Node開發者論壇上尋找答案,這對你而言價值是多少? 你所處的地理區域是前端人才如 Node更多,還是主流技術的專家如 .NET和 Java更多? 找到、吸引、留住優秀的 Node開發者難度是多大? 你是否準備好應對他們可能被挖走的問題? 目前你的團隊很多開發者都掌握了有價值的領域專業知識 … 當你轉向 Node時,你是否計劃繼續保留這些開發者? 如何將專業知識轉化為一門新的技術架構? 如果你計劃不再雇傭他們,你確定你已經準備好看著他們帶著來之不易的領域知識走出公司大門?

這里沒有黑白… 它不像招聘”過時的”開發者:精通過時的技術、對招聘人員也沒有吸引力,這是一個成功的招聘策略。 說句公道話,永遠堅持使用ASP.NET(或其它任何一門技術)也不像是正確的選擇。在你做出由ASP.NET轉向Node重大的決定之前,必須客觀而不是主觀地考慮上面的所有因素。 保持謹慎,保持客觀。

希望我在文章里已經給你了一些思考的東西。 我很喜歡Node,在接下來的幾年我計劃花費更多的時間學習它。 但是我也很喜歡ASP.NET... 鑒于它的功能和未來的規劃。 明智的做法是對兩者都保持關注,不要過早地下決定。

最后,對于不同的場景下選擇哪種語言并沒有一個唯一的答案,但是可以參考一些指導性的原則。 讓我們在下一篇文章中對這些原則進行討論。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!