Image for post
Image for post

Bài viết sẽ không đề cập đến các khái niệm, nếu bạn chưa từng tìm hiểu về Microservice thì nên tìm đọc hết các tài liệu trên trang chỉ của nó.

Ở đây sẽ nêu ra các vấn đề, hướng giải quyết, khó khăn và thuận lợi khi ta sử dụng kiến trúc Microservice thay vì Monolithic như thông thường. Đồng thời cũng là những cách triển khai, phát triển kiến trúc tổng thể của cả sản phẩm và con người trong nhóm.

Không cần phải bàn cãi nhiều, kiến trúc Microservice ra đời để lấp đầy những lỗ hổng, điểm yếu của kiến trúc Monolithic gặp phải.

  • Nó giúp cho source code tinh gọn(mỗi service khá nhỏ, tập trung vào 1 nghiệp vụ nhất định, dễ dàng kiểm soát)
  • Không phụ thuộc vào ngôn ngữ, database , chúng được giao tiếp qua API
  • Bảo mật hơn(dev chỉ tham gia ở 1 số service nhất định)
  • Tồn tại một cách độc lập(service sẽ tồn tại ở những nơi khác nhau)
  • Scale cũng độc lập luôn(tùy vào nhu cầu của từng service mà chúng ta có mức độ ưu tiên khác nhau)

Tuy nhiên nó cũng sẽ đem đến nhiều thách thức cho đội phát triển.

  • Thay vì quản lý tập trung thành 1 khối, nay bạn phải xử lý rất nhiều các service khác nhau, phân tán
  • Log ở tất cả các service, đảm bảo nó dễ dàng theo dõi ở 1 nơi nào đó
  • Tính nhất quán về dữ liệu khá khó khăn trong môi trường phân tán
  • Giao tiếp liên service, gọi chéo nhau khá nhiều, cũng sẽ gây ra việc khó kiểm soát. Các service sinh ra để được gọi từ bên ngoài, việc thiết kế phân chia service không tốt sẽ ảnh hưởng khá nhiều đến performance của ứng dụng.
  • Authen/Author cho từng service(cái này dùng API gateway để authen còn sẽ private các service bằng mạng nội bộ, sẽ có bài khác giới thiệu).
  • Tối đa hóa quyền tự chủ của nhóm : Tạo ra một môi trường nơi các nhóm có thể hoàn thành công việc nhiều hơn mà không phải phối hợp với các nhóm khác.
  • Tối ưu hóa cho tốc độ phát triển : Nếu không thể tăng tốc được với con người, hãy tăng tốc cho máy tính. Trao quyền cho các nhóm để xây dựng các service mạnh mẽ một cách dễ dàng và nhanh chóng.
  • Tập trung vào tự động hóa: Con người thì dễ mắc sai lầm, máy móc thì ít hơn. Nên tập trung vào các công cụ, quy trình ở các bước triển khai service.
  • Cung cấp sự linh hoạt mà không ảnh hưởng đến tính nhất quán : Cung cấp cho các nhóm quyền tự do làm những gì phù hợp với service của họ, nhưng cũng cần có những tiêu chuẩn cụ thể để phục vụ tính nhất quán lâu dài.
  • Service có tính phục hồi cao: Các Service, hệ thống có thể die bất cứ lúc nào, điểm mạnh của ông devOps nằm ở chỗ khả năng ông ấy khôi phục được hệ thống trong bao lâu.
  • Dễ dàng cho việc bảo trì: Code đã được tinh gọn hơn, tuy nhiên cần có hướng dẫn và công cụ tại mỗi thời điểm cần bảo trì một cách nhanh tiện và gọn nhất.

Đơn giản hóa sự phức tạp, mà nếu có phức tạp thì nên là kiểm soát được nó.

Kiến thức cần thiết

