Nguồn gốc NodeJS

Một phần của tài liệu Xây dựng ứng dụng học tiếng nhật trên nền tảng IOS (Trang 30)

5. Phương pháp nghiên cứu

3.2.2 Nguồn gốc NodeJS

Nodejs được xây dựng và phát triển từ năm 2009, bảo trợ bởi công ty Joyent, trụ sở tại California, Hoa Kỳ.

Hiện tại nodejs có 71k start trên Github. 3.2.3 Các khái niệm cơ bản của NodeJs

3.2.3.1 Blocking I/O

Yêu cầu thực thi một IO operation, sau khi hoàn thành thì trả kết quả lại. Pocess/Theard gọi bị block cho đến khi có kết quả trả về hoặc xảy ra ngoại lệ. 3.2.3.2 Nonblocking I/O

Yêu cầu thực thi IO operation và trả về ngay lập tức (timeout = 0). Nếu operation chưa sẵn sàng để thực hiện thì thử lại sau. Tương đương với kiểm tra IO operation có sẵn sàng 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.

17 Hiểu đơn giản: Diễn ra theo thứ tự. Một hành động chỉ được bắt đầu khi hành động trước kết thúc.

3.2.3.4 Asynchronous

Không theo thứ tự, các hành động có thể xảy ra đồng thời , mặc dù các hành động bắt đầu theo thứ tự nhưng kết thúc thì không. Một hành động có thể bắt đầu (và thậm chí kết thúc) trước khi hành động trước đó hoàn thành.

3.2.3.5 Ví dụ về Synchronous và Asynchronous kết hợp với Promise, async/await Trong javascript các action đều là không đồng bộ (asynchronous):

Hình 7: Ví dụ mẫu về Asynchoronous

Hãy đoán thử xem đoạn code này có thực theo đúng trình tự , sẽ có một vài trường hợp máy chạy chậm, function addLinkScript chưa chạy xong thì đoạn code console.log đã thực thi đây là ván đề (asynchronous), để khắc phục được điều đó javascript có khái niệm là callback.

18 Hình 8: Ví dụ mẫu về callback

Nếu có callback đoạn code sẽ được thực thi đúng trình tự(Synchronous), nhưng cũng có vấn đề với callback là nếu lồng quá nhiều callback, khái niệm này gọi là callback hell như hình:

Hình 9: Một đoạn code về callback hell

Như vậy thì sẽ rất là rối và nhìn code sẽ không clean, javascript cho ra đời Promise để khắc phục điều đó.

19 Hình 10: Promise

Khi sử dụng thì:

Hình 11: Single Promise

Nhìn rất dễ đọc nhưng khi lồng nhiều promise thì cũng sẽ rất khó đọc như sau:

20 Nên javascript cho ra đời async/await:

Hình 13: Async/await

Với async/await giúp cho việc xử lý asynchronous trở nên dễ dàng hơn, code đọc dễ hiểu hơn.

3.3 MongoDB

3.3.1 Giới thiệu NoSQL

Thuật ngữ NoSQL được giới thiệu lần đầu vào năm 1998 sử dụng làm tên gọi chung cho các lightweight open source relational database (cơ sở dữ liệu quan hệ nguồn mở nhỏ) nhưng không sử dụng SQL cho truy vấn.

Dữ liệu trong NoSQL DB được lưu dưới dạng document, object. Truy vấn dễ dàng và nhanh hơn RDBMS nhiều.

Việc đổi cấu trúc dữ liệu (thêm, xóa trường hoặc bảng) rất dễ dàng và nhanh gọn trong NoSQL

Một số tính năng:

+ High Scalability: gần như không có một giới hạn cho dữ liệu và người dùng trên hệ thống.

+ High Availability: do chấp nhận sự trùng lặp trong lưu trữ nên nếu một node (commodity machine) nào đó bị chết cũng không ảnh hưởng tới toàn bộ hệ thống.

