Giao tiếp trong Microservices

Giao tiếp trong Microservices

February 8, 2021 3 By Nam Vu

Như mình đã nêu ở bài viết trước, nếu so sánh Microservice với xây dựng một căn nhà thì vấn đề giao tiếp trong Microservice chính là những cánh cửa, có thể là những cánh của thông giữa các phòng (Internal) hay cũng có thể những cánh của thông ra ngoài trời (External).

Bạn đọc có thể xem lại tại đây
http://blog.ntechdevelopers.com/lot-ta-ban-chat-cua-kien-truc-microservice-so-voi-kien-truc-xay-dung/

Ở bài viết này mình sẽ làm rõ các vấn đề giao tiếp trong Microservice nhé.

Bắt đầu thôi!

Trong thế giới Microservice, bạn có thể kiến trúc xây dựng nên một ứng dụng thông qua một tập hợp các services. Mỗi service trong tập hợp đó đều phải tuân theo một quy chuẩn tất yếu bao gồm: Dễ dàng tháo lắp (Loosely coupled), Dễ dàng bảo trì và kiểm thử (Maintainable and testable) và phát hành một cách độc lập (Can be independently deployed).

Mỗi service trong kiến trúc Microservice đều giải quyết các vấn đề business riêng của nó trong một ứng dụng phần mềm, hay đôi khi thì có sự hỗ trợ của một vài service khác nếu logic quá phức tạp và khó có thể độc lập.

Lợi ích của microservice thì mình cũng đã nêu rất cụ thể trong bài viết trước rồi. Bạn đọc cũng có thể xem lại tại đây
http://blog.ntechdevelopers.com/microservices-architecture-kien-truc-microservices/

Vấn đề ở đây nằm ở chỗ các services và database đều nằm phân tán. Mỗi thành phần giữa chúng luôn tuân theo nguyên tắc độc lập nhất có thể. Chính vì điều này nên các kiến trúc sư đã đang và sẽ phải rất đau đầu trong việc phân chia các nghiệp vụ nằm trong từng service. Chia quá lớn thì không đảm bảo tính độc lập, chia quá nhỏ thì thành ra nano-service, khó có thể maintain và trao đổi dữ liệu nghiệp vụ khó khăn. Nhưng dù có chia service như nào đi chăng nữa thì việc chúng có những thời điểm, có những nghiệp vụ phải giao tiếp với nhau là chuyện bình thường. Ví dụ như một ứng dụng làm về shopping thường sẽ có các service như account, product, payment, sale. Vậy theo bạn một chức năng đặt hàng thì nằm trong product hay payment hay account. Tất nhiên là chúng phải giao tiếp trao đổi dữ liệu để hình thành một workflow. Người dùng đăng nhập (Account service) sau đó chọn sản phẩm (Product service) rồi thanh toán đặt hàng (Payment service). Đó, dữ liệu sẽ chuyển qua lại giữa các service với nhau, đó chính là lý do phát sinh ra các hình thức giao tiếp nhằm trao đổi dữ liệu giữa các service. Đôi khi còn phải giao tiếp với dịch vụ bên ngoài như gửi email hay sms thì phải thông qua một bên thứ 3 nữa. Dù sao giao tiếp trong microservice là điều không thể tránh khỏi.

Phương thức giao tiếp đầu tiên mà mình muốn đề cập tới là HTTP communication. Đây là phương thức lâu đời nhất, nó ra đời từ khi Internet xuất hiện và World Wide Web sinh ra từ những năm 1990. Nó có thể là web service api, rest api, restful api hay ra đời gần đây là graphQL. Về ý tưởng chung thì mỗi service được định nghĩa với các endpoint để có thể gọi đến nếu có yêu cầu, chúng thực thi nghiệp vụ độc lập riêng sẽ trong nội bộ service và trả về dữ liệu đã được xử lý, các service khác cần tới nó cũng có thể gọi qua endpoint và lấy output của nó rồi xử lý tiếp phần nghiệp vụ bên phía service mình. Đó là service to service communication. Đây cũng là phương thức khi bạn trao đổi thông tin với những api endpoint bên ngoài của các third party sẵn có. Làm việc với bên thứ ba là một chủ đề khá rộng, có lẽ mình sẽ đề cập tới nó trong một bài viết khác.

Một trong những service được sử dụng nhiều nhất thông qua phương thức giao tiếp này đó là service phía Frontend và Backend. Chúng trao đổi thông tin và thường xuyên nhất, và do đặc điểm của đường truyền http/1 và http/2 thì chúng lại càng được sử dụng phổ biến và thường xuyên.

