Cách chia sẻ DTO trên microservice?


33

Kịch bản của tôi là như sau.

Tôi đang thiết kế một hệ thống được thiết kế để nhận dữ liệu từ nhiều loại cảm biến khác nhau và chuyển đổi và sau đó duy trì nó để được sử dụng bởi các dịch vụ phân tích và phân tích khác nhau sau này.

Tôi đang cố gắng thiết kế mọi dịch vụ trở nên độc lập nhất có thể, nhưng tôi gặp một số rắc rối. Nhóm đã quyết định về một DTO mà chúng tôi muốn sử dụng. Các dịch vụ hướng ra ngoài (người nhận dữ liệu cảm biến) sẽ nhận dữ liệu theo cách riêng của họ, sau đó chuyển đổi nó thành đối tượng JSON (DTO) và gửi nó đến Nhà môi giới tin nhắn. Người tiêu dùng của tin nhắn sau đó sẽ biết chính xác cách đọc tin nhắn dữ liệu cảm biến.

Vấn đề là tôi đang sử dụng cùng một DTO trong một vài dịch vụ khác nhau. Một bản cập nhật phải được thực hiện ở nhiều địa điểm. Rõ ràng, chúng tôi đã thiết kế nó theo cách mà một vài trường thừa hoặc thiếu trong DTO ở đây và không có vấn đề gì cho đến khi các dịch vụ được cập nhật, nhưng nó vẫn làm tôi khó chịu và khiến tôi cảm thấy như mình mắc lỗi Nó có thể dễ dàng biến thành đau đầu.

Tôi đang đi về kiến ​​trúc hệ thống sai? Nếu không, một số cách xung quanh điều này, hoặc ít nhất là để giảm bớt lo lắng của tôi?


Bạn đang chia sẻ loại DTO nào và giao thức nào bạn đang sử dụng giữa các dịch vụ? Chẳng hạn, chia sẻ prototệp cho gRPC hoặc avrolược đồ cho Kafka và tạo DTO trong cả hai dịch vụ, nhưng tôi sẽ không chia sẻ thư viện dùng chung giữa hai dự án.
Vincent Savard

Các chuỗi JSON được mã hóa và AMQP. Tôi không muốn sử dụng bất cứ điều gì ngôn ngữ cụ thể.
nbaughman

Câu trả lời:


38

Lời khuyên của tôi? Không chia sẻ các DTO này giữa các ứng dụng trong bất kỳ loại thư viện nào. Hoặc ít nhất là không làm điều này ngay bây giờ.

Tôi biết, có vẻ rất phản trực giác. Bạn đang sao chép mã, phải không? Nhưng đây không phải là một quy tắc kinh doanh, vì vậy bạn có thể linh hoạt hơn.

Dịch vụ gửi DTO cần phải cứng nhắc trong hợp đồng tin nhắn của anh ấy, như API nghỉ ngơi. Dịch vụ không thể thay đổi DTO theo cách có thể phá vỡ các dịch vụ khác đang tiêu thụ thông tin từ DTO.

Khi một trường mới được thêm vào làm DTO, bạn chỉ cập nhật các dịch vụ khác sử dụng DTO này nếu chúng cần trường mới. Nếu không, hãy quên nó đi. Sử dụng JSON làm kiểu nội dung, bạn có thể linh hoạt tạo và gửi các thuộc tính mới mà không phá vỡ mã của các dịch vụ không ánh xạ các trường mới này trên các phiên bản DTO thực tế của mình.

Nhưng nếu tình huống này thực sự làm phiền bạn, bạn có thể tuân theo Quy tắc ba :

Có hai "Quy tắc ba" được sử dụng lại: (a) Việc xây dựng các thành phần có thể tái sử dụng khó gấp ba lần so với các thành phần sử dụng một lần và (b) một thành phần có thể tái sử dụng nên được thử trong ba ứng dụng khác nhau trước khi nó đủ chung để chấp nhận vào một thư viện tái sử dụng.

Vì vậy, hãy cố gắng chờ thêm một chút trước khi chia sẻ DTO này giữa các dịch vụ.


1
Rất nhiều đánh giá cao. Đây thực sự là một trong số rất ít mối quan tâm lớn mà tôi có trong tương lai. Không đủ để giữ tôi vào ban đêm, nhưng đủ để tôi lo lắng.
nbaughman

4
Các DTO trùng lặp (trong các dịch vụ khác nhau và rất độc lập) không vi phạm DRY. Đó là nó.
Laiv