Trong kiến trúc Microservice, mỗi service gói gọn một phần tính năng, nghiệp vụ độc lập. Bạn cần xây dựng các service đủ nhỏ để giữ cho chúng tập trung vào một mục đích duy nhất và đủ lớn để giảm thiểu tương tác với các service khác.

  • Mỗi service cần được phát triển và triển khai độc lập, không cần giao tiếp giữa các nhóm nếu API không có thay đổi. Mỗi service sẽ gần như là một sản phẩm riêng độc lập, bạn tưởng tượng nó giống như một hệ sinh thái của Vin Group vậy: Vinmart, VinHome, VinFast… nó độc lập nhưng cũng bổ trợ cho nhau.
  • Nếu như trong quá trình phát triển mà chịu sự ảnh hưởng, hoặc chờ đợi vào một service hoàn thành thì có lẽ bạn đã sai ở đâu đó. Nếu như 1 service die mà kéo theo service khác die, thì bạn cũng đang sai ở đâu đó. Nếu code mà cũng giống nhau trên các con serivce thì bạn cũng đang có vấn đề ở đâu đó rồi.
  • Hạn chế sự phụ thuộc vào các thư viện bên ngoài, các open source hoặc bên thứ 3 cung cấp dịch vụ, cần cân nhắc trước khi sử dụng, và phải thực sự hiểu cái mình đang dùng.
  • Có cần mỗi service 1 máy chủ dữ liệu riêng, VPS riêng không? Không nhất thiết. Có thể đặt trong một máy chủ dữ liệu chung và database riêng, hoặc source code riêng trong 1 VPS dùng chung. Điều này cũng sẽ có bất lợi khi mà máy chủ này die thì coi như toàn bộ ứng dụng cũng ra đi, nó đang đi lại vết xe đổ của Monolithic. Nên đã đầu tư theo hướng này thì xác định là mỗi service nên 1 máy ảo riêng.
  • Xác định ranh giới giữa các service. Một service nên được tối thiểu hóa sự phụ thuộc tới các service khác. Mọi thứ đều được kết nối qua API. Một service nên có sự gắn kết cao. Chức năng liên quan chặt chẽ nên ở cùng nhau trong cùng một service. Điều này giảm thiểu tối đa việc giao tiếp giữa các service.
  • Những quan hệ nhiều nhiều (theo nghĩa của Monolithic, chẳng hạn product-order) thì nên đặt bảng quan hệ này ở phía có nhiều sự thay đổi nhất.
  • Một service có thể lớn đến mức nào? Micro trong microservice không liên quan gì đến kích thước vật lý hay source code, đó là về việc giảm thiểu độ phức tạp. Một serivce phải đủ nhỏ để phục vụ mục đích tập trung. Đồng thời, nó phải đủ lớn để giảm thiểu giao tiếp giữa các serivce. Không có một quy tắc nhất định nào cho việc phân chia các service, vì vậy xác định phạm vi chức năng, nghiệp vụ cho từng service là cả một nghệ thuật.
  • Khi các ứng dụng thực hiện một loạt các thao tác qua các service khác nhau, thay vì bị fail ở 1 tiến trình nào đó mà dừng hẳn 1 luồng, ta có thể queue hoặc retry( sử dụng circuit breaker) thao tác đó lại để xử lý sau.
  • Tài liệu API Documentation: Một service(API của nó) chỉ tốt như tài liệu của nó mà thôi. Điều quan trọng là phải có tài liệu sử dụng rõ ràng và dễ dàng cho mỗi service. Lý tưởng nhất, tài liệu sử dụng cho tất cả các serivce nên ở một nơi chung. Các nhóm serivce không cần phải suy nghĩ quá nhiều về việc tài liệu dành cho serivce họ đang sử dụng.
  • Điều gì xảy ra khi API ở mỗi service thay đổi? Cần có sự thông báo nhất quán, hoặc changelog ở mỗi tài liệu API. Điều quan trọng là bạn cung cần phải quản lý và kiểm soát được.
  • Cân bằng tải: Sẽ có những nhu cầu lớn nhỏ khác nhau ở mỗi service. Chính vì thế nên đây là điểm mạnh của microservice khi có thể scale theo từng service mà có nhu cầu cao hơn.

Tương tác

