Kiến trúc hướng dịch vụ Microservice và mô hình triển khai Saga

Kiến trúc hướng dịch vụ Microservice và mô hình triển khai Saga

Khái niệm về dịch vụ microservice hiện nay không còn quá mới trong những năm gần đây. Tiếp xúc và sử dụng các microservice là một phần trong cuộc sống hằng ngày của các lập trình viên. Vì vậy ở đây trong bài viết này, tôi muốn chia sẻ với bạn sự hiểu biết của tôi về microservice là gì và mô hình Saga là gì?

Trong khuôn khổ kiến thức cơ bản của mình chúng ta sẽ qua 3 mục chính sau:

  • Tại sao chúng ta cần các dịch vụ microservices.
  • Ý nghĩa của microservices và các lợi ích của nó.
  • Đào sâu vào khái niệm mô hình Saga, đối với một hệ thống phân tán qua một ví dụ thực tế dễ hiểu.

1. Microservices là gì?

Khái niệm ” Microservice ” được hiểu là một chương trình nhỏ thực hiện một chức năng cụ thể trong một hệ thống lớn hơn và độc lập với những thứ khác xung quanh. Microservice chỉ quan tâm đến chức năng mà nó được tạo ra và được thiết kế để chỉ xử lý một chức năng cụ thể.

Ví dụ,trong một ứng dụng quản lý Nhà Hàng đơn giản với các tính năng quản lý: Đơn Hàng, Khách Hàng, Đặt Chổ …Các tính năng này thực hiện các tác vụ cụ thể đáp ứng các tính năng cần có của ứng dụng nhà hàng. Chúng sẽ tương với nhau khi và chỉ khi chúng ta cần có các chức năng kết hợp với nhau thông qua các API được thiết kế. Hiện tại, chúng ta có thể nghĩ về API như là điểm cuối của các dịch vụ được đưa ra để sử dụng với thế giới bên ngoài (bên ngoài chính microservice). Tôi muốn đề cập đến một số đặc điểm chính của microservice ở đây:

  1. Triển khai dễ dàng: Mỗi microservice được triển khai độc lập, đây là điều làm cho microservice khác với những gì chúng ta gọi là Kiến trúc hướng dịch vụ (SOA).
  2. Quyền sở hữu dữ liệu: Mỗi dịch vụ nên sở hữu dữ liệu của mình, nghĩa là không có thực thể / thành phần / dịch vụ bên ngoài nào có thể truy cập (đọc) dữ liệu này trực tiếp hoặc thực hiện cập nhật (ghi) dữ liệu này.
  3. Luồng dữ liệu: Giao tiếp giữa các dịch vụ siêu nhỏ phản ứng hoặc trong một dịch vụ siêu nhỏ phản ứng chỉ phải ở dạng nhắn tin không đồng bộ (Lưu ý: Giao tiếp đồng bộ có xu hướng di chuyển dịch vụ ra khỏi khái niệm bị phản ứng).
  4. Cô lập thất bại: có nghĩa là trong số n dịch vụ trong ứng dụng của bạn, khi dịch vụ có vấn đề thì lỗi này chỉ ảnh hưởng đến dịch vụ ấy mà thôi. Điều này có nghĩa là các lỗi nghiêm trọng được cách ly với một dịch vụ duy nhất để ứng dụng hoàn chỉnh không bị hỏng. Thất bại không nên truyền đến các dịch vụ phụ thuộc và do đó không làm cho dịch vụ khác cũng bị lỗi.

Bây giờ với sự trợ giúp của các đặc điểm được đề cập ở trên của microservice, chúng ta hãy xem tại sao các dịch vụ trong ứng dụng nhà hàng nên được gọi là microservice. Chúng tôi có ba dịch vụ trong ứng dụng của mình:

  • Đơn hàng
  • Khách hàng
  • Đặt chỗ