3
Có lẽ sau đó không có lý do gì để không sao chép mã nguồn DTO trực tiếp từ dự án này sang dự án khác, như một hoạt động một lần, mặc dù sau đó có thể xóa bất kỳ phần nào trong dự án mới.
bdsl

1
Thậm chí toàn bộ dịch vụ có thể bị xóa, không gây ra vấn đề gì lớn cho toàn hệ thống. Lý tưởng nhất.
Laiv

4
Để làm rõ bản chất của câu trả lời, khi phát triển microservice, mỗi dịch vụ nên được phát triển như thể họ không biết về các dịch vụ khác, ngoại trừ các hợp đồng thực tế có thể yêu cầu.
Jonathan van de Veen

12

Khi nói đến microservice, vòng đời phát triển của dịch vụ cũng phải độc lập. *

SLDC khác nhau và các nhóm phát triển khác nhau

trong một hệ thống MS thực sự, có thể có một số nhóm tham gia vào việc phát triển hệ sinh thái, mỗi nhóm phụ trách một hoặc nhiều dịch vụ. Đổi lại, các nhóm này có thể được đặt tại các văn phòng, thành phố, quốc gia, kế hoạch khác nhau ... Có lẽ, họ thậm chí không biết nhau, điều này khiến việc chia sẻ kiến ​​thức hoặc mã rất khó khăn (nếu có thể). Nhưng điều này có thể rất thuận tiện vì mã được chia sẻ cũng bao hàm một loại lý do chia sẻ và một điều quan trọng cần nhớ lại là, bất cứ điều gì có ý nghĩa đối với một nhóm cụ thể, không phải làm cho nhóm khác. Ví dụ: được cung cấp cho Khách hàng DTO , nó có thể khác nhau tùy thuộc vào dịch vụ đang chơi, bởi vì khách hàng được hiểu (hoặc nhìn thấy) khác nhau từ mỗi dịch vụ.

Nhu cầu khác nhau, công nghệ khác nhau

SLDC bị cô lập cũng cho phép các đội chọn ngăn xếp phù hợp nhất với nhu cầu của họ. Việc áp dụng các DTO được triển khai trong một công nghệ cụ thể sẽ hạn chế khả năng lựa chọn của các đội.

DTO không phải là quy tắc kinh doanh hay hợp đồng dịch vụ

DTOs thực sự là gì? Các đối tượng đơn giản không có mục tiêu nào khác ngoài việc di chuyển dữ liệu từ bên này sang bên khác. Túi của getters và setters. Nhìn chung, đây không phải là loại "kiến thức" đáng để sử dụng lại vì không có kiến ​​thức nào cả. Sự biến động của họ cũng làm cho họ trở thành ứng cử viên tồi cho khớp nối.

Trái với những gì Dherik đã tuyên bố, nó phải có khả năng cho một dịch vụ để thay đổi DTOs của nó mà không cần phải thực hiện các dịch vụ khác để thay đổi cùng một lúc. Dịch vụ nên được độc giả khoan dung, nhà văn khoan dung và không khoan dung . Mặt khác, chúng gây ra khớp nối theo cách làm cho kiến ​​trúc dịch vụ trở nên vô nghĩa. Một lần nữa, và trái với câu trả lời của Dherik, nếu ba dịch vụ cần chính xác các DTO giống nhau, thì có khả năng đã xảy ra sự cố trong quá trình phân tách dịch vụ.

Kinh doanh khác nhau, giải thích khác nhau

Mặc dù có thể có (và sẽ có) các khái niệm xuyên suốt giữa các dịch vụ, nhưng điều đó không có nghĩa là chúng ta phải áp đặt một mô hình chính tắc để buộc tất cả các dịch vụ diễn giải chúng theo cùng một cách.

Nghiên cứu điển hình

Nói rằng công ty chúng tôi có ba bộ phận, Dịch vụ khách hàng , Bán hàngVận chuyển . Nói mỗi trong số này phát hành một hoặc nhiều dịch vụ.

Dịch vụ khách hàng, do ngôn ngữ miền của nó , thực hiện các dịch vụ xung quanh khái niệm khách hàng, nơi khách hàngngười . Chẳng hạn, khách hàng được mô hình hóa như tên , họ , tuổi , giới tính , email , điện thoại , v.v.