21 + Consistency: chấp nhận tính nhất quán yếu, có thể không thấy ngay được sự thay đổi mặc dù đã cập nhật dữ liệu.

+ Durability: dữ liệu có thể tồn tại trong bộ nhớ máy tính nhưng đồng thời cũng được lưu trữ lại đĩa cứng.

+ Deployment Flexibility: việc bổ sung thêm/loại bỏ các node, hệ thống sẽ tự động nhận biết để lưu trữ mà không cần phải can thiệp bằng tay. Hệ thống cũng không đòi hỏi cấu hình phần cứng mạnh, đồng nhất.

+ Modeling flexibility: Key-Value pairs, Hierarchical data (dữ liệu cấu trúc). 3.3.2 MongoDB là gì?

MongoDB là phần mềm cơ sở dữ liệu mã nguồn mở NoSQL hỗ trợ đa nền tảng được thiết kế theo hướng đối tượng. Các bảng (trong MongoDB gọi là

collection) có cấu trúc linh hoạt cho phép dữ liệu không cần tuân theo dạng cấu trúc nào.

22 3.3.3 Các tính năng của Mongodb

3.3.3.1 Truy vấn ad hoc

Truy vấn ad hoc là một trong những tính năng tốt nhất của chương trình. Nó hỗ trợ các trường, truy vấn phạm vi và tìm kiếm các biểu thức để trả về các trường tài liệu cụ thể bao gồm các hàm JavaScript do người dùng xác định hoặc các truy vấn này được cấu hình và trả về mẫu kết quả ngẫu nhiên có kích thước nhất định. Bên cạnh đó, các trường trong MongoDB có thể được dùng để lập các chỉ mục chính và các chỉ mục phụ.

3.3.3.2 Nhân rộng

Đây là tính năng mà chương trình cung cấp Replica set. Nó bao gồm hai hoặc nhiều bản sao của dữ liệu. Trong đó mỗi bản sao có thể đóng vai trò chính và phụ.

Trong quá trình nhân rộng, tất cả các dữ liệu ghi và đọc thực hiện trên bản sao chính.

Bản sao thứ cấp sử dụng bản sao tích hợp để duy trì bản sao dữ liệu của bản chính.

Trong trường hợp một bản sao chính thất bại, Replica set chọn ra một bản sao thứ cấp để trở thành bản sao chính tiếp theo. Replica thứ cấp có thể tùy chọn phục vụ các hoạt động nhưng dữ liệu cuối cùng chỉ nhất quán theo mặc định.

3.3.3.3 Cân bằng tải

Bằng cách sử dụng Sharding, MongoDB chia tỷ lệ theo chiều ngang để người dùng chọn một Shard key. Xác định các dữ liệu được phân phối trong collection. Nhìn chung, dữ liệu được chia thành các phạm vi và

23 được phân phối đồng đều dựa trên các Shard key. Nó chạy trên nhiều máy chủ, cân bằng tải hoặc sao chép dữ liệu để giữ hệ thống luôn hoạt động trong trường hợp có lỗi về phần cứng.

3.3.3.4 Lưu trữ tệp

Với tính năng lưu trữ tệp, MongoDB được sử dụng như một hệ thống tệp (GridFS) giúp cân bằng tải và sao chép dữ liệu trên nhiều máy tính để lưu trữ tệp. Trong đó, GridFS chia một tệp ra thành các phần hoặc các đoạn và lưu trữ thành những tài liệu riêng biệt. Bạn có thể truy cập GridFS bằng tiện ích Mongofiles hoặc plugin cho Nginx và Lighttpd.

3.3.4 Ưu và nhược điểm của Mongodb

3.3.4.1 Ưu điểm

Đầu tiên có thể nhắc đến là tính linh hoạt lưu trữ dữ liệu theo các kích cỡ khác nhau, dữ liệu dưới dạng hướng tài liệu JSON nên bạn có thể chèn vào thoải mái bất cứ thông tin gì bạn muốn.

