12/08/2018, 15:09

So sánh giữa Node.js và Golang

Gần đây, đã có những lời chỉ trích về giá trị của việc sử dụng Node.js trong một môi trường ứng dụng mạng hiệu suất cao, và một số nhà phát triển đã chuyển sang ngôn ngữ Go. Ngoài ra cũng có một số tập đoàn lớn chuyển sang sử dụng Go, ngoài tác giả của ngôn ngữ này là Google. Dropbox đã chuyển ...

Gần đây, đã có những lời chỉ trích về giá trị của việc sử dụng Node.js trong một môi trường ứng dụng mạng hiệu suất cao, và một số nhà phát triển đã chuyển sang ngôn ngữ Go.

Ngoài ra cũng có một số tập đoàn lớn chuyển sang sử dụng Go, ngoài tác giả của ngôn ngữ này là Google. Dropbox đã chuyển sang Go, họ tuyên bố rằng hiệu suất tăng lên đáng kể, và các nhà phát triển của hệ thống ảo hóa Docker cũng đang sử dụng Go.

Tuy nhiên, điều quan trọng cần lưu ý là Node.js vẫn đang được sử dụng rộng rãi hơn nhiều, có nhiều module hơn, dễ dàng sử dụng hơn, và nó sẽ chẳng đi đâu cả trong thời gian sắp tới. Ngoài ra, nếu bạn đang làm một ứng dụng web, Node.js có thể là ngôn ngữ mà bạn lựa chọn, còn Go hiện tại được sử dụng nhiều như là một ngôn ngữ kịch bản tập trung ưu tiên vào ứng dụng đồng thời (concurrency) và tốc độ.

Trong bài viết này, chúng ta sẽ có một cái nhìn vào sự khác biệt giữa Node.js và Go từ góc nhìn của nhà phát triển để phát hiện ra những điểm mạnh và điểm yếu của từng môi trường.

Node.js và ngôn ngữ Javascript

Node.js (và một nhánh gần đây của nó, IO.js) là một nền tảng ngày càng phổ biến được xây dựng trên một JavaScript-based runtime rất nhanh: V8.

V8 là một máy ảo JS tạo ra bởi Google được thiết kế để xây dựng các ứng dụng mạng có khả năng mở rộng. Nó biên dịch code JavaScript thành mã máy, bằng cách sử dụng một số tối ưu phức tạp. V8 cũng thực hiện việc cấp phát bộ nhớ và thực hiện công việc của bộ thu dọn rác (garbage collection) của các đối tượng JS.

Mặc dù những tối ưu hóa dynamic của một ngôn ngữ dynamically-typed cung cấp rất nhiều tính linh hoạt cho các nhà phát triển, nhưng chúng cũng phải đánh đổi bằng phí tổn thực thi tại nhiều thời điểm.

Vì Node.js được viết bằng JavaScript, nên nó thừa hưởng hầu hết các tính chất của ngôn ngữ này. JavaScript hiện nay cũng rất phổ biến với chuẩn phát triển ECMAScript đã được thông qua, đó là một sự tiến hóa hay nói đúng hơn là một cuộc cách mạng thực sự.

Có một số nhược điểm quan trọng khi phát triển bằng JavaScript và Node:

  • Một số sai sót trong ngôn ngữ JavaScript là rất khó sửa chữa mà không làm phá vỡ tính tương thích ngược, mặc dù những vấn đề tồi tệ nhất đang được sửa.

  • Các nhược điểm của ngôn ngữ JS có thể không được sửa chữa hoặc chỉ được khắc phục bằng "một bản vá" dạng add-on. Điều này có thể dẫn đến thiết kế của ngôn ngữ này trở nên bừa bộn khi so sánh với những ngôn ngữ có những tính năng tích hợp rõ ràng vào trong thiết kế của nó. Một ví dụ điển hình của việc này đó là tính toán đồng thời (concurrent computing) với JS. JS trở nên tốt nhất cho tính toán đồng thời đến từ một concurrency API (sử dụng các event-based callback), phát triển các promise, để hỗ trợ cho các async generator. Hiện nay callback hell vẫn là một vấn đề nghiêm trọng trong nhiều ứng dụng Node.js; tuy nhiên điều này dẫn đến việc code khó đọc hơn, và có lẽ thậm chí là dính nhiều bug hơn.