Một kiến ​​trúc microservice có nhiều serivce nhỏ và chúng phải giao tiếp với nhau.

  • Vậy chúng giao tiếp với nhau bằng cách nào? Sử dụng giao thức HTTP
  • Định dạng giao tiếp: JSON(Chắc bây giờ ít ai dùng xml, nghe giống sml 😁)
  • Thiết kế API: Một API tốt là một API có tài liệu tự nó đã nói hết tất cả
  • Thời gian chờ phải min nhất có thể, khách hàng mà phải ngồi đợi lâu(cảm giác như không có phản hồi gì) thì bye bye bạn.
  • Tính nhất quán là rất khó trong một hệ thống phân tán. Hãy sử dụng thêm các công cụ cần thiết để tăng tính nhất quán ứng dụng của bạn. Suy nghĩ thêm về điều này.
  • Xác thực: Nếu private các service để nó có thể tự giao tiếp trong mạng nội bộ thì cũng là một giải pháp hay, nhưng như đã định nghĩa, mỗi service cũng giống như 1 ứng dụng độc lập, vì vậy hãy tính đến trường hợp bạn sẽ phải public nó cho bên thứ 3 sử dụng
  • Tự động thử lại: Khi các thao tác không thành công(trong thời gian cho phép, thì hệ thống sẽ phải tự động thử lại hoặc queue và thông báo cho người dùng biết. Sẽ rất khó chịu nếu cứ bắt khách hàng đợi mà không thấy phản hồi gì. Dù là lỗi gì đi chăng nữa vẫn tốt hơn là không thông báo gì cả.

Phát triển và Triển khai

  • Có chiến lược rõ ràng về quản lý source code
  • Môi trường phát triển: Các nhà phát triển cần có khả năng làm việc nhanh chóng trên máy tính của họ, nhưng lại …không hoạt động trên máy của tester 😁. Để đảm bảo một môi trường nhất quán trên bất kỳ hệ điều hành nào, các môi trường phát triển nên được đóng gói dưới dạng các máy ảo.(Docker là một giải pháp)
  • CI(Continuous Integration): Cần test tự động trước khi merge request, mọi thứ oke thì mới cho deploy
  • Triển khai tự động (CD)
  • Quản lý cấu hình: Mỗi service có những cấu hình khác nhau, để dễ quản lý chúng ta sẽ phải tạo ra một external config service để quản lý.

Hoạt động

  • Ghi nhật ký tập trung: history hay log service là rất quan trọng. Nhưng làm thế nào để bạn theo dõi tác động của một yêu cầu trên nhiều serivce khác nhau nhỉ? Qua ID thôi, cách đánh ID cũng khá quan trọng.
  • Giám sát tập trung: Khi có lỗi xảy ra, các công cụ có thể giúp nhanh chóng hiểu phạm vi và nguồn gốc của vấn đề là vô cùng quan trọng. Giám sát tập trung phải là một thành phần cốt lõi ứng dụng của bạn . Nó cung cấp cho nhóm của bạn một bức tranh lớn cần thiết và đặc biệt hữu ích nếu bạn gặp phải lỗi đột ngột ở một khâu nào đó.

Con người

  • Trao quyền kiểm soát: Khi bạn xây dựng một số serivce nhỏ, mỗi thành viên trong nhóm sẽ là chủ sở hữu của nhiều serivce. Điều quan trọng là nhóm sở hữu serivce phải có các kỹ năng và công cụ cần thiết để phát triển, triển khai và vận hành serivce. Họ nên hoàn toàn tự chủ trong hoạt động hàng ngày để họ có thể phản ứng nhanh với việc thay đổi yêu cầu.
  • Nghỉ việc: Cần ứng biến với tình huống 1 người thao tác và sở hữu nhiều service, luôn đặt câu hỏi nếu họ nghỉ thì sao? Có biện pháp thay thế ra sao để đảm bảo ứng dụng và các service đều hoạt động trơn tru.
  • Một đội nên lớn như thế nào? Các nhóm phải đủ lớn để họ có thể hoàn thành công việc một cách tự động mà không lãng phí quá nhiều thời gian trong các quy trình cho phép họ giao tiếp, mà đội ngũ thì trình độ, năng lực không nên chênh lệch quá nhiều. Ở Amazon, 1 nhóm chỉ được phép tối đa số người ăn vừa đủ 2 cái pizza.

Bài viết sẽ được cập nhật liên tục.

Cập nhật lần cuối 24/02/2019

Danh sách các bài viết: Note for microservice.

Be Curious!| ☕️+✍🏼=❤️ | buihuycuong.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store