Khác với RDBMS, dữ liệu trong đây không có sự ràng buộc và không có yêu cầu tuân theo khuôn khổ nhất định, điều này giúp bạn tiết kiệm thời gian cho việc kiểm tra sự thỏa mãn về cấu trúc nếu muốn chèn, xóa, cập nhật hay thay đổi các dữ liệu trong bảng.

MongoDB dễ dàng mở rộng hệ thống bằng cách thêm node vào cluster – cụm các node chứa dữ liệu giao tiếp với nhau.

Ưu điểm thứ tư là tốc độ truy vấn nhanh hơn nhiều so với hệ quản trị cơ sở dữ liệu quan hệ RDBMS do dữ liệu truy vấn được cached lên bộ nhớ RAM để lượt truy vấn sau diễn ra nhanh hơn mà không cần đọc từ ổ cứng.

24 Cũng là một ưu điểm về hiệu suất truy vấn của MongoDB, trường dữ liệu “_id” luôn được tự động đánh chỉ mục để đạt hiệu suất cao nhất.

3.3.4.2 Nhược điểm

Ngoài các ưu điểm vượt trội, vẫn còn một số hạn chế khi cài đặt và sử dụng bạn cần chú ý như sau:

Dữ liệu trong MongoDB không bị ràng buộc như RDBMS nhưng người sử dụng lưu ý cẩn thận mọi thao tác để không xảy ra các kết quả ngoài ý muốn gây ảnh hưởng đến dữ liệu.

Một nhược điểm mà “dân công nghệ” hay lo ngại là bộ nhớ của thiết bị. Chương trình này thường tốn bộ nhớ do dữ liệu được lưu dưới dạng key-value, trong khi các collection chỉ khác về value nên sẽ lặp lại key dẫn đến thừa dữ liệu.

Thông thường, dữ liệu thay đổi từ RAM xuống ổ cứng phải qua 60 giây thì chương trình mới thực hiện hoàn tất, đây là nguy cơ bị mất dữ liệu nếu bất ngờ xảy ra tình huống mất điện trong vòng 60 giây đó.

3.4 Docker

3.4.1 Vì sao nên sử dụng:

Docker chạy cách li trên môi trưởng ảo hóa, giúp cho việc cài đặt giữa các môi trường, giữa các version không bị conflict với nhau.

Với một dự án cài đặt docker thì chỉ cần config đúng 1 lần duy nhất , sau đó có thể đem project đi bất cư hệ điều hành nào vẫn có thể chạy bình thường mà không cần cài đặt rườm rà.

25 3.4.2 Quá trình hình thành:

Containerlization là gì?

Thời trước mô hình máy chủ thường là:

Máy chủ vật lý (physical server) + hệ điểu hành (operating system) + ứng dụng.

Hình 15: Tổng quan máy chủ vật lý [5] Vấn đề gặp phải ở đây là lãng phí tài nguyên:

• Một máy chủ chỉ cài được một OS

• Cho dù có ổ cứng khủng, ram khủng thì cũng không tận dụng hết lợi thế. • Có thể bạn đã nghe tới cái tên Vituralbox hay VMware rồi đúng không, đó đó

chính nó đó.

• Với công nghệ này, trên một máy chủ vật lý mình có thể cài đặt được nhiều OS tận dụng tài nguyên đã tốt hơn.

26 Sau đó ra đời công nghệ ảo hóa virtualization:

Hình 16: Sơ đồ cấu trúc Docker [5] Vấn đề gặp phải:

• Về tài nguyên:

o Khi bạn bật máy ảo trên VitualBox chẳng hạn, bạn cần cấu hình để cung cấp ngay từ đầu tài nguyên ổ cứng và ram từ máy thật cho máy ảo.

o Bật máy ảo lên rồi để đó không làm gì thì máy thật cũng không thể tái sử dụng tài nguyên đã cho đi.