Vì vậy, hãy phân tích và xem hành vi của họ và trả lời câu hỏi liệu họ có nên được phân loại là microservice hay không:

  1. Triển khai độc lập: Tất cả các dịch vụ này hoạt động độc lập với nha và được triển khai độc lập. Ví dụ: dịch vụ đơn hàng không phụ thuộc vào dịch vụ khách hàng để hoạt động.
  2. Quyển sở hữu dữ liệu: Dữ liệu được sử dụng bởi microservice Đơn hàng có liên quan về mặt khái niệm với chức năng mà microservice được tạo. Nó có thể chứa thông tin như: được đặt, giao dịch bị từ chối, chờ đợi, v.v. sẽ có dữ liệu cụ thể cho trường hợp sử dụng. Và không cho phép dịch vụ khách hàng tương tác với cơ sở dữ liệu được liên kết trực tiếp với dịch vụ đơn hàng. Nếu dịch vụ khách hàng cần một số thông tin về một đơn đặt hàng cụ thể thì chỉ có thể nhận được thông tin đó bằng cách yêu cầu dịch vụ đặt hàng cung cấp bằng cách gọi API tiếp xúc của dịch vụ đặt hàng.
  3. Giao tiếp không đồng bộ: Giao tiếp không đồng bộ giữa các dịch vụ và trong dịch vụ sẽ tránh được các vấn đề tranh chấp. Nội bộ của các dịch vụ phải được triển khai theo cách mà sẽ không chờ phản hồi từ một số phần khác. Thay vào đó, khi có phản hồi các dịch vụ chỉ xử lý tại thời điểm đó.
  4. Cô lập Thất bại: Giả sử dịch vụ đặt chỗ của chúng tôi ngừng hoạt động. Điều đó không có nghĩa là khách hàng sẽ không thể xem chi tiết của mình từ dịch vụ khách hàng hoặc không thấy các đơn đặt hàng trước đó của họ từ dịch vụ đặt hàng. Chỉ có điều dịch vụ đặt phòng sẽ bị ảnh hưởng bởi sự thất bại của dịch vụ đặt chỗ.

3. Điểm mạnh và điểm yếu của kiến trúc Microservice

Tôi hy vọng rằng bây giờ bạn đã hiểu khá rõ về microservice là gì và đã bắt đầu phân tích điểm mạnh và điểm yếu của nó. Tôi đã cố gắng làm cho nó đơn giản bằng cách chỉ đưa ra một cái nhìn tổng quan về một dịch vụ microservice sẽ trông như thế nào, nhưng còn nhiều điều nữa mà tôi sẽ không đề cập đến trong bài này. Mặc dù tôi muốn đề cập đến một sự khác biệt chính giữa microservice và SOA (Kiến trúc hướng dịch vụ). Đúng, hai cái này không giống nhau và đó là vì SOA không nói về việc triển khai dịch vụ và đó là lý do khi chúng tôi xây dựng một hệ thống bằng cách sử dụng SOA, chúng tôi sẽ xây dựng nó theo kiểu nguyên khối, trong đó tất cả các dịch vụ được triển khai hoàn toàn như một ứng dụng. Mặt khác, microservice là một tập hợp con của SOA, nhưng chúng yêu cầu mỗi dịch vụ phải được triển khai độc lập.

Vì vậy, hãy nhìn vào những lợi ích của việc sử dụng microservice:

  1. Triển khai nhanh: Vì mỗi microservice độc ​​lập với việc triển khai các dịch vụ khác, điều này dẫn đến việc triển khai nhanh chóng trong một ứng dụng.
  2. Cơ sở dữ liệu: Chúng tôi có thể có nhiều cơ sở dữ liệu độc lập.
  3. Ít phụ thuộc: Khớp nối lỏng lẻo giữa các thành phần của ứng dụng.
  4. Tính chất bất đồng bộ: Giao tiếp giữa các thành phần có thể ở dạng nhắn tin đồng bộ hoặc nhắn tin không đồng bộ. Tuy nhiên, chế độ bất đồng bộ là thích hợp hơn.
  5. Thu nhỏ microservice: Mỗi microservice được chia tỷ lệ độc lập.
  6. Thất bại cách ly: Thất bại được cách ly với nguồn gốc và chúng không xếp tầng cho các dịch vụ khác (điều này sẽ khiến toàn bộ ứng dụng bị lỗi thay vì chỉ là nguồn của sự thất bại). Chức năng của dịch vụ là điều duy nhất bị ảnh hưởng, do đó làm cho các chức năng còn lại của ứng dụng hoạt động bình thường.

