10 điều không nên làm khi chạy ứng dụng Node.js

Ở Hashnode, phần lớn chúng tôi thường sử dụng Node.js. Cá nhân tôi là một fan lớn của Node.js và đã học được rất nhiều điều trong thời gian điều hành Hashnode. Khi tiếp xúc với các lập trình viên khác, tôi nhận ra rằng nhiều người trong số họ chưa biết tận dụng tối đa Node và thực hiện một số điều nhất định theo các cách sai lầm. Do đó, bài viết này sẽ nói cho bạn biết về những điều không nên làm khi chạy một ứng dụng Node trong thực tế. Hãy bắt đầu cùng Quản Trị Mạng điểm danh 10 điều bạn không nên làm khi chạy ứng dụng Node.js nhé!

10 điều không nên làm khi chạy ứng dụng Node.js

1. Không sử dụng Node.js Cluster

Node.js là một luồng duy nhất trong tự nhiên và giới hạn bộ nhớ 1.5GB. Vì thế, nó không thể tự động tận dụng nhiều lõi CPU. Nhưng tin tốt là Cluster module cho phép bạn tạo nhiều tiến trình con (fork) sử dụng IPC để giao tiếp với tiến trình mẹ. Quy trình tổng thể kiểm soát các nhân viên (hay còn gọi là tiến trình con) và tất cả các kết nối được phân phối theo kiểu luân chuyển vòng robin (round-robin).

Không sử dụng Node.js Cluster

Clustering nâng cao hiệu suất ứng dụng cho phép bạn giảm thời gian dừng khi triển khai xuống 0 một cách dễ dàng. Bên cạnh đó, số lượng tiến trình con có thể được tạo ra mà không bị giới hạn bởi số lõi CPU của máy.

Cá nhân tôi - tác giả bài viết, nhận thấy clustering là một việc phải làm đối với bất kỳ ứng dụng Node.js nào chạy trong thực tế và không có lý do gì không áp dụng nó.

2. Xử lý các tác vụ nặng trên Web Server

Xử lý các tác vụ nặng trên Web Server

Node/Express server không phù hợp để xử lý các tác vụ nặng và yêu cầu tính toán nhiều. Ví dụ, một ứng dụng web đơn giản cần gửi một loạt email cho người dùng. Mặc dù bạn có thể thực hiện công việc này trong Node.js web server nhưng nó sẽ ảnh hưởng đáng kể tới hiệu suất hoạt động. Tốt hơn nên tách các tác vụ nặng kiểu này thành những kiến trúc micro services (kiến trúc nhiều dịch vụ nhỏ) và triển khai chúng thành các ứng dụng Node riêng biệt. Hơn nữa, bạn có thể sử dụng message queue (mô hình giao tiếp truyền tin bất động bộ, trao đổi giữa người gửi và người nhận không xảy ra đồng thời tại cùng 1 thời điểm) như RabbitMQ để giao tiếp giữa các kiến trúc micro services.

Khi bạn đăng bài trên Hashnode và gắn nó với các từ khóa, chúng tôi chèn bài viết vào nguồn cấp dữ liệu của hàng nghìn người dùng. Đây là một tác vụ nặng. Chỉ vài tháng trước, công việc chèn bài viết vào trang tin tức vẫn được thực hiện bởi chính web server. Khi lưu lượng vào trang web tăng lên, chúng tôi nhận thấy sự kìm hãm phát triển xuất hiện và tắc nghẽn xảy ra. Sau đó, nếu bạn đăng một bài viết và gắn từ khóa "General Programming" hay "JavaScript" thì cả trang web sẽ bị đơ vài giây. Khi tìm hiểu kỹ càng, vấn đề nằm ở tác vụ đẩy bài viết vào trang tin tức của người dùng. Giải pháp chính là chuyển toàn bộ môđun xử lý tác vụ đó sang một máy khác và bắt đầu tác vụ này qua message queue.

Vì vậy, điều quan trọng chúng ta nên nhớ là Node.js phù hợp khi xử lý các sự kiện và non-blocking I/O. Bất cứ tác vụ nào cũng có thể gây tốn thời gian hoàn thành nên được xử lý bởi một tiến trình riêng biệt.

3. Không sử dụng công cụ quản lý tiến trình

Rõ ràng công cụ quản lý tiến trình mang lại nhiều lợi ích nhưng đa phần các lập trình viên lần đầu triển khai ứng dụng của họ trên thực tế không sử dụng nó. Ở Hashnode, chúng tôi sử dụng pm2, một công cụ quản lý mạnh cho ứng dụng Node.js.

Hơn nữa, nếu sử dụng pm2 bạn có thể dễ dàng bắt đầu chạy ứng dụng của mình trong chế độ cluster.

pm2 start app.js -i 2

Trong câu lệnh ở ví dụ trên, i là số lượng tiến trình con mà ta muốn tạo trong chế độ cluster. Điều tuyệt vời nhất chính là bạn có thể chạy lại lần lượt từng tiến trình con mà không làm ảnh hưởng đến nhau. Vì thế, ứng dụng không phải lãng phí khoảng thời gian chết khi triển khai. Lệnh dưới đây sẽ chạy lại ứng dụng:

pm2 reload app

Nếu bạn sử dụng pm2, hãy tham khảo Keymetrics, một dịch vụ giám sát ứng dụng Node.js (dựa trên pm2).