o Ví dụ khi tạo một máy ảo ram 2GB trên máy thật ram 6GB, lúc này máy thật sẽ chỉ còn tối đa 6 - 2 = 4 GB ram, kể cả khi máy ảo không dùng hết 2GB ram được cấp, đó là một sự lãng phí.

27 • Về thời gian: Việc khởi động, tắt máy ảo khá lâu, có thể lên tới hàng phút.

Ở bước tiến hóa tiếp theo, người ta sinh ra công nghệ containerlization: Với công nghệ này, trên một máy chủ vật lý, ta sẽ cài đặt được nhiều máy ảo (giống với công nghệ ảo hóa virtualization), nhưng tốt hơn ở chỗ là các máy con này (Guess OS) đều dùng chung phần nhân của máy mẹ (Host OS) và chia sẻ với nhau tài nguyên máy mẹ.

Có thể nói là khi nào cần tài nguyên thì được cấp, cần bao nhiêu thì cấp bấy nhiêu, như vậy việc tận dụng tài nguyên đã tối ưu hơn. Điểm nổi bật nhất của containerlization là nó sử dụng các container.

3.4.3 Container là gì?

Các phần mềm, chương trình sẽ được Container Engine ( là một công cụ ảo hóa tinh gọn được cài đặt trên host OS) đóng gói thành các container.

Thế Container là gì, nó là một giải pháp để chuyển giao phần mềm một cách đáng tin cậy giữa các môi trường máy tính khác nhau bằng cách:

• Tạo ra một môi trường chứa mọi thứ mà phần mềm cần để có thể chạy được. • Không bị các yếu tố liên quan đến môi trường hệ thống làm ảnh hưởng tới. • Cũng như không làm ảnh hưởng tới các phần còn lại của hệ thống.

Bạn có thể hiểu là ruby, rails, mysql ... kia được bỏ gọn vào một hoặc nhiều cái thùng (container), ứng dụng của bạn chạy trong những chiếc thùng đó, đã có sẵn mọi thứ cần thiết để hoạt động, không bị ảnh hưởng từ bên ngoài và cũng không gây ảnh hưởng ra ngoài.

28 Các tiến trình (process) trong một container bị cô lập với các tiến trình của các container khác trong cùng hệ thống tuy nhiên tất cả các container này đều chia sẻ kernel của host OS (dùng chung host OS).

Đây một nền tảng mở dành cho các lập trình viên, quản trị hệ thống dùng để xây dựng, chuyển giao và chạy các ứng dụng dễ dàng hơn. Ví dụ, bạn có một app java, bạn sẽ không cần cài đặt JDK vào máy thật để chạy app đó, chỉ cần kiếm container đã được setting tương ứng cho app về, bật nó lên, cho app chạy bên trong môi trường container đó, vậy là ok. Khi không sài nữa thì tắt hoặc xóa bỏ container đó đi, không ảnh hưởng gì tới máy thật của bạn.

Ưu điểm:

• Linh động: Triển khai ở bất kỳ nơi đâu do sự phụ thuộc của ứng dụng vào tầng OS cũng như cơ sở hạ tầng được loại bỏ.

• Nhanh: Do chia sẻ host OS nên container có thể được tạo gần như một cách tức thì. Điều này khác với vagrant - tạo môi trường ảo ở level phần cứng, nên khi khởi động mất nhiều thời gian hơn.

• Nhẹ: Container cũng sử dụng chung các images nên cũng không tốn nhiều disks.

• Đồng nhất :Khi nhiều người cùng phát triển trong cùng một dự án sẽ không bị sự sai khác về mặt môi trường.

• Đóng gói: Có thể ẩn môi trường bao gồm cả app vào trong một gói được gọi là container. Có thể test được các container. Việc bỏ hay tạo lại container rất dễ dàng.

29 Nhược điểm:

Xét về tính an toàn:

• Do dùng chung OS nên nếu có lỗ hổng nào đấy ở kernel của host OS thì nó sẽ ảnh hưởng tới toàn bộ container có trong host OS đấy.

