So sánh nodejs và asp net

Chào các bạn, đầu tiên TEDU xin gửi tới các bạn và gia đình một năm mới Mậu Tuất thật nhiều sức khoẻ và niềm vui. Để mở đầu năm mới mình viết một vài dòng chia sẻ cho các bạn đang còn băn khoăn năm nay chúng ta sẽ bắt đầu học gì, học từ đâu và đi về đâu?

Trong ngành lập trình nói chung và lập trình web nói riêng, có rất nhiều các dòng công nghệ cũng như là lộ trình nghề nghiệp cho các bạn. Hiện nay nếu theo lập trình web bạn có thể đi theo một số hướng chính như sau: .NET, Java, NodeJS...Mỗi một nhánh nó lại có ưu nhược điểm về công nghệ riêng nhưng các bạn cũng cần tìm hiểu về nhu cầu thị trường và công việc và sở thích của mình.

Nhưng có một điểm chung là các bạn muốn làm lập trình web tốt bạn phải học tốt tiếng Anh, HTML, CSS và JavaScript căn bản. Sau đó học đến các design pattern, kiến thức căn bản về lập trình và tư duy phân tích thiết kế.

Như liệt kê ở trên thì bạn có thể đi theo một trong số các con đường sau đây:

  1. Java Web Developer: Đây là hướng lập trình web sử dụng ngôn ngữ Java, nó cũng có các framework đi kèm như Spring MVC là tiêu biểu. Java Developer sẽ có cơ hội lương cao và ít cạnh tranh hơn vì số người làm Java ở Việt nam vẫn ít hơn các dòng công nghệ khác. Ngược lại thì cũng có hạn chế là ít lựa chọn công việc hơn. Với Java bạn có thể tham gia vào các dự án lớn của doanh nghiệp như ngân hàng, chứng khoán....Một điểm nữa là Java ít thay đổi công nghệ nên các bạn sẽ ít phải cập nhật (đây cũng không rõ là ưu hay nhược điểm nữa).
  2. .NET Developer: Với .NET Developer thì bạn có nhiều sự lựa chọn công việc vì các job về .NET ở Việt Nam tương đối nhiều. Hơn nữa MS vừa ra bản ASP.NET Core open source nên lượng doanh nghiệp sang sử dụng ASP.NET Core ngày càng nhiều. Với .NET bạn cần học SQL Server, ASP.NET Core và Entity Framework. Các bạn có thể không cần dùng đến bản ASP.NET MVC cũ nữa vì ASP.NET Core đang ngày càng hoàn thiện hơn. Đối với các sản phẩm phát triển lâu dài thì nên sử dụng .NET Core từ giờ vì tốc độ và tiện ích của nó theo mình hơn hẳn bản cũ. Có một điểm yếu là các package của ASP.NET Core chưa đầy đủ như trên .NET Framework nên có nhiều dự án vẫn phải include cả nền .NET Framework vào. Tương lai chắc chắn điều này sẽ được khắc phục. Được đánh giá rất cao về tốc độ và chạy đa nền tảng thì .NET Core cũng có tương lai rất tươi sáng. Đây cũng là hướng mình nghĩ các bạn nên cân nhắc.
  3. PHP Developer: PHP là một ngôn ngữ thông dịch rất phổ biến trong lập trình web với cộng đồng rất mạnh. Bản thân mình thấy PHP dễ học, có nhiều thư viện hỗ trợ làm việc với Web rất mạnh. Hơn nữa nhu cầu tìm người với PHP Developer cũng rất lớn.
  4. NodeJS Developer: Đây là một framework mới viết trên nền V8 Engine của Google. Ngôn ngữ chính của nó là JavaScript nên các bạn có cơ hội trở thành một Full Stack JS Developer từ backend đến frontend đều sử dụng 1 ngôn ngữ duy nhất là JavaScript. Đây cũng là một xu hướng của tương lai. Điểm mạnh nhất của NodeJS là hệ sinh thái rất mạnh với nhiều module hỗ trợ giúp phát triển ứng dụng nhanh chóng, tốc độ đáp ứng cho người dùng và khả năng mở rộng cũng rất cao. Đây cũng là một lựa chọn cho các bạn mới bước vào lập trình web. Các bạn chỉ cần thành thạo JavaScript thì học rất nhanh.