Tất cả điều này có nghĩa rằng ngôn ngữ JavaScript phát triển khá chậm (và thậm chí một số người còn nói là quá kém), ngay cả khi những khái niệm từ các ngôn ngữ khác được cho là làm việc tốt hơn.

Node.js vẫn có một cộng đồng lớn và có hàng tấn các ứng dụng tuyệt vời được viết bởi nó, vì vậy chúng tôi không muốn khuyên bạn bỏ nó đi chỉ bởi vì một số nhược điểm trong những trường hợp nhỏ; theo như đại đa số các nhà phát triển thì nó vẫn là một nền tảng tuyệt vời để làm việc.

Ngôn ngữ Go hoặc Golang

Go, hay còn được gọi là "Golang", là một ngôn ngữ lập trình biên dịch hướng hệ thống (systems-oriented) được bắt đầu bởi Google vào năm 2007. Go có thể được xem như là kết quả của một quá trình tiến hóa ngôn ngữ khá thận trọng từ các ngôn ngữ như C và C++.

Go cải tiến một số nhược điểm của những ngôn ngữ này như:

  • quản lý dependency kém
  • các hệ thống kiểu cồng kềnh
  • khó quản lý bộ nhớ
  • thiếu sự hỗ trợ tính toán song song
  • thiếu sự hỗ trợ multi-core

Go cũng làm giảm số lượng code cần phải viết bằng cách trở nên sáng sủa hơn C hoặc C++.

Go làm cho nó dễ dàng hơn khi viết các ứng dụng mạng mạnh mẽ, mà không cần phải đánh đổi nhiều trong cách thực thi, khi so sánh với C hoặc C++. Hiệu suất cao một phần lớn là nhờ việc biên dịch tĩnh của code Go kiểu statically-typed. Rất nhiều tối ưu hóa có thể được thực hiện khi một trình biên dịch làm tất cả công việc kiểm tra mã trước đó, trái ngược với trình biên dịch dynamic của JS thực hiện ở lúc runtime.

So sánh các tính năng giữa Golang vs Node.js

Chúng ta bắt đầu nhìn thấy lý do tại sao, đối với một số loại phát triển ứng dụng thì việc sử dụng Go sẽ có ích hơn Node.js; tuy nhiên Node.js vẫn là một ngôn ngữ rất hữu ích trong nhiều trường hợp sử dụng.

Hãy so sánh những điểm mạnh và điểm yếu của các ngôn ngữ lập trình này, vì nó có thể làm cho bạn dễ dàng hơn khi chọn lựa môi trường nào là công cụ thích hợp cho dự án tiếp theo của bạn.

