Microservice có nên nói chuyện với nhau?


30

Tôi đang thiết kế một ứng dụng bằng Micro-Services và tôi không chắc về cơ chế tốt nhất để sử dụng để thu thập dữ liệu từ nhiều dịch vụ.

Tôi tin rằng có hai lựa chọn:

  • Tích hợp cơ chế giao tiếp 'liên dịch vụ' cho phép các dịch vụ nói chuyện trực tiếp. API Gateway sẽ gọi một dịch vụ riêng lẻ, sau đó gọi các dịch vụ khác để thu thập dữ liệu, trước khi trả lại phản hồi tổng hợp cho API Gateway. API sau đó trả về phản hồi cho người gọi. (Đây sẽ phải là các cuộc gọi đồng bộ khi cuộc gọi đến dịch vụB yêu cầu phản hồi từ dịch vụA. Dịch vụ địa chỉ và dịch vụ địa chỉ của IE.)
  • Yêu cầu Cổng API gọi trực tiếp từng dịch vụ và hợp nhất dữ liệu trong API trước khi trả lời phản hồi.

Tôi đang nghiêng về lựa chọn thứ hai, vì các dịch vụ nói chuyện với nhau sẽ giới thiệu khớp nối, trong trường hợp đó tôi cũng có thể chỉ là kiến ​​trúc sư một ứng dụng nguyên khối. Tuy nhiên, có một vài nhược điểm nghiêm trọng mà tôi có thể nghĩ ra khỏi đỉnh đầu với tùy chọn này:

  • Việc API thực thi nhiều cuộc gọi đến nhiều dịch vụ sẽ tăng tải cho máy chủ API, đặc biệt là khi một số cuộc gọi đó bị chặn.

  • Phương pháp này có nghĩa là API phải 'nhận thức' về những gì ứng dụng đang cố gắng thực hiện (IE Logic sẽ phải được lập trình vào API để xử lý lần lượt gọi các dịch vụ, sau đó mới hợp nhất dữ liệu) hoạt động như một 'điểm cuối' câm cho các dịch vụ vi mô.

Tôi muốn biết cách tiếp cận tiêu chuẩn cho vấn đề này là gì và liệu có lựa chọn thứ ba nào khác mà tôi thiếu không?


Bạn có thể cung cấp một số bối cảnh? Ứng dụng của bạn là gì và nó đang cố gắng làm gì
Ewan

Tôi đoán sẽ ở đâu đó ở giữa hai lựa chọn của bạn: Mỗi dịch vụ vi mô giao tiếp với các dịch vụ vi mô khác khi cần để thực hiện công việc của mình. Và cổng API cũng có thể được coi là một dịch vụ vi mô, một trong đó chủ yếu là các đại biểu làm việc cho các dịch vụ khác.
Bart van Ingen Schenau

Tôi tranh luận rằng việc soạn thảo các dịch vụ siêu nhỏ ở phía máy chủ sẽ đánh bại mục đích chính là bắt đầu sử dụng các dịch vụ siêu nhỏ. Toàn bộ ý tưởng là làm cho các dịch vụ trở nên độc lập và để lại sự phối hợp cho khách hàng. Nhưng có lẽ tôi không thực tế
Sridhar Sarnobat

Câu trả lời:


21

Tôi thường khuyên bạn không nên để các dịch vụ siêu nhỏ thực hiện giao tiếp đồng bộ với nhau, vấn đề lớn là khớp nối, điều đó có nghĩa là các dịch vụ hiện được ghép với nhau, nếu một trong số chúng bị lỗi thì hiện tại đã bị hỏng hoàn toàn hoặc một phần.

Tôi sẽ phân biệt rõ ràng giữa các hoạt động thay đổi trạng thái và hoạt động đọc ( Tách truy vấn lệnh CQS ). Đối với các hoạt động thay đổi trạng thái, tôi sẽ sử dụng một số loại cơ sở hạ tầng nhắn tin và đốt cháy và quên đi. Đối với các truy vấn, bạn sẽ sử dụng giao tiếp phản hồi yêu cầu đồng bộ và có thể sử dụng API http hoặc chỉ cần truy cập trực tiếp vào cửa hàng dữ liệu của bạn.

Nếu bạn đang sử dụng nhắn tin thì bạn cũng có thể xem xuất bản đăng ký để nâng cao sự kiện giữa các dịch vụ.

Một điểm khác cần xem xét là chia sẻ dữ liệu (giao dịch) (trái ngược với chế độ chỉ đọc) nếu bạn để lộ trạng thái nội bộ của mình, người đọc có thể nhận được trạng thái sai của dữ liệu của bạn hoặc phiên bản sai và cũng có khả năng khóa dữ liệu của bạn?

Cuối cùng nhưng không kém phần quan trọng, hãy cố gắng làm mọi thứ bạn có thể để giữ cho các dịch vụ của bạn tự chủ (ít nhất là ở mức logic).

Hy vọng điều này có ý nghĩa.


11

Nó phụ thuộc vào lý do tại sao bạn cần dữ liệu đó. Nếu nó là dành cho UI, thì nó hoàn toàn ổn. Hơn nữa, đó là cách nó nên được. Chris Richardson có một lời giải thích hay về khái niệm đó và Sam Newman có một bài viết tuyệt vời về khái niệm rất giống nhau được gọi là Backends for Frontends .

Nhưng nếu bạn cần nó cho một số logic, rất có thể là ranh giới dịch vụ của bạn là sai.