Tóm lại, bản thân mình nghĩ rằng mỗi hướng đều có cái lợi riêng, các bạn theo hướng nào cũng ok miễn là phải làm tốt thì vẫn thành công được. Và một điều nữa là các bạn học gì cũng sẽ phải dính đến JavaScript, mình thì thích theo ASP.NET Core nhưng biết NodeJS để có thể lựa chọn tuỳ theo ứng dụng và nhiều dự án phải kết hợp nhiều loại công nghệ khác nhau. Với .NET hay JAVA hoặc PHP với mô hình giống nhau nên mình quyết định làm thêm với NodeJS vì thấy có nhiều module hỗ trợ hơn nữa nhiều framework mã nguồn mở dùng NodeJS khá nhiều. Mình muốn nhắn nhủ các bạn thêm là khi mình chắc chắn một thứ rồi sang học cái thứ 2 sẽ rất nhanh nên các bạn nên tìm hướng chủ đạo của mình trước khi học cái thứ 2 nhé.

Chúc các bạn thành công.

Tác giả: Bạch Ngọc Toàn

Chú ý: Tất cả các bài viết trên TEDU.COM.VN đều thuộc bản quyền TEDU, yêu cầu dẫn nguồn khi trích lại trên website khác.

(Rất tiếc là mình ko đưa code cũng như hình ảnh minh hoạ vào đây vì hạn chế status của FB, có lẽ hẹn anh em 1 bài blog sau).

— NodeJS bá đạo như vậy, nhưng các bạn vẫn luôn cần lựa chọn một cách khôn ngoan, và các bạn cần biết NodeJS phù hợp nhất với những ứng dụng gì.

Câu trả lời đơn giản là: Viết các chương trình JS để giao tiếp với networks, file systems, hay các I/O resources khác (như input/output, reading/writing). Chỉ vậy thôi, mục đích của NodeJS chính là 1 I/O platform giúp bạn xây dựng được những ứng dụng đòi hỏi tốc độ nhanh và xử lý được lượng connection lớn. Ở những mức thấp hơn là những network programs sử dụng HTTP, TCP, UDP, DNS, SSL, các chương trình đọc viết dữ liệu tới file hệ thống hay bộ nhớ cục bộ…

Một vài ví dụ: Websockets, HTTP + JSON, Files (image resizer, video editor, internet radio), caching proxy, Facebook/Twitter API, RedisDB, MongoDB, CouchDB…

Và, quan trọng không kém, đừng hiểu lầm Nodejs là 1 trong những thứ sau: 1. A web framework (đếch giống Rails hay Django hay Laravel…đâu nhé). 2. A programming language (nó dùng Javascript, Node ko có ngôn ngữ riêng).

Tuy bây giờ với sức mạnh của Express và nhiều module khác NodeJS có thể làm được “mọi thứ” mà một web framework khác được (như 1 CRUD web app chả hạn), cá nhân mình cho rằng nhưng ứng dụng nặng về CRUD thì cứ Rails hay Django hay Laravel mà phang cho nhanh!

Có rất nhiều điều để nói về bài viết này nhưng kết luận đầu tiên của mình là nó không giúp cho người đọc “hiểu hơn”, mà khiến cho người đọc “hiểu sai”. Tác giả đề cập đến khá nhiều khái niệm, Process, Thread-Thread pool, nonblocking, performance… tuy nhiên hầu hết kiến thức đưa ra đều nhầm lẫn hoặc sai lệch, khiến cho kết luận cũng sai theo.

Trong bài viết dưới đây, mình sẽ đề cập đến vài vấn đề được nêu ra trong post nói trên, vừa nhằm mục đích phản biện, vừa nhằm phổ biến kiến thức.

Lưu ý: bài viết này nhằm mục đích phản biện khoa học chứ không nhắm đến bất cứ cá nhân hay cộng đồng nào. Nếu bạn là người không chịu được chỉ trích thì tốt nhất không nên đọc

