NodeJS – Single threaded Model

Khi mới bắt đầu tìm hiểu Nodejs, có một câu hỏi phổ biến liên quan đến cơ chế hoạt động bên dưới Nodejs được đặt ra cho người mới bắt đầu:

Tại sao Nodejs lại chỉ dùng 1 thread và được kỳ vọng sẽ có hiệu năng cao hơn các nền tảng sử dụng đa luồng (multi-thread) ? Chẳng phải đa luồng thì sẽ xử lý cùng lúc được nhiều việc hơn sao.

Cùng tìm hiểu lý giải phù hợp cho câu hỏi này.

  • Trước hết cùng tìm hiểu cách các ứng dụng đa luồng handle request:

    Mỗi khi có 1 request tới, app sẽ sinh ra 1 thread để xử lý request được. Thread này sẽ chạy logic code, gọi các I/O event (tương tác DB, file, network …), đợi kết quả, và trả về cho client. Vì mỗi request được handle bởi 1 request, kiến trúc này thường được gọi là one thread per request model. Hầu hết các webserver Java sử dụng mô hình này.

    Điểm yếu của mô hình này:

    • Khi số lượng request tăng lên, số thread cũng tăng lên => ngốn RAM
    • Mỗi thread khi handle request liên quan đến I/O, trong khi đợi kết quả từ I/O thì ở trong trạng thái rảnh rỗi => lãng phí tài nguyên.

      Related image

  • Mô hình single-threaded

    Trong mô hình này, khi nhận request, main-thread sẽ xử lý và gọi các I/O event, sau đó tiếp tục nhận các request khác mà không chờ đợi kết quả từ I/O event => Chúng ta tránh được các điểm yếu của mô hình one thread per request.

    Image result for multi threaded vs single threaded

  • Trở lại với câu hỏi ở đầu bài, ta có thể nhận thấy mặc dù Nodejs là single thread nhưng không phải mọi tác vụ đều được xử lý tại thread này. Ví dụ khi request cần gọi vào database, process riêng của database sẽ xử lý việc gọi vào database, và rõ ràng là process của database này là multi-thread. Nói cách khác, main-thread của Nodejs sẽ ủy quyền đặc tính multi-thread cho các process khác. Trong thực tế, mọi tác vụ bất đồng bộ đều được main-thread ủy quyền cho các thread của process khác hoặc thread trong thread-pool (gồm mặc định 4 threads) của libuv.

    Từ luận điểm trên ta có thể suy ra điểm yếu của mô hình single-thread, đó là các tác vụ đồng bộ cần nhiều CPU (Fourier transform, 3D rendering) đều được xử lý ở main-thread => nó sẽ busy và không thể nhân thêm request mới => block cả app. Ngoài ra nếu máy tính có nhiều core thì single thread cũng chỉ tận dụng được 1 core.

Bạn hiểu Nodejs tới mức nào?

  1. V8 là gì? Node có chạy được không nếu thiếu V8?
    – V8 là một javascript engine dùng để compile, tối ưu và chạy Node.js
    – Node có thể chạy mà không cần V8, một vài js engine khác: SpiderMonkeyChakraCore
  2. exports và module.exports
    enter image description here
    Ban đầu exports và module.exports cùng trỏ vào 1 object rỗng. Nhưng hãy luôn nhớ rằng, ở cuối mỗi module trong Nodejs, module.exports là object được return.
    – Khi bạn code như sau:

    Nodejs sẽ add thêm 1 thuộc tính a và b vào object rỗng ban đầu. Do exports và module.exports vẫn đang trỏ vào cùng 1 object nên sẽ không có sự khác biệt khi bạn code:

    – Khi bạn code như sau:

    Nodejs sẽ báo lỗi ngay lập tức. Bởi vì exports giờ đã được trỏ tới 1 object hoàn toàn mới (function Something), trong khi module này vẫn return exports.module

    Tips: chỉ dùng exports.module cho đỡ phải nhọc não

  3. Khi khai báo 1 biến global trong 1 module, tại sao nó không global với các module khác?
    Do mỗi module trong Nodejs được wrap bởi 1 function:

  4. Có thể dùng nhiều version của 1 package trong cùng 1 app ko?
    Không
  5. Event-loop là gì?
    <
    wait-for-it>
  6. Call-stack là gì?
    Là 1 cấu trúc dữ liệu stack ghi lại các lời gọi hàm:Khi 1 hàm được gọi, nó được push vào stack. Khi 1 hàm return, nó được pop khỏi stack.Mỗi khi chương trình gặp lỗi, browser sẽ hiển thị trạng thái hiện tại của call-stack. Trong Node, call-stack được xử lý bởi V8.
  7. Sự khác nhau giữa spawn, exec, và fork
  8. Xem memory used by Node?

  9.  V8 Object là gì?
    La object C++ native biểu diễn object JS. Nói cách khác V8 object là cách V8. biểu diễn object của JS.
  10. Libuv là gì?
    libuvMột thư viện đa nền tảng tập trung vào xử lý các tác vụ I/O bất đồng bộ: file system event, event loop, thread pool, timers…
  11. Làm sao để thực hiện 1 function trước khi exit process?

  12. Node buffer có sử dụng V8 memory ko?
    Không. Node buffer mem được allocated bên ngoài V8 heap.
  13. Trường main trong file package.json có tác dụng gì?

    Xác định entry point khi app được chạy. Ví dụ khi app với package.json trên được chạy, nó sẽ chạy vào file index.js đầu tiên.

  14. 3 loại file sẽ được chạy khi require
    .json, .node, .js
  15. Bằng cách nào 1 module có thể được gọi trực tiếp và require từ module khác đồng thời?

  16. Đo execute time ntn?

  17. Callback là gì?
    Là 1 hàm được gọi sau khi 1 tác vụ được hoàn thành.
  18. Error-first callback là gì?
    Là 1 callback với argument đầu tiên luôn là error, các argument khác được dùng để pass data.

  19. Promise là gì?
    Là 1 cơ chế giúp xử lý các tác vụ bất đồng bộ.

 