Có một số đặc điểm mà ý thức chung cho chúng ta biết các dịch vụ của chúng ta nên sở hữu . Họ đang:

  1. Khớp nối thấp. Nếu bạn thực hiện một số thay đổi trong dịch vụ A, bạn không muốn chúng ảnh hưởng đến dịch vụ B.
  2. Độ kết dính cao. Nếu bạn cần triển khai một số tính năng, bạn muốn số lượng dịch vụ ít nhất có thể bị ảnh hưởng.
  3. Tự chủ cao. Nếu một số dịch vụ không thành công, bạn không muốn toàn bộ hệ thống ngừng hoạt động.
  4. Độ chi tiết chính xác. Bạn không muốn các dịch vụ của mình quá trò chuyện, vì mạng của bạn là một điều phức tạp hơn bạn nghĩ.
  5. Dịch vụ nên giao tiếp thông qua các sự kiện. Bạn không muốn dịch vụ của bạn nhận thức được nhau vì nó làm giảm khả năng bảo trì. Hãy suy nghĩ về những gì xảy ra nếu bạn cần thêm một dịch vụ mới.
  6. Dữ liệu phi tập trung. Một dịch vụ không nên chia sẻ cách lưu trữ thông tin. Giống như một đối tượng tốt, nó phơi bày hành vi, không phải dữ liệu.
  7. Vũ đạo phục vụ trong dàn nhạc.

Để đạt được điều này, hãy coi ranh giới dịch vụ của bạn là khả năng kinh doanh . Một quy trình chính thức xác định ranh giới dịch vụ trông như sau:

  1. Xác định ranh giới cấp cao hơn. Tôi thích nghĩ về chúng như một bước mà tổ chức của bạn nên thực hiện để đạt được mục tiêu kinh doanh của mình, để đạt được giá trị kinh doanh của nó. Bạn có thể biết ý tưởng về các bước cơ bản thông qua việc xem xét chuỗi Giá trị của Porter .
  2. Trong mỗi dịch vụ, đào sâu hơn. Xác định các đơn vị độc lập trẻ em với trách nhiệm riêng của họ.
  3. Tâm trí cách họ giao tiếp. Dịch vụ chính xác giao tiếp chủ yếu thông qua các sự kiện. Hãy suy nghĩ về cấu trúc tổ chức của bạn. Giao tiếp bên trong họ khá chuyên sâu, mặc dù thông thường một vài sự kiện bên ngoài được phơi bày.

Một ví dụ về việc áp dụng phương pháp này có thể được quan tâm.


1

Theo mặc định, tôi sẽ nghiêng về cách tiếp cận thứ hai, mặc dù có thể không có trong "cổng API" của bạn, nhưng tôi sẽ xem xét nó hoàn toàn hợp lý để tạo ra một dịch vụ vi mô mới với mục đích duy nhất là phối hợp các yêu cầu cho các dịch vụ vi mô khác và đại diện dữ liệu ở dạng cao hơn. Trong kiến ​​trúc dịch vụ vi mô, tôi sẽ dựa vào việc các dịch vụ vi mô "cơ sở" giao tiếp trực tiếp với nhau.

Để làm cho điều này bớt chủ quan hơn một chút, giả sử một dịch vụ phụ thuộc vào dịch vụ khác nếu dịch vụ đầu tiên yêu cầu dữ liệu hoặc dịch vụ từ dịch vụ thứ hai, trực tiếp hoặc gián tiếp . Trong thuật ngữ toán học, chúng tôi muốn mối quan hệ này là một thứ tự một phần và không phải là một thứ tự trước . Ở dạng sơ đồ, nếu bạn vẽ sơ đồ phụ thuộc, bạn sẽ có sơ đồ Hassevà không có bất kỳ chu kỳ (theo chỉ dẫn). (Trong sơ đồ Hasse, các cạnh được định hướng ngầm từ thấp đến cao hơn.) Theo hướng dẫn thêm, bạn muốn các đường dẫn từ trên xuống dưới thường ngắn hơn. Điều này có nghĩa là bạn muốn phụ thuộc trực tiếp hơn vào mọi thứ theo mặc định. Lý do là điều này giảm thiểu số lượng điều có thể sai đối với bất kỳ yêu cầu cụ thể nào, nó giảm thiểu chi phí và giảm sự phức tạp. Vì vậy, trong trường hợp "lý tưởng" theo số liệu này, sơ đồ Hasse sẽ chỉ có hai cấp độ. Tất nhiên, có rất nhiều lý do tại sao bạn có thể muốn giới thiệu các dịch vụ trung gian như bộ nhớ đệm, hợp nhất, cân bằng tải, quản lý lỗi.

Để giải thích mối quan tâm thứ hai của bạn về việc có Cổng API là "thông minh", một mô hình hiện đang có lực kéo với các khung như FalcorRelay / GraphQL là yêu cầu thêm thông số kỹ thuật về những gì cần làm để "Cổng API" có thể nói chung thực hiện các thông số kỹ thuật mà không cần phải biết những gì GetTimelineđòi hỏi. Thay vào đó, nó sẽ nhận được một yêu cầu như "yêu cầu thông tin người dùng này từ dịch vụ người dùng và nhận các bài đăng này từ dịch vụ bài đăng" hoặc bất cứ điều gì.


0

Tôi nghi ngờ nhu cầu của bạn về các dịch vụ "gọi vào" lẫn nhau cho thấy rằng bạn đang tiến hành một hệ thống chưa được kiến ​​trúc tốt, vì nhu cầu này cho các dịch vụ siêu nhỏ "gọi vào" nhau là một hình thức ghép đôi hiếm khi xuất hiện khi microservice được thiết kế phù hợp.

Bạn có thể giải thích thêm về vấn đề bạn đang cố gắng giải quyết không? Trong tiếng Anh đơn giản?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.