Thứ nhất, trong bài, người viết có đề cập đến việc “Nodejs nhanh”, và đưa 2 lý do chủ yếu:

1. Nodejs sử dụng Single-thread và event loop(asynchronous I/O).

2. Nodejs sử dụng Javascript engine v8 của Google.

Trong bài viết mình sẽ lần lượt bàn đến các vấn đề:

1. Nodejs có thực sự “nhanh”

2. Single threaded, async i/o đóng góp thế nào trong performance.

1. Nodejs chạy nhanh?

Đây là một kết luận “bí hiểm” mà rất nhiều lập trình viên Nodejs mặc định cho là đúng. Trước hết, “nhanh” là một khái niệm mang tính so sánh, chúng ta cần phải hiểu xem Nodejs “nhanh” so với những công nghệ nào tương đương?

Đây là một kết luận “bí hiểm” mà rất nhiều lập trình viên Nodejs mặc định cho là đúng. Trước hết, “nhanh” là một khái niệm mang tính so sánh, chúng ta cần phải hiểu xem Nodejs “nhanh” so với những công nghệ nào?

Trên thực tế khi đem so sánh với những framework, platform khác, nodejs HOÀN TOÀN không nhanh (như bạn có thể vẫn nghĩ). Tất nhiên, khi chúng ra nói đến performance, không thể chỉ dựa vào võ đoán mà cần có số liệu đo đạc cụ thể. Khi đo đạc, chúng ta cũng cần xác định cụ thể xem mình đang đo đạc những gì, và số liệu đo được có cho chúng ta ý nghĩ thực sự hay không.

Có 2 thứ mà chúng ta có thể đo ở đây

  1. Xét về hiệu năng tính toán và xử lý (những tác vụ cần làm việc nhiều với CPU và RAM), Nodejs thua kém hoàn toàn so với các ngôn ngữ được biên soạn (như Java, .NET, Go…). Bạn có thể tham khảo qua bài test CombSort:

Đối với các bạn lười đọc, kết quả tóm tắt là:

* C++ (G++ 4.9.2): CPU: 0.05s Real: 0.12s RAM: 19428KB

* PHP 5.6.4: CPU: 102.69s Real: 104.20s RAM: 2497508KB

* Ruby 2.2.0 : CPU: 52.87s Real: 53.02s RAM: 87892KB

* Node 0.10.35: CPU: 2.64s Real: 2.64s RAM: 92240KB

* Go 1.4.1 : CPU: 0.14s Real: 0.17s RAM: 31568KB

* Java 1.7: CPU: 1.05s Real: 0.73s RAM: 65952KB

* Python 3.4.2: CPU: 90.47s Real: 90.83s RAM: 403192KB

* C# Mono: CPU: 0.44s Real: 0.47s RAM: 45908KB