Bây giờ hãy nói, Bán hàngVận chuyển cũng mô hình hóa các dịch vụ của họ theo ngôn ngữ tên miền tương ứng. Trong các ngôn ngữ này, khách hàng khái niệm cũng xuất hiện nhưng với một sự khác biệt tinh tế. Đối với họ, khách hàng không phải là (nhất thiết) người . Đối với bán hàng , khách hàng có một số tài liệu một thẻ tín dụngđịa chỉ thanh toán , cho Vận chuyển một tên đầy đủđịa chỉ vận chuyển quá.

Nếu chúng tôi buộc SalesShipping áp dụng mô hình dữ liệu chính tắc của Dịch vụ khách hàng , chúng tôi buộc họ phải xử lý các dữ liệu không cần thiết có thể gây ra sự phức tạp không cần thiết nếu họ phải duy trì toàn bộ đại diện và giữ dữ liệu khách hàng đồng bộ với dịch vụ khách hàng .

Liên kết liên quan


* Đây là điểm mạnh của kiến ​​trúc này


Cảm ơn bạn! Các nghiên cứu trường hợp thực sự là những gì giúp tôi xác định có nên chia sẻ DTO hay không. Bây giờ tôi chắc chắn về lý do tại sao tôi không muốn chia sẻ chúng.
Igor

8

Tôi đang cố gắng thiết kế mọi dịch vụ để độc lập nhất có thể

Bạn nên xuất bản các sự kiện . Sự kiện là một loại thông điệp nhất định đại diện cho một thực tế vững chắc về điều gì đó đã xảy ra tại một thời điểm cụ thể.

Mỗi dịch vụ nên có trách nhiệm được xác định rất rõ và nên có trách nhiệm xuất bản các sự kiện liên quan đến trách nhiệm đó.

Hơn nữa, bạn muốn các sự kiện của bạn được đại diện cho các sự kiện liên quan đến kinh doanh, không phải các sự kiện kỹ thuật. Ví dụ như thích OrderCancelledsự kiện vào một OrderUpdatedvới status: "CANCELLED".

Theo cách đó, khi một dịch vụ cần phản ứng với một đơn đặt hàng bị hủy, nó chỉ cần lắng nghe một loại thông báo cụ thể, chỉ mang dữ liệu liên quan đến sự kiện đó. Ví dụ, OrderCancelledcó lẽ chỉ cần một order_id. Bất kỳ dịch vụ nào cần phản ứng với điều này đã được lưu trữ bất cứ điều gì nó cần biết về thứ tự trong kho lưu trữ dữ liệu của chính nó.

Nhưng nếu dịch vụ chỉ có OrderUpdatedcác sự kiện để lắng nghe, thì nó sẽ cần diễn giải về dòng sự kiện và giờ đây nó phụ thuộc vào lệnh giao hàng để kết luận chính xác khi đơn hàng bị hủy.

Trong trường hợp của bạn, tuy nhiên, như bạn được xuất bản dữ liệu cảm biến, nó có thể làm cho tinh thần để có một dịch vụ, lắng nghe các sự kiện và công bố một dòng mới của "sự kiện kinh doanh", ví dụ như TemperatureThresholdExceeded, TemperatureStabilised.

Và hãy cẩn thận về việc tạo quá nhiều microservice. Microservice có thể là một cách tuyệt vời để đóng gói sự phức tạp, nhưng nếu bạn không khám phá các ranh giới dịch vụ phù hợp, thì sự phức tạp của bạn nằm trong sự tích hợp dịch vụ. Và đó là một cơn ác mộng để duy trì.

Tốt hơn là có quá ít dịch vụ, quá lớn, hơn là có quá nhiều dịch vụ quá nhỏ.


Tôi chắc chắn đồng ý. Dữ liệu cảm biến đi thẳng vào một dịch vụ siêu nhỏ để phân tích thông điệp và chuyển nó thành định dạng được đồng ý cho toàn tổ chức trước khi xuất bản nó cho nhà môi giới. Chúng tôi sẽ có một số dịch vụ đọc tin nhắn và lưu nó vào cơ sở dữ liệu và các dịch vụ khác thực hiện phân tích tin nhắn và thực hiện công việc của riêng chúng với nó. Mỗi dịch vụ, về bản chất của doanh nghiệp, không có nhiều việc phải làm, do đó dẫn đến (hy vọng) các dịch vụ khá đơn giản.
nbaughman

2
@ Nickdb93 - Trong trường hợp của bạn, vì bạn đang xuất bản dữ liệu cảm biến, nên có một dịch vụ, lắng nghe các sự kiện và xuất bản một luồng "sự kiện kinh doanh" mới, ví dụ: Nhiệt độThực hiện, Nhiệt độ ổn định. (được thêm vào để trả lời)
Pete
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.