Một số khái niệm được sử dụng trong bài viết:
- Container (docker container): được compose từ nhiều docker images tạo nên một
enviroment để chạy một
hay nhiều nodejs application app trên đó.
- Process: 1 process sẽ được tạo ra khi 1 nodejs được start.
- Thread: có thể coi thread là 1 process trong 1 process cha (process được khởi tạo
khi start 1
application). 1 process có thể mở ra nhiều threads.
-----------------------------------------------------------------------------------------------------
Nodejs được cho là single-thread. Điều này chưa hoàn toàn đúng nhưng bởi vì NodeJS có thể xử lí hầu hết các
request
đồng thời trên 1 thread duy nhất dưạ trên cơ chế event loop của JS nên phần nào đó có thể
cho rằng NodeJS là single-thread.
Ngày nay, với sự ra đời của CPU multiple cores thì việc xử lí nhiều request cùng lúc không có nghĩa là
single thread nữa, một server có thể tạo được nhiều thread cùng lúc, dựa trên cơ chế multiple cores của CPU.
Multiple thread trong cùng 1 server có thể được mở trong cùng 1 process hoặc bằng cách start nhiều process
cùng lúc (Cluster). Mỗi 1 cách thì đều có ưu nhược điểm riêng.
Start nhiều process có thể giúp các thread hoạt động độc lập hơn , việc này đồng nghĩa với việc chia sẻ tài
nguyên giữa các thread sẽ khó khăn hơn, và việc giao tiếp giữa các thread sẽ trở nên tốn kém
hơn. Trong khi đó, việc chạy nhiều thread trong một process cung cấp khả năng scale hiệu quả hơn, việc chia
sẻ dễ dàng hơn
nhưng số lượng thread được mở cũng sẽ bị hạn chế trên 1 process, Việc này cũng xảy ra tương tự trên các
container.
Đối với các nền tảng cloud ngày nay cung cấp giải pháp auto scaling bằng cách scale container, tức là việc
tạo thêm threads/process sẽ không bị phụ thuộc vào resource của phần cứng nữa, việc này sẽ giúp việc xử lí
nhiều
request đồng thời nhưng không cần tạo thêm nhiều thread.
Các giải pháp cho việc scaling 1 NodeJS Application:
1,
Decomposing: Chúng ta có thể scale một nodejs application bằng cách chia nhỏ app dựa
theo function và
services. Điều này có nghĩa 1 app có thể được chia thành nhiều app khác nhau với nhiều codebases khác và
mỗi service cũng có thể có một database riêng. Giải pháp này còn được biết đến với tên gọi Microservice.
Việc này sẽ giúp giảm thời gian thực thi một request trên một thread.
2,
Worker threads: Khi giải pháp decomposing, không còn tỏ ra hiệu quả, tức là khi có 1
request đến 1 single
container sẽ tốn thời gian để xử lí gây blocking main thread thì giải pháp tiếp theo có thể sử dụng đó là
Worker threads, Cách này nên sử dụng hơn là cách tạo ra nhiều process trong cùng 1 container. ( Có thể sử
dụng
Piscina support làm việc dễ dàng hơn với worker pool).
Ngoài ra worker threads cũng có thể sử dụng với application chỉ chạy với single process (các desktop
application), đơn giản bởi vì trong trường hợp này bạn không thể tạo thêm các process khác được.
3, Giao việc scaling app cho 1 tool support quản lí các container (auto scaling). Ví dụ như khi 1
application được deploy lên Kubernetes, không nên sử dụng Cluster, để tạo ra multi thread trong 1 container
hay apply theo cách 1 và 2. Cách hiệu quả nhất lúc này là
hãy để Kubernetes xử lí công việc này (Tăng thêm resource cho container hiện tại hay tạo thêm nhiều replica
cho container hiện tại)
Bài gốc
Cảm ơn anh em đã thẩm!!! ^.^