NATS, hệ thống phân tán nhắn tin và độ trễ cực thấp được người phỏng vấn Naver sử dụng
Khi làm phát triển backend, sẽ có lúc bạn phải đối mặt với những trăn trở như thế này.
Đó là khoảnh khắc bạn cảm nhận được giới hạn của việc chỉ sử dụng giao tiếp REST đơn thuần và cấu trúc CRUD khi dịch vụ mở rộng và lưu lượng truy cập tăng lên. Bản thân tôi cũng đã gặp phải vấn đề tương tự trong thực tế và đã trải qua nhiều lần thử sai giữa hiệu suất và sự phức tạp của cấu trúc.
Câu trả lời mà tôi lựa chọn trong quá trình đó chính là NATS. Với cấu trúc đơn giản dựa trên một tệp thực thi duy nhất (single binary), hiệu suất độ trễ cực thấp tính bằng micro giây, và việc cung cấp vừa đủ các tính năng thiết yếu cho thực tế từ Pub/Sub đến Queue Group, JetStream đã khiến nó trở thành một lựa chọn rất thực tế trong môi trường dịch vụ thực tế.
Khóa học này không phải là một bài giảng liệt kê các tính năng của NATS. Dựa trên những vấn đề tôi đã đối mặt trong công việc, tôi sẽ giải thích thông qua mã nguồn và luồng xử lý về việc tại sao tôi chọn NATS trong những tình huống nào và cách tôi thiết kế cấu trúc ra sao. Đây là khóa học giúp mọi người, từ những người mới bắt đầu với hệ thống nhắn tin (messaging system), các nhà phát triển backend đang chuẩn bị xin việc, cho đến các nhà phát triển cấp cao đang trăn trở về một kiến trúc tốt hơn, có thể hiểu về hệ thống phân tán và tiến thêm một bước trong sự nghiệp.
Tôi đã từng có kinh nghiệm sử dụng NATS trong thực tế, một điều khá hiếm gặp, nên tôi đã đăng ký khóa học này để tìm hiểu sâu hơn. Các khái niệm được hệ thống rất tốt và cách giải thích dễ hiểu nên tôi đã thực hành rất thú vị.
Mặc dù phần thực hành được tiến hành bằng JS, nhưng tôi đã vừa nghe giảng vừa tự thiết lập trong môi trường Kotlin và Spring Boot. Khi kết hợp giữa các khái niệm trong bài giảng và xem tài liệu hướng dẫn thì tôi thấy nó không quá khó (so với Kafka thì nó cực kỳ trực quan và đơn giản..).
Khóa học đã giúp ích cho tôi rất nhiều~!
5.0
Ande
92% đã tham gia
Tôi đang phát triển tại Naver, nơi tạo ra khóa học này, và nó được gọi là Ande!!
NATS... có thể các bạn còn xa lạ, nhưng đây thực sự là một nền tảng tuyệt vời và có cấu trúc rất hữu ích.
Chính vì vậy mà tôi cũng thường xuyên sử dụng nó và đang tập trung áp dụng trong công việc thực tế.
Tôi đã cố gắng hết sức để chia sẻ những phần mà tôi đã trải nghiệm và hiểu biết, mong các bạn xem vui vẻ và cho tôi nhiều phản hồi nhé.
Chúc các bạn một ngày tốt lành!!
5.0
02년생 개발자
96% đã tham gia
Tôi thực sự nghĩ đây là khóa học giải thích mọi thứ về NATS ngay cả khi bạn không biết gì về nó. Giảng viên giải thích rất tốt và giống như có một developer giỏi ngồi bên cạnh chỉ cho bạn tại sao nền tảng này hữu ích và cách sử dụng nó...
Cảm ơn vì khóa học tuyệt vời này.
Bạn sẽ nhận được điều này sau khi học.
Khả năng trực tiếp thiết kế và triển khai kiến trúc nhắn tin độ trễ cực thấp dựa trên NATS.
Khả năng thiết kế, lựa chọn và áp dụng Pub/Sub, Request-Reply, Queue Group phù hợp với từng tình huống cụ thể
Kinh nghiệm cấu trúc hệ thống tin nhắn phân tán ổn định, có tính đến Consumer Lag và nghẽn cổ chai (bottleneck)
Triển khai tính bền vững của tin nhắn và đường ống xử lý sự kiện thực tế bằng JetStream
Năng lực backend có thể giải thích và thiết kế hệ thống phân tán dựa trên sự kiện (event-driven), vượt xa khỏi CRUD thông thường.
Phát triển · Lập trình · Backend
Nếu bạn đang trì hoãn việc áp dụng Kafka
Khi dịch vụ phát triển lớn hơn, việc chỉ sử dụng các lệnh gọi REST sẽ gặp những hạn chế. Tuy nhiên, khi định áp dụng messaging thì Kafka lại quá nặng nề và bạn cũng không tự tin để vận hành nó. NATS chính là lựa chọn nằm ở giữa. Bạn có thể bắt đầu một cách nhẹ nhàng, và khi cần tính bền vững (persistence), bạn có thể chuyển sang sử dụng JetStream.
Mức độ Nhập môn
Thực hành Docker
Core NATS · JetStream
cho đến khi vận hành
Thời hạn khóa học vô tận
Từ Core đến Vận hànhPub/Sub · Queue Groups · JetStream
Trọng tâm thực hànhTriển khai bằng Docker Compose và trực tiếp chạy thử từng pattern
2 nhà phát triển đang đương nhiệm10 năm kinh nghiệm tại trụ sở Naver · Phát triển máy chủ nền tảng tại Pangyo
NATS là một lớp giao tiếp dành cho các hệ thống phân tán để trao đổi tin nhắn. Core NATS được sử dụng để truyền tải nhẹ nhàng với mục tiêu đơn vị micro giây, trong khi JetStream được sử dụng khi cần lưu lại tin nhắn.
Nơi bài giảng này bắt đầu
Không phải là bạn phải chọn một trong hai đâu.
Core NATS
Không để lại dấu vết và nhanh chóng
Nếu không có bên nhận, tin nhắn sẽ biến mất. Thay vào đó, nó nhẹ và nhanh.
Cùng một hệ thống Hai chế độ
JetStream
Lưu lại và đọc lại
Lưu trữ tin nhắn và tiêu thụ lại sau. Consumer Lag cũng phát sinh từ đây.
Khóa học này sẽ được chia thành hai phần để học. Trong phần 2~3, chúng ta sẽ làm quen với các mô hình giao tiếp thông qua Core NATS, và từ phần 4 trở đi, chúng ta sẽ tìm hiểu về tính bền vững và vận hành với JetStream. Mục tiêu là giúp bạn có thể quyết định khi nào nên sử dụng bên nào.
Cấu trúc
Một máy chủ được đặt ở giữa
Bên gửi không biết bên nhận là ai. Chỉ cần biết tên chủ đề gọi là Subject và gửi đi, thì bên nào đăng ký chủ đề đó sẽ nhận được. Đây là lý do tại sao các dịch vụ không cần phải biết trực tiếp về nhau.
ProducerGửi tin nhắn đến Subject. Không cần biết có bao nhiêu bên nhận
→
NATS ServerChạy dưới dạng một tệp thực thi (binary) duy nhất. Chỉ cần một tệp cấu hình và không có sự phụ thuộc bên ngoài
→
ConsumerPhía đăng ký cùng một Subject sẽ nhận được. Nếu có nhiều phía, sẽ chia ra nhận bằng Queue Group
Đến đây là kết thúc phần Core NATS. Nếu không có bên nhận nào, tin nhắn sẽ đơn giản là biến mất. Khi cần lưu lại, chúng ta bật JetStream trên server, và từ đó những câu chuyện như lưu trữ, tiêu thụ lại (re-consume), hay Consumer Lag mới bắt đầu.
Nơi bài giảng này bắt đầu
Đây là cuộc đối thoại đã diễn ra trên thực tế
Khi một nhà phát triển từ Naver mới gia nhập nhóm, chủ đề đầu tiên mà người đó đưa ra chính là NATS.
Đây là câu chuyện đã diễn ra khi nhà phát triển Naver gia nhập đội ngũ.
NNhà phát triển NaverCó ai ở đây biết về NATS không ạ? Vì tôi thường xuyên sử dụng nó nên tôi định thử quay một video về chủ đề đó.
KNhà phát triển Kakao (Người phỏng vấn)Ồ, tôi đã từng dùng cái đó rồi. Tôi biết là nếu dùng ở cấp độ Core thì hiệu suất có thể đạt tới mức micro giây.
NNhà phát triển NaverĐúng vậy. Nhưng trên thực tế, thay vì dùng Core, người ta thường dùng dưới dạng JetStream để đảm bảo tính HA nhiều hơn. Nó cực kỳ hữu ích trong việc triển khai và áp dụng các hàng đợi tin nhắn đơn giản.
HHongTôi cũng chỉ mới nghe nói về NATS chứ chưa có kinh nghiệm sử dụng, nếu được anh hướng dẫn, tôi sẽ cố gắng hết sức để thực hiện.
TNhà phát triển TossDạo này tôi bận quá… Tôi cũng muốn tạo một cái mới vào lúc nào đó, và tôi nghe nói NATS rất tốt. Việc định tuyến cũng rất linh hoạt và dễ dàng.
KNgười phỏng vấn Kakao (Nhà phát triển)Các nhà phát triển của Naver thực sự rất giỏi. Tôi rất vui khi bạn gia nhập cùng chúng tôi.
Bạn sẽ học được gì
Nắm vững các pattern và đi đến cả vận hành
Pub / SubMô hình xuất bản - đăng ký (Publish/Subscribe) cơ bản nhất
Request / ReplyCách gửi và nhận yêu cầu cũng như phản hồi trên nền tảng nhắn tin
Queue GroupsXem xét hoạt động bên trong và thực hành cho đến phần cân bằng tải (load balancing)
Định tuyến SubjectChính sách quyết định nơi gửi tin nhắn dựa trên chủ đề
JetStream Stream và ConsumerLưu lại tin nhắn và quyết định chiến lược tiêu thụ
Consumer Lag và DLQCách theo dõi người tiêu dùng bị chậm trễ và nơi gửi các tin nhắn bị lỗi
Tính khả dụng cao và phân cụmCho đến các lưu ý khi vận hành và Best Practice
KV Bucket và Object StorageCùng với các công dụng khác ngoài nhắn tin
NATS không chỉ là một công cụ dùng để truyền tin (messaging). Đúng như cách tài liệu chính thức tự giới thiệu, bên trong một tệp thực thi (binary) duy nhất bao gồm các thành phần sau:
Pub / Sub
Streaming (JetStream)
Kho lưu trữ Key-Value
Object Store
Microservices
Từ Đa đám mây (Multi-cloud) đến Rìa (Edge)
Nếu bạn đã chạy NATS rồi, có những trường hợp bạn không cần phải gắn thêm một kho lưu trữ khác để chia sẻ giá trị cài đặt hay lưu trữ tệp tin. Trong phần 6, chúng ta sẽ thực hành về KV Bucket và Object Storage.
Không chỉ dừng lại ở việc đọc
Chạy bằng Docker Compose và trực tiếp thực hiện theo từng pattern.
Nội dung và trình tự các phần được đề cập như thế nào
Phần đầu là Core NATS, phần giữa là JetStream, và phần cuối là các chủ đề nâng cao cùng với sự so sánh với các hệ thống messaging khác.
01
Giới thiệu khóa học
Giới thiệu khóa học
Bản tóm tắt lý thuyết
Source Code
Tài liệu chính thức của NATS
02
Giới thiệu và lý do tại sao nên học NATS - hệ thống xử lý tin nhắn hiệu năng cực cao
Giới thiệu, lịch sử và Kiến trúc của NATS
Core NATS vs JetStream
Các trường hợp sử dụng (Use Case) tối ưu hóa việc áp dụng NATS
Cấu trúc tổng thể & Giao tiếp
03
Cách sử dụng NATS ở cấp độ ứng dụng
Cấu hình môi trường Docker Compose
[Thực hành] Pub & Sub Pattern
[실습] Request & Reply 패턴
Hoạt động bên trong của Queue Groups
[Thực hành] Cân bằng tải với Queue Groups
[Thực hành] Chính sách định tuyến tin nhắn dựa trên Subject
04
JetStream để duy trì dữ liệu trong NATS
[실습] JetStream 기본 개념 및 Stream 생성
[Thực hành] Chiến lược xử lý tin nhắn và JetStream Consumer
05
Cách sử dụng JetStream của NATS trong thực tế
[실습] JetStream의 Consumer Lag 관리 및 모니터링
[실습] JetStream의 Dead Letter Queue 처리 전략
[실습] Xây dựng pipeline xử lý sự kiện thực tế sử dụng JetStream
[Thực hành] Cấu hình tính sẵn sàng cao và phân cụm (clustering) của JetStream
Lưu ý và Best Practice khi vận hành JetStream
06
Chủ đề nâng cao của NATS — So sánh Object Storage · KV Bucket và MSQ
Giới thiệu và cách sử dụng NATS Key-Value Bucket
[Thực hành] Quản lý tệp tin sử dụng NATS Object Storage
So sánh các nền tảng nhắn tin NATS vs Kafka vs RabbitMQ
Các lưu ý khi áp dụng NATS và chiến lược di chuyển dữ liệu
Kết thúc khóa học và hướng dẫn cộng đồng
Dành cho những người như thế này
Khóa học này dành cho ai?
Nhà phát triển Backend đang cảm thấy bị giới hạn trong việc mở rộng chỉ với giao tiếp REST và cấu trúc CRUD
Những nhà phát triển đang trì hoãn việc áp dụng Kafka
Sinh viên mới tốt nghiệp/Người đang tìm việc chưa biết điểm bắt đầu của kiến trúc hướng sự kiện (Event-Driven Architecture)
Nhà phát triển thực tế đang không giải quyết được vấn đề Consumer Lag
Nhà phát triển thiếu kinh nghiệm thiết kế truyền thông thời gian thực với độ trễ cực thấp
Thị trường hiện nay
Câu chuyện về việc AI thay thế lập trình viên
Tuyển dụng mới đang giảm dần, và các doanh nghiệp chỉ muốn chọn những người đã được kiểm chứng. Đây là những bài báo đã xuất hiện trong vài tháng gần đây.
Krafton, công ty vừa đạt được kết quả kinh doanh cao kỷ lục, đã bắt đầu cắt giảm nhân sự. Lý do được đưa ra là để chuyển đổi thành một doanh nghiệp 'ưu tiên AI' (AI First).
Các doanh nghiệp chuyên về phần mềm đang ngừng tuyển dụng lập trình viên mới. Cũng có dự báo cho rằng việc tuyển dụng lập trình viên trình độ sơ cấp sẽ giảm mạnh tới 77%.
53% nhà thiết kế trò chơi đã trả lời rằng "AI sẽ thay thế công việc của tôi". Các trường hợp thôi việc theo khuyến nghị cũng đã được báo cáo.
Khi doanh nghiệp càng bất an, phía người ứng tuyển càng phải thể hiện sự khác biệt rõ rệt hơn. Việc học cuối cùng vẫn là tự thân vận động, nhưng tùy vào việc bạn nhìn nhận cái gì dưới góc độ nào mà cùng một khoảng thời gian bỏ ra, chiều sâu trong cách diễn đạt sẽ khác nhau. Bài giảng này được tạo ra để truyền tải góc nhìn đó.
Đánh giá khóa học
Chia sẻ từ những người đã học trước đó
Tôi đã sao chép nguyên văn từ đánh giá khóa học trên Inflearn.
"Vì tôi đã có kinh nghiệm hiếm hoi khi sử dụng NATS trong thực tế nên đã đăng ký học để tìm hiểu kỹ hơn. Các khái niệm được hệ thống rất tốt và giải thích dễ hiểu nên tôi đã thực hành rất thú vị. Mặc dù phần thực hành được tiến hành bằng JS, nhưng tôi đã tự thiết lập trong môi trường Kotlin và Spring Boot để học, và tôi thấy nếu vừa xem khái niệm trong bài giảng vừa xem tài liệu thì cũng không quá khó. So với Kafka thì nó cực kỳ trực quan và đơn giản."
감성코딩 · Viết sau khi hoàn thành 73% khóa học
"Tôi nghĩ đây là một bài giảng sẽ dạy cho bạn mọi thứ ngay cả khi bạn không biết gì về NATS. Cách giải thích rất tốt, cảm giác giống như được một nhà phát triển tài năng ngồi cạnh bên chỉ dẫn cho bạn tại sao nền tảng này lại hữu ích và cách sử dụng nó như thế nào vậy."
Lập trình viên sinh năm 02 · Viết sau khi hoàn thành 96% khóa học
Giảng viên
Được tạo ra bởi hai nhà phát triển đang làm việc thực tế.
Được tạo ra bởi Ande, nhà phát triển backend 10 năm kinh nghiệm tại trụ sở chính của Naver, và Hong, nhà phát triển server nền tảng tại Pangyo.
NAVER · KỸ SƯ BACKEND · 10 NĂM KINH NGHIỆM
Ande
Tôi là nhà phát triển Backend với 10 năm kinh nghiệm, hiện đang phát triển máy chủ tại trụ sở chính của Naver. Hầu hết các cấu trúc và tiêu chí đánh giá được đề cập trong bài giảng đều là những điều tôi đã đúc kết được từ trải nghiệm thực tế tại hiện trường. Đừng ngần ngại để lại câu hỏi nhé.
"Không nhất thiết phải lấy Kafka ra dùng ngay từ đầu. Chỉ cần trở nên nặng đô ở mức độ cần thiết là được."
Hiện là nhà phát triển server tại Naver (trụ sở chính) · Cựu nhà phát triển backend tại tập đoàn Shinsegae · Cựu nhà phát triển server tại startup chăm sóc sức khỏe · Chuyên ngành Khoa học máy tính
Hệ thống phân tánMessagingTraffic lớnKiến trúc Backend
Người chia sẻ kiến thức · Phát triển máy chủ nền tảng tại Pangyo
Hong
Tôi đang đảm nhận việc phát triển máy chủ nền tảng tại Pangyo. Tôi tiếp tục hoạt động với tư cách là người chia sẻ kiến thức để chia sẻ các phương pháp tự học cũng như các vấn đề và giải pháp gặp phải trong thực tế. Các bài giảng không được thực hiện một mình mà được xây dựng cùng với nhiều nhà phát triển khác đang làm việc trong ngành.
"Việc gắn messaging không khó, cái khó là biết khi nào nên gắn nó vào."
Phát triển máy chủ nền tảngKiến trúc hướng sự kiệnNhiều bài giảng Backend
Câu hỏi thường gặp
Các câu hỏi thường gặp về khóa học NATS
Q.NATS khác với Kafka như thế nào?
⌄
Khác biệt lớn nhất chính là trọng lượng. NATS tập trung vào việc truyền tải tin nhắn nhanh chóng mà không lưu lại ở chế độ Core, và sẽ bật JetStream nếu cần tính bền vững (persistence). Trong khi đó, Kafka có cấu trúc lưu lại log ngay từ đầu. Ở phần 6, chúng ta sẽ so sánh song song với Kafka·RabbitMQ, đồng thời đề cập đến các lưu ý khi áp dụng và chiến lược di chuyển (migration).
Hỏi: Tôi có thể sử dụng hệ thống nhắn tin (messaging system) ngay cả khi mới bắt đầu không?
⌄
Mức độ khó được thiết lập ở mức nhập môn. Bắt đầu từ lý do tại sao NATS ra đời và kiến trúc của nó ở Phần 2, sau đó ở Phần 3, chúng ta sẽ thực hành từng mẫu cơ bản nhất như Pub/Sub trong môi trường Docker Compose.
Hỏi:Nên dùng Core NATS hay JetStream?
⌄
Sự khác biệt nằm ở việc bạn có chấp nhận mất tin nhắn hay không. Với Core NATS, nếu không có bên nhận, tin nhắn sẽ biến mất. Đổi lại, nó nhẹ và nhanh. Nếu bạn cần lưu lại tin nhắn và đọc lại sau này, hãy dùng JetStream. Khóa học này sẽ hướng dẫn riêng biệt cả hai và đưa ra các tiêu chí lựa chọn ngay trong phần 2.
Q.Khóa học có đề cập đến Consumer Lag không?
⌄
Đó chính là bài giảng đầu tiên của phần 5. Chúng ta sẽ cùng thực hành quản lý và giám sát Consumer Lag, sau đó đi đến chiến lược xử lý Dead Letter Queue. Đây là lý do tại sao trong đối tượng đề xuất có bao gồm "những nhà phát triển thực tế không giải quyết được vấn đề Consumer Lag".
Q.Môi trường thực hành được cấu hình như thế nào?
⌄
Được triển khai bằng Docker Compose. Bài giảng đầu tiên của phần 3 là về cấu hình môi trường, và sau đó là các bài thực hành cho từng pattern.
Q.Ngoài việc truyền tin nhắn (messaging) ra thì còn có công dụng nào khác không?
⌄
Trong Phần 6, chúng ta sẽ tìm hiểu về Key-Value Bucket và Object Storage. Vì chúng có thể được sử dụng để chia sẻ các giá trị cài đặt hoặc xử lý tệp tin, nên nếu bạn đã triển khai NATS, đôi khi các vấn đề có thể được giải quyết mà không cần đến bộ lưu trữ riêng biệt.
Kafka không phải là câu trả lời duy nhất
Bắt đầu nhẹ nhàng và chỉ trở nên chuyên sâu khi cần thiết. Chúng ta sẽ cùng xem xét từ những cốt lõi (Core) cho đến vận hành thực tế.
Nếu bị tắc nghẽn một mình sẽ mất rất nhiều thời gian. Có một không gian riêng để bạn có thể thoải mái chia sẻ từ những phần vướng mắc khi nghe bài giảng, những câu hỏi phát sinh khi áp dụng vào dịch vụ của chính mình, cho đến cả những câu chuyện về sự nghiệp và thực tế công việc.
OPEN CHAT · Cộng đồng nhà phát triển
Chúng ta chia sẻ những gì?
Chúng tôi chia sẻ về những vấn đề thực tế gặp phải trong công việc, các cấu trúc mà người khác đã lựa chọn, cũng như những câu chuyện về sự nghiệp lập trình viên. Các câu hỏi liên quan đến bài giảng cũng luôn được chào đón.
"Những chỗ bạn bị vướng mắc thường thì người khác cũng sẽ vướng mắc. Hỏi người đã đi trước là cách nhanh nhất."
Câu hỏi về bài giảngTrường hợp áp dụng thực tếCâu chuyện nghề nghiệp
Nhà phát triển backend cảm thấy bị giới hạn trong việc mở rộng dịch vụ nếu chỉ dựa vào giao tiếp REST và cấu trúc CRUD.
Những nhà phát triển vẫn đang trì hoãn việc áp dụng messaging vì cảm thấy Kafka quá áp lực.
Sinh viên mới tốt nghiệp đang tìm việc, biết rằng cần phải sử dụng kiến trúc hướng sự kiện (Event-Driven Architecture) nhưng không biết phải bắt đầu từ đâu.
Các nhà phát triển thực tế đang cảm thấy bế tắc vì không thể giải quyết một cách có hệ thống các vấn đề về Consumer Lag, độ trễ và nút thắt cổ chai.
Nhà phát triển chưa từng thiết kế đúng cách cấu trúc dịch vụ yêu cầu độ trễ cực thấp và giao tiếp thời gian thực.
Tôi bắt đầu học lập trình sau một thời gian dài lười biếng ở nhà và cảm thấy hứng thú với nó, hiện tại tôi đang đảm nhận việc phát triển máy chủ nền tảng (platform server) tại Pangyo. Tôi tiếp tục hoạt động với tư cách là người chia sẻ kiến thức vì muốn cung cấp cho các bạn phương pháp tôi đã học cũng như những vấn đề và giải pháp khác nhau mà các bạn có thể gặp phải trong thực tế.
Bài giảng không chỉ được tạo ra từ kiến thức của riêng tôi. Mọi bài giảng đều có sự đồng hành của những người cộng sự.
Tôi đang phát triển tại Naver, nơi tạo ra khóa học này, và nó được gọi là Ande!!
NATS... có thể các bạn còn xa lạ, nhưng đây thực sự là một nền tảng tuyệt vời và có cấu trúc rất hữu ích.
Chính vì vậy mà tôi cũng thường xuyên sử dụng nó và đang tập trung áp dụng trong công việc thực tế.
Tôi đã cố gắng hết sức để chia sẻ những phần mà tôi đã trải nghiệm và hiểu biết, mong các bạn xem vui vẻ và cho tôi nhiều phản hồi nhé.
Chúc các bạn một ngày tốt lành!!
Có vẻ như đây là khóa học duy nhất trên Inflearn đào tạo về nền tảng NATS.. Tôi biết rằng nó thực tế cũng được sử dụng rất nhiều trong server game, thật tuyệt khi có thể học tập nội dung này một cách thoải mái như vậy.
Tôi đã xem và học hỏi được những nội dung rất bổ ích. Cảm ơn bạn.
Nội dung rất trực quan và dễ hiểu, đặc biệt tôi rất thích phần cuối khi bạn chỉ ra điểm khác biệt so với các dịch vụ MSQ khác và khi nào thì nên sử dụng nó.
Chào bạn Jeondanji, cảm ơn bạn đã để lại đánh giá tốt. Sau này mình sẽ cố gắng cung cấp thêm nhiều bài giảng bổ ích hơn nữa.
Chúc bạn một ngày tốt lành!