Go Node.js
Mức độ trưởng thành Trưởng thành và mạnh mẽ so với tuổi của nó Trưởng thành, nhưng API vẫn còn hơi thay đổi. Những thay đổi gần đây của nhánh IO.js cũng có thể trở thành một nguyên nhân cho các vấn đề API đối với các lập trình viên đang viết và sử dụng các module Node. Mức độ nghiêm trọng của vấn đề này vẫn chưa rõ ràng ngay bây giờ.
Hiệu suất Có hiệu suất tương tự như là C hoặc C++, điều này có thể nói là rất tốt Do tính chất dynamically-typed tự nhiên của JS, Node không thể đạt đến hiệu suất tối đa của CPU hoặc bộ nhớ trong các tác vụ mà Go có thể thu được trong nhiều thử nghiệm. Tuy nhiên, trong các trường hợp sử dụng thông thường, nơi liên quan đến giao tiếp mạng hoặc tương tác cơ sở dữ liệu thì hiệu suất của Node và Go thường bằng nhau.
Tính toán đồng thời (Concurrency) Go sử dụng các coroutine gọi là goroutines. Một goroutine là một lightweight thread được quản lý bởi Go runtime. Truyền thông giữa các goroutine được thực hiện rất gọn gàng sử dụng các channel. Node hỗ trợ concurrency ít gọn gàng hơn thông qua sử dụng cơ chế event-callback. Tuy nhiên, đối với rất nhiều ứng dụng, làm việc với các JS promise và sắp tới hỗ trợ async generator (còn được gọi là "semi-coroutines") cũng đã đủ xài. Một cái gì đó kiểu như Koa framework cũng đã hỗ trợ hướng tiếp cận async generator trong Node.
Khả năng mở rộng Go đã thực sự được thiết kế cho khả năng mở rộng và đồng thời (concurrency), mà không có quá nhiều rắc rối. Một số cá nhân và công ty sử dụng Node.js đã khẳng định rằng Node có một số vấn đề trong các môi trường mà cần mở rộng ở quy mô lớn. Có lẽ Node có thể khắc phục vấn đề mở rộng này trong thời gian tới.
Dễ phát triển Những người đến từ một nền tảng JS/Node sẽ cần phải tìm hiểu một số khái niệm lập trình mới như: coroutines, channels, strict typing (với biên dịch), interfaces, structs, pointers, và một số khác biệt khác. Đối với một nhà phát triển JS, thì tham gia vào lập trình Node là việc rất dễ dàng.
Frontend & Backend Mặc dù bạn có thể chạy code Go trong trình duyệt bằng cách sử dụng gopherjs, nhưng JS vẫn là cách mà hầu hết các nhà phát triển thích lập trình cho frontend. Go nhắm nhiều hơn vào phần backend, đặc biệt là cho việc phát triển các dịch vụ đồng thời có hiệu suất cao ở phía server. Không có gì phải suy nghĩ trong một ngữ cảnh phát triển một hệ thống client-server dựa trên JS vì nó thực sự tốt.
Packages & Tooling Số lượng của các Go package chuẩn phát triển một cách ổn định, hiện tại có trên 100 cái, và các Go community package có thể được tìm thấy một cách dễ dàng. Mặc dù không có nhiều ứng dụng framework khác nhau, thân thiện với các nhà phát triển để lựa chọn như Node, bạn có thể tìm kiếm các package từ cộng đồng Go, hiện tại đang có trên 58.000 package để sử dụng và phát triển. Số lượng các Node package hiện tại có nhiều hơn 100.000. Điều này có nghĩa là có rất nhiều nền tảng đã được xây dựng, và nó có thể làm cho các dự án phần mềm chắc chắn sẽ dễ dàng hơn và/hoặc rẻ hơn khi thực hiện. Các công cụ của Node cũng rất là tuyệt vời. Trình quản lý gói npm đã học được từ tất cả những trình quản lý gói đi trước và làm hầu hết những việc đúng đắn.
Cộng đồng (Developer Mindshare) Một nghiên cứu gần đây cho thấy sự tăng hạng của Go tới vị trí trong top 20. Bước tiến này xảy ra vượt quá cả sự mong đợi. Go chắc chắn đã có rất nhiều động lực để phát triển, đặc biệt là với sự hỗ trợ gần đây của hệ điều hành di động Android. Node phổ biến hơn tại thời điểm này bởi nhiều đơn đặt hàng lớn. Có sự hỗ trợ của các hosting rất tốt, hỗ trợ thương mại, và các freelancer Node.js cho dự án của bạn tại thời điểm này.
Quản lý lỗi (Error Handling) Quản lý lỗi trong Golang đòi hỏi bạn phải thực hiện kiểm tra lỗi rõ ràng, có thể khiến cho việc xử lý lỗi trở nên khó khăn. Tuy nhiên, một số người cho rằng bạn sẽ có được một ứng dụng về tổng thể là sạch hơn, một khi bạn đã hiểu được cách quản lý lỗi trong Golang. Quản lý lỗi trong Node.js có thể không nhất quán trong nhiều trường hợp, nhưng nó cung cấp nhiều cơ chế throw/catch phổ biến hơn cho các lỗi mà các nhà phát triển đang quen sử dụng với những ngôn ngữ khác.

Tổng kết so sánh giữa Node.js vs Golang

Việc lựa chọn giữa Node.js hoặc Go phụ thuộc rất nhiều vào loại phát triển phù hợp với bạn nhất và độ lớn của ứng dụng cần phải mở rộng.

Go chưa có được tất cả các community package hoặc cộng đồng mà Node có, nhưng cú pháp của nó rõ ràng hơn với mô hình concurrency, sử dụng tối đa hiệu suất của CPU và bộ nhớ, và khả năng mở rộng quy mô của nó tốt hơn với tải đồng thời (concurrent loads) có thể khiến nó trở thành một nền tảng tốt hơn cho các loại ứng dụng mạng nhất định.

Nếu bạn cần chắc chắn một số package Node.js mà vẫn chưa có sẵn trong Go, và sẽ khó hoặc tốn kém để viết lại trong Go, thì Node có thể là sự lựa chọn khôn ngoan hơn.

Tham khảo : hostingadvice.com

0