Giống như một chiếc lá với hai mặt trái phải. Một vài nhược điểm của microservice là:

  1. Triển khai phức tạp: Chúng tôi có thể có nhiều dịch vụ siêu nhỏ trong một ứng dụng và các dịch vụ đó có thể được viết bằng các ngôn ngữ khác nhau có thể dẫn đến các hệ thống triển khai phức tạp.
  2. Giám sát phức tạp: Một số lượng lớn các dịch vụ siêu nhỏ được triển khai, điều đó có nghĩa là chúng tôi cần một cách để giám sát nhiều dịch vụ để xem liệu có bất kỳ dịch vụ nào đang gặp sự cố hay không. Đây không phải là trường hợp nguyên khối, nơi chúng tôi chỉ giám sát toàn bộ một ứng dụng.
  3. Hỗ trợ các phiên bản cũ: Chúng tôi cần cung cấp hỗ trợ liên tục cho phiên bản API cũ để khách hàng vẫn đang sử dụng phiên bản API cũ đó có thể tiếp tục thực hiện các hoạt động hàng ngày của mình mà không gặp rắc rối. Vì vậy, quy ước chung là chúng tôi giữ ít nhất hai phiên bản (tiền thân gần nhất hiện tại và hiện tại) được triển khai cho cùng một dịch vụ cho đến khi tất cả các khách hàng chuyển sang phiên bản mới hơn.

2. Kiến ​​trúc microservice và thiết kế responsive.

Chúng tôi nói rằng một hệ thống là responsive(phản ứng, đáp ứng, phản hồi) nếu nó tuân theo các nguyên tắc của kiến ​​trúc phản ứng. Điều này có nghĩa là một ứng dụng phải hội tụ:

  1. Responsive – Hệ thống sẽ có thể phản hồi lại cho người dùng trong một thời gian ( t ) được chỉ định trong các trường hợp (mặc dù một số sai lệch không đáng kể được chấp nhận) cho dù có lưu lượng truy cập lớn hoặc lưu lượng danh nghĩa. Nếu thời gian đáp ứng của hệ thống xuống cấp với tải ngày càng tăng thì nó không được coi là đáp ứng. Một hệ thống phản ứng luôn đáp ứng một cách kịp thời.
  2. Khả năng phục hồi – Khả năng phục hồi có nghĩa là hệ thống, ngay cả khi nó đang gặp phải một số vấn đề nội bộ (lỗi) có thể vẫn phản hồi và nên tiếp tục cung cấp phản hồi cho người dùng cùng lúc ( t ) như đã cung cấp nếu có không có thất bại trong nội bộ.
  3. Đàn hồi – Một hệ thống được cho là co giãn nếu nó có thể tăng hoặc giảm quy mô theo yêu cầu. Điều này dẫn đến việc sử dụng tài nguyên tốt hơn. Độ co giãn ngụ ý rằng chúng ta không thể chỉ tăng quy mô khi cần thiết mà còn là việc giảm xuống khi dư thừa, chúng ta có thể thu nhỏ lại để bảo tồn tài nguyên.
  4. Tin nhắn được điều khiển – Các hệ thống phản ứng dựa trên tin nhắn không đồng bộ để thiết lập ranh giới giữa các thành phần đảm bảo khớp nối lỏng lẻo, cách ly và minh bạch vị trí. Giao tiếp không chặn cho phép người nhận chỉ tiêu thụ tài nguyên trong khi hoạt động, dẫn đến chi phí hệ thống ít hơn.

4.Mô hình kiến trúc Saga Pattern

Một hệ thống phản ứng được điều khiển theo thông điệp và nó nhấn mạnh vào các thông điệp không đồng bộ và không chặn. Lý tưởng nhất là chúng ta nên luôn luôn đi với tin nhắn không đồng bộ giữa các thành phần nhưng chúng ta cũng có thể có tin nhắn đồng bộ. Điều quan trọng là phải hiểu ở đây rằng nhu cầu về tin nhắn đồng bộ nên được điều khiển bởi các yêu cầu tên miền hơn là sự thuận tiện về kỹ thuật. Đôi khi, bản chất không đồng bộ không giúp được gì nhiều. Hãy xem xét một kịch bản:

Mẫu Saga là một cách thể hiện một giao dịch dài hạn. Những gì chúng tôi làm là có nhiều yêu cầu, được quản lý bởi một Saga. Các yêu cầu này có thể được chạy theo trình tự hoặc song song. Khi tất cả các yêu cầu đã hoàn thành và đã hoàn thành thành công, thì chúng ta có thể nói rằng câu chuyện của chúng ta đã hoàn thành. Nhưng điều gì xảy ra nếu một yêu cầu (R1) kết thúc thành công nhưng một yêu cầu khác (R2) không thành công? Làm thế nào để bạn đối phó với thất bại này? Câu trả lời cho điều đó nằm trong việc thực hiện mô hình saga. Trong mẫu saga, mỗi yêu cầu được ghép nối với một hành động bù. Nếu một yêu cầu thất bại, các hành động bù được thực hiện cho tất cả các bước hoàn thành trong yêu cầu đó. Một khi kịch bản như vậy xảy ra, chúng tôi không hoàn thành câu chuyện, thay vào đó, chúng tôi thất bại câu chuyện và nếu hành động bù cũng thất bại thì chúng tôi thử lại hành động bù cho đến khi thành công.

Chúng ta không nên nhầm lẫn một hành động bù với một rollback.Một rollback ngụ ý rằng một giao dịch chưa hoàn thành, nhưng khi chúng tôi quay lại, chúng tôi xóa bằng chứng của giao dịch và theo cách đó chúng tôi thậm chí không biết rằng một giao dịch đã được thực hiện và nó đã thất bại. Với các hành động bù (hoặc Sagas), chúng tôi thừa nhận rằng việc chúng tôi đang cố gắng thực hiện không hoàn thành thành công và do đó, chúng tôi đang áp dụng các bản sửa lỗi dưới dạng hành động bù cho bất kỳ thay đổi nào được thực hiện đối với trạng thái của hệ thống yêu cầu này (R2) trước khi thất bại. Bằng chứng về các hành động ban đầu sẽ vẫn còn và chúng tôi trung thực và minh bạch với khách hàng về kịch bản, giao dịch, sự việc đã xảy ra, thất bại…

Một ví dụ thực tế về mô hình Saga đang sử dụng có thể được tìm thấy trong lĩnh vực ngân hàng. Giả sử bạn đã cố gắng thực hiện giao dịch, ghi nợ 500k, từ một tài khoản ngân hàng của bạn khi mua hàng từ một cửa hàng. Nhưng do một số yếu tố bạn nhận được thông báo rằng tài khoản của bạn đã bị ghi nợ nhưng chủ cửa hàng đã không nhận được khoản thanh toán. Vì vậy họ yêu cầu bạn thực hiện giao dịch (ghi nợ 500k một lần nữa) và lần này đã thành công. Bây giờ khi bạn nhìn thấy bảng sao kê ngân hàng của mình. Bạn sẽ thấy hai giao dịch vào cùng một ngày cho cùng một sản phẩm bạn đã mua. Và bây giờ, bạn tò mò, suy nghĩ về vấn đề người bán hàng đó có nói dối bạn không? Anh ấy đã tính phí bạn hai lần cho cùng một mặt hàng?v.v … Tuy nhiên mặc dù phải thanh toán 2 lần, nhưng bạn không bị tính phí hai lần cho cùng một mặt hàng!

Vì vậy, nếu bạn xem xét kỹ chi tiết bảng sao kê ngân hàng của mình, bạn sẽ thấy rằng không có hai giao dịch được thực hiện cho cửa hàng đó từ tài khoản của bạn ngày hôm đó, thay vào đó, có ba giao dịch. Điều đó sẽ trông giống như:

  1. (Giao dịch-1) Ghi nợ 500k từ tài khoản của bạn để thanh toán tại cửa hàng.
  2. (Giao dịch-2) Đã ghi có 500k vào tài khoản của bạn thông qua khoản hoàn trả, v.v.
  3. (Giao dịch-3) Ghi nợ 500k từ tài khoản của bạn để thanh toán tại cửa hàng.

Đó là cách mô hình saga hoạt động và bạn có thể thấy rõ rằng đã xảy ra sự cố với Giao dịch-1 dẫn đến Giao dịch-2 diễn ra và do đó bạn được yêu cầu thực hiện Giao dịch-1 dưới dạng Giao dịch-3 một lần nữa bởi chủ tiệm.

Trong bài này, chúng ta đã thấy microservice là gì, cần gì để dịch vụ hoặc dịch vụ được phân loại là microservice, một số ưu và nhược điểm khi làm việc với kiến ​​trúc microservice, đã đi qua các nguyên tắc cơ bản của kiến ​​trúc phản ứng và xem xét mô hình saga trong hành động với một ví dụ thực tế.

Bài viết được sưu tầm và edit từ https://dzone.com/articles/microservices-and-the-saga-pattern-part-3

 

 

Bài sau →