Với phương thức này việc giao tiếp giữa các service có thể thực hiện một cách đồng bộ hoặc bất đồng bộ dữ liệu. Bạn không muốn phải đợi quá lâu để có được thông tin dữ liệu và tiếp tục xử lý nghiệp vụ trong service của mình chứ!

Một đặc điểm nữa của phương thức này chính là tính đóng gói, bạn chẳng cần biết đến service kia hoạt động như nào, bạn chỉ cần quan tâm đến bạn có được quyền truy cập vào endpoint đó hay không và input, output là gì để có thể trao đổi với chúng.

Cũng nằm trong danh mục phương thức này mà mình chưa đề cập đến bên trên đó là RPC protocol. Nó là viết tắt của Remote Procedure Call và đúng như cái tên nó có thể thực hiện một function hay method đến một remote server. Tôi gọi bạn và bạn thực thi nó giúp tôi. Giao thức này được dùng phổ biến trong các service internal với nhau vì đơn giản tốc độ là đường truyền của nó nhanh hơn hẳn. Đến đây mình cũng đề cập đến gRPC, một sự tái cấu trúc định nghĩa lại và dựa trên RPC framework. RPC protocol thì đã ra đời rất lâu rồi có trước cả http và vào những năm 1970s. Thế nhưng gRPC thì là một sự cải tiến với cơ chế stream và thay đổi dạng dữ liệu giao tiếp thành xml và json để hợp thời đại. Mình sẽ có một bài viết khác với chủ đề gRPC này sau nhé!

Phương thức giao tiếp thứ hai trong các phương thức giao tiếp của microservice đó là Message communication. Không giống như HTTP communication, các services không giao tiếp trực tiếp với nhau, mà chúng giao tiếp thông qua Message Broker. Bạn cứ hình dung nó là một nhà môi giới. Tôi cần thông tin tôi tìm đến nhà môi giới, tôi bán thông tin tôi cũng đưa thông tin cho nhà môi giới và thông tin của tôi sẽ được bán cho những người cần đến nó.

Với phương thức này dữ liệu truyền nhận được gọi là messages. Khi service muốn truyền thông tin đi chúng sẽ publish cho Message Broker nhận và xếp chúng vào hàng đợi (queue). Khi service muốn nhận thông tin thì chúng subscribe với Message Broker và chúng sẽ nhận được message mà chúng cần. Điều này giải quyết được những khó khăn và sự phức tạp mà HTTP communication gặp phải.

Một cải tiến đối với Message communication chính là Advance message queue protocol (AMQP). Nó được chuẩn hóa để truyền và nhận message giữa các service hay ứng dụng một cách tin cậy hơn. Bạn hình dung bạn gửi một bức thư đi nhưng bạn không thể đảm bảo cái đứa môi giới kia có chuyển bức thư đó cho bạn đến đúng người bạn cần không, vậy là AMQP sinh ra để giải quyết điều đó. Một số AMQP điển hình hiện nay như ActiveMQ, Azure Service Bus, RabbitMQ, StormMQ hay Kafka… Mình cũng lại hứa hẹn với các bạn sẽ có bài viết ngay sau bài viết này về các Message communication này nhé!

Phương thức thứ ba để giao tiếp của microservice đó là Event-driven communication. Đây là một cách tiếp cận tương tự như Message communication. Tuy nhiên với ví dụ trên thì tôi không cần đến môi giới nữa, tôi tự bán hàng và những ai tìm mua thì cứ đến tìm tôi.Với ý tưởng này thì Event-driven communication sẽ là sự giao tiếp trực tiếp giữa 2 hoặc nhiều service với nhau theo hình thức fire event. Có 2 loại phát fire event, một là fire and forgot, khi tôi gửi messages đi tôi không qua tâm đến nó đã đến đích hay chưa, tôi  quên nó luôn và không chờ tín hiệu phản hồi kiểu gửi email, hơn nữa bạn có thể gửi một loạt các service khác nhau cùng một thời điểm. Loại thứ 2 là fire event kiểu pub/sub (publisher/subscriber) tôi gửi messages cho những người đăng ký messages đó, sau khi gửi đi tôi có thể chờ hoặc không chờ thông tin phản hồi.

Trên đây là 3 phương thức giao tiếp dữ liệu phổ biến nhất của microservice, bạn có thể tìm kiếm được đâu đó những cách giao tiếp khác như wcf, web socket… nhưng về mức độ tiếp cận thì mình nghĩ 3 phương thức trên đã có thể đáp ứng hầu hết tất cả những nhu cầu giao tiếp của bạn.

Nếu bạn có đóng góp ý về các phương thức khác, mình sẵn sàng lắng nghe mọi phản hồi của các bạn dưới phần bình luận nhé!