Các bạn có thể thấy Nodejs có hiệu năng tỏ ra tương đối vượt trội so với các nền tảng sử dụng interpreter khác ( như PHP, Ruby, Python…) tuy nhiên thua kém so với các ngôn ngữ được biên soạn (Go, C#, Java). Dĩ nhiên ở đây C++ vẫn cho thấy hiệu năng cao nhất. Lý do sẽ được giải thích trong phần 2.

  1. Xét về khả năng xử lý I/O (các tác vụ liên quan đến truy xuất dữ liệu từ đĩa, networking…), vốn là điều mà Nodejs tỏ ra khá tự hào về hiệu năng ( dựa trên khái niệm non-blocking I/O mà nhiều người vẫn hiểu lầm), Nodejs cũng không thực sự được xếp hạng cao. Mình sẽ làm thử một bài benchmark để đo khả năng xử lý http request (ứng dụng I/O có thể nói là cơ bản và phổ biến nhất) của Nodejs so với .NET. ( Bạn có thể tiến hành bài đo tương tự với các http framework mà bạn muốn)

Để đo đạc mình sẽ sử dụng Wrk, công cụ benchmark webserver vốn được dùng rất phổ biến. Nodejs server được viết như sau:

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

var http \= require('http'); var fs \= require('fs'); var cluster \= require('cluster'); var numCPUs \= require('os').cpus().length; const message \= "Hello world!"; const contentType \= "text/plain"; if (cluster.isMaster) { // Fork workers. for (var i \= 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', function (worker, code, signal) { console.log('worker ' + worker.process.pid + ' died'); }); } else { http.createServer(function (request, response) { response.writeHead(200, { 'Content-Type': contentType }); response.end(message); }).listen(5000, '127.0.0.1'); } console.log('Server running at ;)

Trong webserver này, Nodejs sẽ tạo ra một cluster bao gồm 1 số các process con trùng với số nhân CPU của bạn. Mục đích là để Nodejs có thể tận dụng hết được các nhân CPU (do mặc định Nodejs chỉ có thể hoạt động trên 1 thread).

.NET webserver được viết như sau:

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

using System; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; namespace ConsoleApplication { public static class Program { const string Message \= "Hello world!"; const string ContentType \= "text/plain"; public static void Main(String[] args) { var host \= new WebHostBuilder() .UseKestrel() .UseUrls("http://*:5000") .Configure(app \=> { app.Use(d \=> async c \=> { c.Response.Headers["Content-Type"] \= ContentType; await c.Response.WriteAsync(Message); }); }) .Build(); host.Run(); } } }

Webserver được sử dụng trong benchmark này là Kestrel được viết bằng C#. Điều thú vị ở bài test này là Kestrel và httpServer của Nodejs sử dụng chung một thư viện networking có tên là libuv. Điều này sẽ cho chúng ta sự so sánh chính xác hơn về hiệu năng giữa 2 platform.

Bạn có thể thấy là bài đo của chúng ta khá đơn giản, webserver chỉ trả về “Hello world” mà thôi. Mục đích của bài đo này là kiểm tra khả năng xử lý nhiều request, do đó chúng ta chỉ nên tập trung vào tình huống đơn giản nhất

Cấu hình máy:

– CPU: Intel Core i5 – 6600 3.30GHz x 4

– RAM: 8GB

– OS: Ubuntu 16.04 x64

Câu lệnh mà mình thưc hiện đo là:

./wrk -t4 -c100 -d20s http://localhost:5000/

Câu lệnh này sẽ gửi liên tục các request đến webserver trong khoảng thời gian 20s (-d20s), sử dụng 4 threads (-t4) và giữ tối đa là 100 connections (-c100). Kết quả như sau:

Kestrel, .NET Core 1.0.0 : 291747 request/ giây

So sánh nodejs và asp net

httpServer, Nodejs 6.3.1: 104796 request/ giây

So sánh nodejs và asp net

Bạn có thể thấy rằng .NET xử lý được lượng request gấp hơn 2.5 lần so với Nodejs.

Nếu như bạn vẫn chưa thoả mãn với những phép đo này thì bạn có thể tham khảo những phép đo có hệ thống hơn tại benchmark. Nếu như trước giờ bạn là một trong số những người cho rằng “Nodejs cực kì nhanh”, bạn có thể sẽ ngạc nhiên với xếp hạng của Node ở trong những bài đo này

Nhầm lẫn 1: Nodejs nhanh do chạy bởi engine Google V8

Vậy tại sao Nodejs không nhanh (như bạn tưởng)?Trở lại bài viết phía đầu bài khi người viết cho rằng V8 là một trong những lý do khiến Nodejs nhanh (V8 là javascript engine của Google chrome). Bỏ qua việc V8 chưa hẳn đã là Engine javascript nhanh nhất, có một điều chúng ta phải công nhận là v8 là một engine JS có hiệu năng tốt. Tuy nhiên một Engine Javascript tốt thì vẫn chỉ là 1 engine javascript, và hiệu năng của nó luôn bị giới hạn bởi đặc trưng của ngôn ngữ. Một ví dụ đơn giản nhất là cách javascript lưu trữ dữ liệu trong các object. Trong javascript, mỗi object lưu và đọc dữ liệu của mình bằng một bảng “Hash” chứ không lưu trực tiếp giá trị như Java, hay C#. Bạn hoàn toàn có thể làm một phép thử đơn giản:

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

var person \= { name: "Foo", age: 30 }; console.log(person.name \=== person["name"]); //true console.log(person.age \=== person["age"]); //true

Điều này có nghĩa là mỗi lần lưu (hay đọc) dữ liệu từ object, thay vì truy cập trực tiếp, Javascript phải tiến hành “hash” tên của trường cần truy cập. Cách lưu dữ liệu này rất phổ biến trong các ngôn ngữ sử dụng dynamic typing (Python, Ruby…), và Google v8 thực sự cho thấy hiệu năng vượt trội ( như chúng ta thấy trong bài test CombSort ở phần 1). Tuy nhiên, so với các ngôn ngữ sử dụng static typings (Java, C#, Go…) thì javascript khó có thể so bằng được. (lưu ý: mình nói khó, không phải “không thể”)

Nhầm lẫn 2: Nodejs chạy nhanh do có Single-threaded, Non-blocking I/O, Event loop … blah blah…

Để hiểu được Event loop hay Non-blocking I/O là cả một chủ đề dài (mà mình hy vọng sẽ có dịp viết về nó). Tuy nhiên có hai điều mình muốn chỉ ra từ bài viết trên:

– Cho rằng Non-blocking i/o là lý do khiến Nodejs nhanh là hoàn toàn sai lầm. Lý do? Non blocking i/o là thứ có trên hầu hết(nếu như không muốn nói là tất cả) các platform/ framework hiện đại. Những ứng dụng Java sử dụng Future interface, .NET với TPL (Task parralel library), hay Python sử dụng IO loop (như trong Tornado framework) đều có thể thực hiện Non-blocking I/O như Nodejs. Trên thực tế, nếu bạn là lập trình viên .NET sử dụng TPL với async/await, bạn có thể viết các ứng dụng non-blocking mà không cần phải “callback” như trong nodejs. Async/await cũng đang là tính năng được dự trù trong ES7.Đối với Nodejs, sự khác biệt duy nhất là nonblocking i/o trở thành ý tưởng chủ đạo trong việc lập trình.

– Cho rằng việc sử dụng Thread-pool là “lãng phí tài nguyên” và hệ điều hành phải “nai lưng” ra quản lý thread chứng tỏ tác giả không có hiểu biết thực sự về thread pool. Thread pool là một dạng “Cache” để lưu trữ các thread đã qua sử dụng. Trong mô hình Thread pool, bạn trả những thread đã sử dụng xong về Threadpool, để Thread đó có thể được tái sử dụng mà không mất công tạo lại từ đầu. Đây là một kĩ thuật giúp cho việc sử dụng nhiều thread trở nên hiệu quả mà không gây nên gánh nặng cho hệ điều hành. Trong benchmark tại phần 1, Kestrel cũng sử dụng Thread pool và chúng ta có thể thấy kết quả tương đối rõ ràng.

Nếu Nodejs không nhanh (như bạn tưởng), vậy bạn có nên đầu tư sử dụng nó hay không

Từ trước đến giờ, performance luôn là chủ đề gây tranh cãi. Benchmark chỉ là benchmark và nó cũng chỉ phản ánh được 1 khía cạnh mà thôi. Hầu hết những framework/platform hiện đại đều đáp ứng được về vấn đề hiệu năng và những sự khác biệt (nếu có) đều có thể được lấp đầy bằng cách nâng cấp phần cứng. Vậy nên theo mình, khi lựa chọn 1 platform/framework để đầu tư, chúng ta cần xem xét 2 yếu tố:

1. Nó có giúp bạn đạt được mục đích hay không.

2. Bạn có thông thạo/thoải mái khi sử dụng nó hay không.

Điều quan trọng nhất là người sử dụng một công nghệ nào đó cần có hiểu biết và khái niệm đúng về những gì bạn đang làm. Performance của ứng dụng của bạn sẽ phụ thuộc nhiều vào cách bạn tổ chức, thiết kế hệ thống của mình, và bạn nên dành nhiều thời gian cho việc đó. Điều cuối cùng là khi nói đến hiệu năng, đừng bao giờ chỉ nói mồm, mà hãy đo đạc cụ thể.