• Ngoài ra hãy thử tưởng tượng với host OS là Linux, nếu trong trường hợp ai đấy hoặc một ứng dụng nào đấy có trong container chiếm được quyền superuser, điều gì sẽ xảy ra? Về lý thuyết thì tầng OS sẽ bị crack và ảnh hưởng trực tiếp tới máy host bị hack cũng như các container khác trong máy đó.

3.3.4 Các câu lệnh trong Docker? [3] Pull một image từ Docker Hub: Pull một image từ Docker Hub: sudo docker pull image_name

Tạo mới container bằng cách chạy image, kèm theo các tùy chọn: sudo docker run -v <forder_in_computer>:<forder_in_container> -p <port_in_computer>:<port_in_container> -it <image_name> /bin/bash Một vài câu lệnh khác:

docker images: Liệt kê các images hiện có docker rmi {image_id/name}: Xóa một image docker ps: Liệt kê các container đang chạy docker ps -a: Liệt kê các container đã tắt

docker rm -f {container_id/name}: Xóa một container

docker start {new_container_name}: Khởi động một container

30

3.5 Redis

3.5.1 Redis là gì?

Redis (Remote Dictionary Server) là một mã nguồn mở được dùng để lưu trữ dữ liệu

có cấu trúc, có thể sử dụng như một database, bộ nhớ cache hay một message broker. Nó là hệ thống lưu trữ dữ liệu với dạng KEY-VALUE rất mạnh mẽ và phổ biến hiện nay. Redis nổi bật bởi việc hỗ trợ nhiều cấu trúc dữ liệu cơ bản như:hash, list, set, sorted set, string… Tất cả dữ liệu được ghi và lưu trên ram, do đó tốc độ đọc ghi dữ liệu rất là nhanh.

Hình 17: Tổng quan cấu trúc redis [4]

3.5.2 Các ứng dụng của Redis

Redis ngoài tính năng lưu trữ KEY-VALUE trên RAM thì Redis còn hỗ trợ tính năng xắp xếp, query, backup dữ liệu trên đĩa cứng cho phép bạn có thể phục hồi dữ liệu khi hệ thống gặp sự cố…và có thể nhân bản (Chạy nhiều Server Redis cùng lúc).

Caching: Sử dụng làm bộ nhớ đệm. Chính tốc độ đọc ghi nhanh mà Redis có

thể làm bộ nhớ đệm, nơi chia sẻ dữ liệu giữa các ứng dụng hoặc làm database tạm thời. Ngoài ra Redis có thể sử dụng để làm Full Page Cache cho website. Cũng vì tính nhất quán của Redis, cho dù restart Redis thì người dùng cũng không có cảm nhận chậm khi tải trang.

31

Counter: Sử dụng làm bộ đếm. Với thuộc tính tăng giảm thông số rất nhanh

trong khi dữ liệu được lưu trên RAM, sets và sorted sets được sử dụng thực hiện đếm lượt view của một website, các bảng xếp hạng trong game chẳng hạng. Redis hỗ trợ thread safe do đó nó có thể đồng bộ dữ liệu giữa các request.

Publish/Suscribe (Pub/Sub): Tạo kênh chia sẻ dữ liệu. Redis hỗ trợ tạo các

channel để trao đổi dữ liệu giữa publisher và subscriber giống như channel trong Socket Cluster hay topic trong Apache Kafka. Ví dụ: Pub/Sub được sử dụng theo dõi các kết nối trong mạng xã hội hoặc các hệ thống chat.

Queues: Tạo hàng đợi để xử lý lần lượt các request. Redis cho phép lưu trữ

theo list và cung cấp rất nhiều thao tác với các phần tử trong list, vì vậy nó còn được sử dụng như một message queue.

3.5.3 Các kiểu dữ liệu trong Redis

Một phần của tài liệu Xây dựng ứng dụng học tiếng nhật trên nền tảng IOS (Trang 30)