Xin chào! Chúng ta lại quay trở lại với loạt bài về trải nghiệm của mình trong việc xây dựng hệ thống microservices tại EGANY, trong số trước – Microsevices #2 – Triển khai microservices “tinh gọn” để bắt đầu dễ dàng hơn đã có đề cập tới một số yếu tố cần để xây dựng microservices "tinh gon", hôm nay mình sẽ chia sẻ với mọi người về vấn đề trong bài viết trên có đề cập đó là service communication. Bài viết này sẽ nói về quá trình mình bắt đầu triển khai, thay đổi khi tìm hiểu về cái dân tình xôn xao là gRPC (ở đây mình dùng gRPC danh cho nodejs) và những vấn đề phát sinh. Vậy những vấn đề này là gì? Giải quyết như thế nào? Hãy cùng tìm hiểu trong bài viết hôm này nhé.
Sự khởi đầu luôn là một thử thách, sau khi tìm hiểu một số tài liệu về vấn đề giao tiếp giữa các service như hình dưới đây
Rồi hình này
Tiếp nè
Trời mình là thằng sinh viên mới ra trường mà? Cái gì thế này? Mình nên lựa chọn cài gì đây? Mình nên theo "ông" nào đây? Thôi kiếm gì xem tiếp coi có gì nữa không.
Rồi! Có vẻ như dùng REST API được nhiều nơi đề cập tới, hơn nữa trong trường mình cũng được học và làm quen còn mấy cái kia nhìn nó mông lung quá, triển khai thì giờ chưa có kinh nghiệm, sản phẩm thì cần hoàn thành sớm nhất có thể, giờ mà lao đầu vào mấy cái cao siêu thì chắc mùa thu sang năm mới xong. Vì thế mình quyết định chọn REST API để triển khai trước, rồi sau này nâng cấp sau. Mình bắt đầu triển khai những services đầu tiên và mọi thứ khá ổn trên môi trường production.
Trong thời gian này mình có tìm hiểu thêm về chủ đề này và rồi một công nghệ đang được chia sẻ và thảo luận đó là gRPC, tại thời điểm mình tìm hiểu thường những so sánh về tốc độ giữa gRPC với REST API (HTTP) sau khi xem xét và cân nhắc một số đặc điểm sau:
Mình bắt đầu thử nghiệm và thực hiện demo với thư viện grpc dành cho nodejs, xong xui mình trình bày với sếp và anh sếp rất hoan nghênh, nhưng vẫn nhắc nhở về những vấn đề có thể gặp phải và khuyên là nên cân nhắc kĩ trước khi triển khai.
Dạ, để em xem xét nhưng mà cái này em cũng test rồi, nó chạy ngon như demo anh thấy đấy
À, lúc này mình cũng có làm việc với một bạn dev không cao nhưng mà thân thiện và vui vẻ ^^. Sau khi trình bày với sếp xong, mình có trao đổi thêm với bạn này, 2 người thống nhất và lao vào thay thế toàn bộ REST API thành gRPC (Chỗ này in đậm nè, cuối bài sẽ hiểu), dùng thư viện grpc dành cho nodejs.
Sau hơn 1 tuần triển khai thì mọi thứ đã xong, khá nhanh phải không một phần là vì mình có tự triển khai một package (npm) để hỗ trợ về việc khai báo các file proto
đó là @zerocore/grpc-helper. Nếu các bạn có tìm hiểu hoặc đã dùng thì đối với ứng dụng có nhiều model hay entity phức tạp thì việc viết file proto
khá là mất thời gian và "rường rà" mình nghĩ là vậy, do đó thư viện trên giúp tối giản hay đơn giản việc khai báo, cụ thể bạn tìm hiểu thêm nhé.
Giờ quay lại chủ đề chính, sau khi triển khai trên môi trường production, mọi thứ hoạt động khá ổn.
Gác chân lên bàn, ăn miếng bánh, uống miếng trà tận hưởng cuộc sống.
Bổng một ngày, một thành viên trong đội hỗ trợ khách hàng phản hồi rằng khách hàng không đăng nhập được.
Quầy, quầy chuyện gì đây?
Đời không như là mơ, sau một thời gian hoạt động, đâu đó khoảng gần 1 tháng thì một số vấn đề bắt đầu phát sinh, sau khi nhận được phản hồi và bắt đầu điều tra thì phát hiện hệ thống gặp lỗi 14 UNAVAILABLE: read ECONNRESET
do thư viện grpc ghi nhận.
Chuyện gì vậy? Có thể nó chỉ xảy ra cục bộ trong 1 services mà thôi.
Chưa dứt suy nghĩ, một đồng đội lên tiếng, anh ơi sao mấy cái service khác nó cũng báo lỗi ý vậy nè rồi 1,2,5,7… tất cả các service đều gặp lỗi tương tự. Trong tình thế cấp bách cần khôi phục hệ thống càng nhanh càng tốt, quyết định được đưa ra ngay lập tức bằng một phương pháp mà ai cũng biết là phương pháp gì với hiểu quả đạt 96,69%… Các bạn đoán đúng rồi đấy, đó là tắt máy khởi động lại, cũng may là hệ thống được triển khai với docker swarm do đó việc khởi động/restart khá đơn giản và nhanh chóng, càng dễ dàng hơn khi sử dụng portainer. Và kết quả đúng như mong đợi mọi thứ đã hoạt động trở lại bình thường.
Sau đấy mình vẫn tiếp tục theo dõi hệ thống, lỗi trên vẫn xảy ra, sau tìm hiểu thêm, đã đưa ra một số giả thiết cho nguyên nhân gây ra lỗi được liệt kê bên dưới, nhưng trước hết cần lướt qua một số thông tin khác về bối cảnh lúc này.
Tình trạng
Giả thiết
Trong thời gian này mình cũng tự cải thiện tình hình bằng cách tự triển khai code xử lý retry. Rồi một ngày đẹp trời khi kiểm tra thư viện grpc trên thì nhận được thông tin như các bạn thấy ở hình phía dưới
Trong phiên bản mới có các tính năng đáng chú ý như các bạn có thể thấy ở hình dưới
Mình cũng đã chuyển đổi sang thư viện mới nhưng tình hình vẫn không được cải thiện. Một tháng sau mình quyết định quay trở lại phương thức giao tiếp cũ (REST API), cổ điển nhưng lại ổn định.
Vì trước kia, khi chuyển sang dùng thư viện grpc dành cho nodejs mình không có dự phòng việc sẽ quay lại REST API, vì vậy việc chuyển đổi này khá mất thời gian, một phần vì các tính năng cũ đang chạy, tính năng mới được phát triển sắp được ra mắt. Nhưng với sự nỗ lực thì cũng đã hoàn thành việc chuyển đổi. Với REST API hệ thống hoạt động ổn định cho tới thời điểm hiện tại.
Tuy nhiên với REST API mà dùng giao tiếp nội bộ thì việc định nghĩa các endpoint, rồi viết tài liệu, mỗi khi có thay đổi thì cập nhật ở các service liên quan khá là tốn thời gian và công sức, vì vậy mình luôn tìm kiếm thêm các cách thức khác tốt hơn. À, ở đây mình không đề cập tới thiết kế theo hướng sự kiện như pub/sub nha ^^, cái này có thể mình sẽ nói ở các bài tiếp theo. Rồi một ngày sếp gọi tên, ê tới chỉ cho cái này hay lắm nè.
Moleculer Service, anh sếp mặc dù bận nhiều việc nhưng vẫn hay tìm được mấy thứ khá là mới và hay họ – nể thật sự, về framework trên ai có hứng thú thì click vào link ở đầu đoạn này để xem nhé. Rồi quay lại câu chuyện, tại thời điểm này moleculer vẫn chưa có bản phát hành chính thức và khi xem qua thì cũng chưa hỗ trợ tốt Typescript, mà Typescript là mục tiêu hướng tới tiếp theo của mình, nên lúc đấy cũng chưa có quyết định dùng.
Quay lại thời điểm hiện tại, cuối năm công việc cũng bận nhưng chủ yếu là hoàn thành những gì chưa làm xong chứ cũng không phát triển mới nữa, vì vậy mình mới có thời gian nghĩ về việc cải thiện hệ thống, nên có xem lại moleculer và thấy nó đã hỗ trợ Typescript cũng khá ổn và hơn nữa moleculer có triển khai transporter khá linh hoạt, xem hình dưới để dễ hình dung.
Ngoài ra còn có các cơ chế liên quan tới event
Những ưu điểm dễ nhận thấy gồm
Hiện tại mình đang refactor các dự án cũ sang moleculer giúp hệ thống hoạt động được tốt hơn, phát triển trong những năm tiếp theo được dễ dàng hơn, nhanh hơn hy vọng mọi việc đúng như kỳ vọng ^^.
Qua những gì đã trải qua, mình rút ra được một số bài học sau:
Bài viết tới đây là hết rồi, cảm ơn các bạn đã theo dõi, chúc một ngày tốt lành và hẹn gặp lại trong các bài tiếp theo. Ngoài ra bạn có thể đọc thêm các bài viết trong loạt bài về trải nghiệm phát triển hệ thống microservices tại EGANY ở dưới đây:
Nội dung, hình ảnh sử dụng trong bài việt được tham khảo và lấy từ các nguồn dưới đây:
Trong phần trước, mình đã chia sẻ với mọi người những khó khăn khi team…
Xin chào, tiếp tục loạt bài về trải nghiệm của mình trong việc xây dựng…
Cắm đầu cắm cổ dọn dẹp deadline và dọn nhà trước Tết nên ngâm bài…
Nếu bạn yêu thích phát triển sản phẩm với nhiều thử thách và cơ hội…
Trong phần 1, mình đã giải thích lý do tại sao EGANY chọn AWS làm…
Trong giới công nghệ hiện nay, Amazon Web Service không còn là một cái gì…