4. Không sử dụng reverse proxy

Không sử dụng reverse proxy

Tôi đã thấy các lập trình viên chạy ứng dụng Node trên cổng 80 và cung cấp tài nguyên tĩnh thẳng qua cổng này. Bạn nên nhớ rằng chạy ứng dụng Node trên cổng 80 không phải là ý tưởng hay và thực tế nó nguy hiểm trong phần lớn các trường hợp. Thay vào đó, bạn nên chạy trên một cổng khác như cổng 3000 và sử dụng nginx (hay cái gì đó như HAProxy?) như một reverse proxy đứng trước ứng dụng Node.js.

Cấu hình trên bảo vệ ứng dụng của bạn không tiếp xúc trực tiếp với lưu lượng truy cập Internet, mở rộng server và cân bằng tải yêu cầu dễ dàng hơn.

5. Thiếu sự giám sát

Những thứ tệ hại như lỗi không mong muốn, các trường hợp ngoại lệ xảy ra thường xuyên. Bạn biết điều tệ hơn là gì không? Đó chính là không biết lỗi nào xảy ra trong hệ thống. Khi sử dụng công cụ quản lý tiến trình, mỗi lần tiến trình được khởi động lại sẽ xuất hiện một lỗi không được xử lý. Vì thế, trừ khi bạn kiểm tra logs, bạn sẽ biết vấn đề nào đã xảy ra. Giải pháp cho chuyện này chính là sử dụng dịch vụ giám sát và thông báo qua email hay sms mỗi khi tiến trình của bạn bị "ngưng" và khởi động lại.

6. Không xóa câu lệnh console.log

Không xóa câu lệnh console.log

Khi phát triển ứng dụng, chúng ta sử dụng console.log để kiểm tra mọi thứ. Tuy nhiên, đôi khi chúng ta lại quên xóa những câu lệnh này gây tốn thời gian CPU và tài nguyên. Cách tốt nhất để tránh chuyện này là sử dụng môđun debug (gỡ lỗi). Do đó, trừ khi bạn chạy ứng dụng trong môi trường DEBUG, các câu lệnh console.log sẽ được in ra.

7. Duy trì trạng thái Global bên trong các quy trình web Node

Đôi khi, các lập trình viên lưu trữ giá trị session ids, socket connections,... trong bộ nhớ. Việc này hoàn toàn không nên và cần tránh bằng bất kỳ giá nào. Nếu bạn lưu session ids trong bộ nhớ, bạn sẽ thấy người dùng bị đăng xuất ngay mỗi lần server khởi động lại. Hơn nữa, việc này cũng dẫn đến khó khăn và vấn đề khi mở rộng ứng dụng, làm tăng thêm servers. Web server của bạn chỉ tập trung xử lý các yêu cầu, truy cập qua lại trên web chứ không lưu trữ bất cứ thông tin nào ở bộ nhớ.

8. Không dùng SSL

SSL

Với một trang web dành cho người dùng, không có lý do gì để không mặc định dùng SSL. Đôi khi, tôi thấy lập trình viên đọc khóa SSL từ một file và sử dụng nó trong tiến trình Node. Bạn nên sử dụng reverse proxy trước ứng dụng Node.js và cài đặt SSL ở reverse proxy.

Hơn nữa, hãy thường xuyên kiểm tra những điểm yếu mới nhất của SSL và áp dụng biện pháp xử lý nhanh nhất có thể.

9. Thiếu các biện pháp bảo mật cơ bản

Bảo mật luôn quan trọng và người dùng lo lắng đến vấn đề bảo mật là một điều tốt. Bên cạnh việc kiểm tra bảo mật cơ bản, bạn nên sử dụng những thứ như NSP để phát hiện các điểm yếu trong dự án của mình.

Đừng sử dụng bản quá cũ của Node và Express. Loại bỏ ngay những bản không còn được bảo trì và nâng cấp về bảo mật.

10. Không sử dụng VPN

VPN

Luôn tải ứng dụng của bạn trên mạng lưới riêng tư để chỉ có những khách hàng đáng tin cậy mới có thể giao tiếp với máy chủ của bạn. Mọi người thường quên đi điều đơn giản này khi triển khai và gặp phải nhiều vấn đề sau đó. Trước khi tải ứng dụng lên mạng, bạn cần nghĩ đến kiến trúc và nền tảng cơ sở vật chất.

Ví dụ, nếu máy chủ Node của bạn chạy trên cổng 8080 và đã thiết lập cấu hình nginx làm revers proxy, điều quan trọng bạn nên đảm bảo rằng chỉ có nginx có thể giao tiếp với server tại cổng này. Cổng này nên được cô lập hoàn toàn và không bị truy cập bởi những thứ khác trên mạng.

Trên đây, tôi đã liệt kê danh sách 10 điều không nên làm trong khi chạy Node.js. Tôi sẽ tiếp tục cập nhật thêm thông tin nếu có. Danh sách kiểm tra mà bạn theo dõi trong triển khai Node.js là gì? Hãy cho tôi biết trong phần bình luận bên dưới nhé.

Tác giả: Sandeep Panda

Tham khảo thêm một số bài viết: 

Chúc các bạn vui vẻ!

Thứ Ba, 06/02/2018 16:42
51 👨 985