Async/await Javascript

  1. Wait millisecond
  2. Parallel

    example:

    more

The Little Book of Talent tips

  • Tip #3: Steal without apology

    Good artists borrow. Great artists steal

  • Tip #6: Choose Spartian over Luxurious

    Humble spaces help focus attention on the deep-practice task at hand

  • Tip #14: Take off your watch

    Deep practice is not measured in minutes but how many connections you form in your brain

  • Tip #15: Break every move into chunk
  • Tip #17: Embrace struggle

    Because no pain, no gain

Continue reading The Little Book of Talent tips

[WILFLC] GIT cheat sheet

  1. Set/Edit remote repo
  2. Ghi đè nhánh trên remote repo lên nhánh trên local

    Dùng trong trường hợp code, commit linh tinh trên local => muốn reset lại từ đầu cho nó nét =)))
  3. Ghi đè 1 nhánh lên nhánh khác

    Dùng trong trường hợp: backup code (đã) chuẩn vào 1 nhánh dev, code code code trong nhánh master => fail => ghi đè nhánh backup dev lên master như cũ
  4. Sửa nội dung commit message

    Dùng trong trường hợp lỡ ghi bậy bạ, chửi rủa do bug quá ức chế trong message commit =)) (chỉ áp dụng cho commit mới nhất)
  5. gitignore file thừa sau khi lỡ commit
  6. Lưu công việc đang giở trên 1 branch lại mà ko cần commit

[WILFLC] Deploy nodejs server to DigitalOcean

 

    1. Push code lên git
    2. Access vào server bằng ssh
    3. Cài nodejs và npm:
    4. Clone code từ git về
    5. cd vào thư mục project 

    6. Cài  foreverjs =>
    7. Start server

      Khi có modify code thì chạy lại bằng:

 

 

 

 

[WILFLC] Detect OS device Nodejs

Xác định device của user request lên server: ios, android, web?

 

[WILFLC] Xử lí vấn đề “Cross-origin resource sharing” khi gọi API – Nodejs

Vấn đề gặp phải khi mình phải code 1 con server để upload ảnh và trả về url. Code xong xuôi, test trên postman chạy ok nhưng khi ốp vào client vkt thì tạch:

  1. Nguồn gốc vấn đề
    Same-Origin Policy:  một biện pháp bảo mật an ninh hạn chế sự tương tác giua 2 document có nguồn gốc khác nhau.Về cơ bản, đây là một chính sách quy định nội dung từ một website chỉ được đọc và thay đổi bởi một thành phần khác cùng site đấy, trường hợp truy cập nằm ngoài phạm vi site sẽ bị chặn.Nếu không có SOP, khi người dùng vô tình truy cập một trang web độc hại, script được đặt sẵn trên này có thể truy cập được dữ liệu và thực hiện tính năng của bất kỳ trang web nào người dùng đã dùng trước đóNguôn gốc ở đây được xác định bởi: protocol, host và port.

    Continue reading [WILFLC] Xử lí vấn đề “Cross-origin resource sharing” khi gọi API – Nodejs