Archive for January, 2017

Phía sau 1 Node.JS

Posted: January 23, 2017 in backend

Nodejs được thần thánh hóa khắp nơi, mình cũng có thời gian dùng nó vào projects của mình, và có 1 số kiến thức nhất định về mô hình này.

– Đây chắc là 1 trong những dự án mà ý tưởng hình thành có lẽ được mấy người đó viết ra để chống C10k

– Nodejs dùng V8 Engine để dịch code và thực thi code javascript, nên có tốc độ nhanh, ổn định, nên có thể tận dùng nguồn lực dev js frontend để invoke vào làm node.js.

– Hoạt động trên 1 single-thread trên 1 process : nên tốc độ cao ( vì không gọi các hàm fork, create thread và dùng memory space để lưu trữ thread, cũng như bỏ các giai đoạn context switch ..) , cũng như còn tránh các vấn đề về threadsafe, race condition, mutex…

– Non-blocking với socket : Yêu cầu thực thi operation và trả về ngay lập tức. Nếu chưa sẵn sàng để thực hiện thì thử lại sau. Tương đương với kiểm tra operation có ready ngay hay không, nếu có thì thực hiện và trả về, nếu không thì thông báo thử lại sau.

– Mô hình Nonblocking I/O trên nodejs:

  •         Với các dạng Slow IO : dùng IO multiplexing : poll, select , epoll, kết quả trả về ngay khi ready.
  •         Với dạng Fast IO :  dùng ThreadPool : là mô hình multithread kết hợp 1 threadpool để quản lý, kết quả trả về liền.

Các dạng IO thông dụng :

  •         Block Device     => Fast
  •         Pipe    => Slow
  •         Socket    => Slow
  •         Regular    => Slow
  •         Directory    => Fast
  •         Character Device    Varies

+ Hàm epoll – xương sống của NodeJS :Giám sát, quản lý các IO và trả về trạng thái (ready or not) để event-loop có thể gọi và sử dụng file đó. Nên nhớ trên Linux, mọi thứ được xem như là 1 file IO.

– Event-loop là 1 thứ dùng để quản lý các callback ( trả về kết quả từ quá trình gọi thực thi vào nonblocking IO) vào 1 callstack, event-loop sẽ lặp đi lặp lại và trả về response tương ứng bất cứ lúc nào các hàm callback có trong callstack có dữ liệu.

– NodeJS được folk từ repo của libuv : Là thư viện xử lý các vấn đề nêu trên (nonblocking-IO) kết hợp cùng V8 tạo nên mô hình là 1 event-loop ( gọi chung là mô hình event-driven ) + Nonblocking I/O và xử lý các request của client, trả về response asynchronize như bọn nó từng quảng cáo.

Tổng kết :

Node.JS có ý tưởng hình thành là khá thú vị, có nhiều service khác cũng sử dụng mô hình nonblocking tương tự như HAProxy, Redis, Nginx ..

Tuy nhiên, nó có 1 số nhược điểm mà mình từng gặp, là việc dùng 1 thread, sẽ gặp 1 số vấn đề khi không khai thác hết những hệ thống có tài nguyên dồi dào như CPU có nhiều core chẳn hạn .. Lúc này, ta cần dùng 1 đầu proxy để phân tải ra nhiều instance nodejs khác nhau, thì vấn đề đồng bộ session, id .., và các bài toán về đồng bộ, phân hoạch request .. cần phải xử lý.

Ngoài ra, khi làm việc với các mô hình blocking, hay các lib blocking xử lý ảnh, xử lý bản vẽ kỹ thuật .. thì nodejs cũng không khá hơn dùng các mô hình khác, mà còn có khi tệ hơn vì đã chiếm dụng hết cpu usage để event loop hoạt động.

Tuy nhiên, với 1 dự án start-up, thiếu điều kiện, mà phải serve 1 lượng lớn request, thì nodejs là giải pháp khá ổn.

Mô hình tốt cho 1 dự án start-up : Nodejs + Nginx(hoặc HAProxy) + Redis + Mysql( hoặc MongoDB tùy hoàn cảnh). Đây là mô hình mình đã dùng để build project cho các nhà đầu tư ít vốn ( cùng wordpress, lavarel ).

Tham khảo nhiều từ :

http://en.sotatek.com/nodejs-hieu-asynchronous-event-drivent-nonblocking-io/