Xử lý các thay đổi trong kiến ​​trúc microservice theo sự kiện


9

Tôi đang thực hiện một dự án nghiên cứu trong đó tôi đang nghiên cứu các tùy chọn để xử lý các thay đổi trong kiến ​​trúc microservice hướng sự kiện.

Vì vậy, giả sử chúng tôi có một ứng dụng nơi chúng tôi có bốn dịch vụ khác nhau. Mỗi dịch vụ này có một cơ sở dữ liệu riêng để lưu trữ dữ liệu cục bộ.

Trong thiết lập này, bốn dịch vụ liên lạc với nhau bằng Bus sự kiện. Vì vậy, khi một cái gì đó xảy ra trong một dịch vụ, nó xuất bản một sự kiện. Tất cả các dịch vụ khác quan tâm đến sự kiện đó sẽ xử lý nó theo cách riêng của họ.

Trong trường hợp đó, các dịch vụ khác nhau trong kiến ​​trúc cần phải có "hợp đồng" về nội dung của các sự kiện này (thuộc tính, v.v.). Vì vậy, các dịch vụ có "sự phụ thuộc liên kết lỏng lẻo" với các sự kiện này

Câu hỏi của tôi là: Làm thế nào chúng ta có thể xử lý những thay đổi trong những sự kiện này?

Vì vậy, giả sử dịch vụ A đăng ký người dùng mới trong ứng dụng. Vì vậy, nó sẽ gửi một sự kiện "" UserRegistered ". Dịch vụ B chọn sự kiện đó và xử lý nó. Nhưng một số nhà phát triển trong nhóm dịch vụ C đã quyết định rằng họ cũng cần giới tính của người dùng đã đăng ký. Vì vậy, sự kiện được thay đổi và giới tính thuộc tính được thêm vào sự kiện "UserRegistered".

Làm cách nào chúng tôi có thể đảm bảo rằng Dịch vụ B vẫn có thể chọn cùng một sự kiện với thuộc tính bổ sung đó mà không cần triển khai lại?

Và có những cách khác để tiếp cận vấn đề này sau đó phiên bản những sự kiện này?


Định dạng nào là tin nhắn của bạn, hoặc đó là thứ bạn có thể thiết kế? Một số định dạng tin nhắn cho phép các thuộc tính tùy chọn. Tùy thuộc vào việc triển khai trình đọc, bạn có thể thêm các thuộc tính tùy chọn mà không cần cập nhật tất cả các trình đọc.
Thomas Owens

Tôi tự do chọn định dạng để sử dụng cho tin nhắn của mình. Tôi nghĩ rằng sử dụng JSON là cách tốt nhất để đi. Điều quan trọng là các dịch vụ khác nhau này được xây dựng bằng các ngôn ngữ khác nhau. Đó là lý do tại sao một định dạng chung như XML hoặc JSON là cần thiết.
CGeense

Câu trả lời:


1

Sự kiện không phải là về những gì đã thay đổi. Họ sắp sửa thay đổi.

Tôi có thể tạo một hệ thống sự kiện tách rời hoàn toàn khỏi nội dung đã thay đổi. Bằng cách đó, tất cả những gì tôi học được từ một sự kiện là một đối tượng đã được cập nhật. Nếu tôi thậm chí quan tâm rằng đối tượng đã được cập nhật thì tôi sẽ nói bất cứ điều gì biết cách nói chuyện với đối tượng đó để hỏi xem điều gì đã thay đổi.

Điều đó không giải quyết được vấn đề truyền đạt những thay đổi này. Nó chỉ ngăn nó trở thành một phần của hệ thống sự kiện.

Một ví dụ về một cách để giải quyết vấn đề của các phiên bản dữ liệu khác nhau là để người quan sát tạo và trao cho đối tượng quan sát một bộ sưu tập. Đối tượng được quan sát sẽ điền vào bộ sưu tập dữ liệu mới nhất của nó và khi điều khiển trả về cho bạn (người quan sát) có những gì bạn cần. Nếu có thêm mà bạn không quan tâm, bởi vì bạn chưa bao giờ nghe về nó, bạn chỉ cần bỏ qua nó.

Nhiều cách khác để lột da con mèo đó nhưng đó là cách tôi đã thực hiện trong trường hợp này.


Điều này sẽ không làm tăng đáng kể lưu lượng giữa các dịch vụ? Sử dụng ví dụ trong câu hỏi, một UserRegisteredsự kiện, nếu có một sự kiện không chứa thông tin về người dùng, sẽ có 1 tin nhắn được xuất bản lên xe buýt và sau đó {số dịch vụ quan tâm} yêu cầu dịch vụ người dùng hoặc tin nhắn được xuất bản lên xe buýt Sau đó, sẽ có {số lượng dịch vụ quan tâm} trở lại với các kích cỡ khác nhau. Mặc dù tôi nghĩ rằng đây có lẽ là một thiết kế sạch hơn trên giấy, nhưng nếu hiệu suất là một mối quan tâm, nó bị hỏng trong bất kỳ hệ thống không tầm thường nào, đặc biệt là qua mạng.
Thomas Owens

@ThomasOwens Gửi dữ liệu với sự kiện có nghĩa là nếu tôi có N người quan sát tôi gửi N tin nhắn. Gửi sự kiện một mình có nghĩa là tôi gửi tin nhắn 3N chỉ 1 trong số đó có gói dữ liệu. Đó là quy mô tốt ngay cả trên một mạng. Nhược điểm đáng kể duy nhất là nó tăng gấp ba lần độ trễ của bạn. Không nói rằng bạn không thể tìm thấy một giải pháp tối ưu hơn cho một tình huống cụ thể. Tôi đang chứng minh rằng các hệ thống sự kiện và phiên bản dữ liệu không cần phải được ghép nối.
candied_orange

1
Toàn bộ ý tưởng của xe buýt sự kiện này là để tách các dịch vụ khác nhau. Bằng cách sử dụng một phần của phần mềm trung gian, chúng tôi có thể đảm bảo rằng các dịch vụ này không biết nhau và có thể tồn tại và giao tiếp mà không biết về sự tồn tại của nhau. Nếu chúng tôi xóa trạng thái khỏi các sự kiện này và để các dịch vụ kết nối trực tiếp với nhau, chúng tôi sẽ ghép các dịch vụ này. Theo cách đó, chúng tôi không bao giờ có thể triển khai lại một dịch vụ mà không phải triển khai lại phần còn lại
CGeense

1
Vấn đề ở đây là hệ thống sự kiện hay không bạn cần dữ liệu mở rộng. JSON hoặc XML làm tốt điều đó nếu bạn không thay đổi tên hoặc cấu trúc đã được thiết lập trước đó. Tôi đã làm tương tự với các bộ sưu tập. Hệ thống sự kiện không nên quan tâm đến giới tính. Nếu nó gửi dữ liệu, nó sẽ chuyển chúng đi và một cái gì đó ở đầu bên kia sẽ quan tâm đến giới tính hoặc nó sẽ không.
candied_orange

1

Các khung như NServiceBus xử lý việc này bằng cách sử dụng phiên bản sự kiện với việc gửi thông điệp đa hình.

Ví dụ: phiên bản 1 của Dịch vụ A có thể xuất bản một sự kiện với tên IUserRegistered_v1. Khi Dịch vụ Phiên bản 1.1 cần bao gồm một trường bổ sung, nó có thể khai báo giao diện IUserRegistered_v1_1, kế thừa từ IUserRegistered_v1 cũng như khai báo một số trường bổ sung.

Khi Dịch vụ A xuất bản sự kiện IUserRegistered_v1_1, NServiceBus sẽ gửi tin nhắn đến tất cả các điểm cuối xử lý IUserRegistered_v1 hoặc IUserRegistered_v1_1.


0

Cải tiến gia tăng

Một thay đổi đơn giản cho mô hình là khi người nghe đăng ký làm người quan sát, họ bao gồm một danh sách hoặc cấu trúc khác của các yếu tố dữ liệu mà họ muốn biết. Điều này có thể hoạt động nếu dữ liệu được trả về từ dịch vụ đơn giản nhưng nếu bạn có một lượng dữ liệu phân cấp hợp lý, điều này có thể thực sự phức tạp để thực hiện.

Sỏi đá

Nếu bạn thực sự muốn một cách mạnh mẽ để thực hiện thiết kế này, thì dịch vụ này sẽ giữ lịch sử các thay đổi đã được thực hiện đối với dữ liệu mà nó lưu trữ. Về cơ bản, bạn không bao giờ cập nhật các bản ghi trong cơ sở dữ liệu của mình, bạn thêm các bản ghi mới trong đó mỗi bản ghi đại diện cho sự thay đổi. Mỗi bản ghi mới này được liên kết với một id sự kiện xác định hành động. Một bản ghi chẵn được lưu trữ với tất cả các thông tin liên quan về sự thay đổi (ai, cái gì, khi nào, v.v.) Điều này có một số lợi ích khác nằm ngoài phạm vi của câu trả lời này nhưng được thảo luận trong bài viết này về định lý CAP .

Khi thay đổi được thực hiện, bạn tạo bản ghi sự kiện và thêm tất cả dữ liệu mới vào cơ sở dữ liệu của bạn. Sau đó, bạn xuất bản một sự kiện cho người nghe có chứa (tối thiểu) id sự kiện. Người nghe sau đó có thể yêu cầu dữ liệu được liên kết với id đó và nhận phiên bản của dữ liệu được liên kết với nó. Mỗi người nghe sau đó có thể nhận được bất cứ thứ gì họ cần mà không cần ghép các nhu cầu khác nhau với nhau. Tôi khuyên bạn nên thêm một tập hợp con của các trường dữ liệu được sử dụng phổ biến nhất vào thông báo sự kiện để người nghe có thể lọc ra các sự kiện mà họ không quan tâm. Điều này có thể làm giảm độ chói của quá trình và một số người nghe có thể không cần phải gọi trở lại tất cả Điều này cũng bảo vệ bạn khỏi các vấn đề thời gian. Nếu bạn chỉ cần gọi lại dịch vụ và lấy dữ liệu dựa trên khóa, có thể có những thay đổi khác đã xảy ra giữa việc lấy sự kiện và lấy dữ liệu cho nó. Điều này có thể không quan trọng đối với tất cả người nghe nhưng nó có thể tạo ra vấn đề lớn nếu bạn cần biết về tất cả các thay đổi. Cải tiến thiết kế gia tăng ở trên tương thích với phương pháp này nếu bạn thực sự muốn biến nó thành 11.

Một số điều này có thể quá mức cho những gì bạn cần làm nhưng theo kinh nghiệm của tôi nếu bạn không có cách chính xác để xem bản ghi thay đổi theo thời gian như thế nào, bạn hoặc ai đó làm việc với dữ liệu của bạn cuối cùng sẽ muốn nó.


-1

@CandiedOrange đưa ra một điểm hợp lệ trong một nhận xét cho câu trả lời của chính anh ấy về các định dạng dữ liệu mở rộng như xml.

Nó không quan trọng miễn là bạn thêm dữ liệu. Tuy nhiên, hãy cung cấp mặc định hợp lý cho các sự kiện cũ / các trường không bắt buộc.

Bạn chỉ nên cập nhật các dịch vụ quan tâm - trong trường hợp này - Giới tính. Trình phân tích cú pháp xml / json có thể bỏ qua dữ liệu bổ sung cho các dịch vụ khác. Tất nhiên, điều này phụ thuộc vào sự lựa chọn của bạn về trình phân tích cú pháp và định dạng dữ liệu sự kiện.

Tôi không đồng ý với các sự kiện không có dữ liệu liên quan. Đối với tìm nguồn cung ứng sự kiện, các sự kiện nên xác định những gì đã thay đổi. Khi nhận được một sự kiện, các dịch vụ khác không cần phải lấy dữ liệu từ nguồn của sự kiện.


Quan điểm của tôi là nó cần xử lý tất cả các loại thay đổi. Hãy nghĩ về một dịch vụ phát sóng một sự kiện. Và sự kiện đó chứa một tài sản đã lỗi thời và cần được loại bỏ. Ngay cả khi các dịch vụ khác không sử dụng tài sản, nó sẽ phá vỡ chúng đơn giản vì họ đang mong đợi nó. Vì vậy, tôi đã đọc bài viết này trên martinfowler.com về các hợp đồng do người tiêu dùng điều khiển: martinfowler.com/articles/consumerDrivenContuces.html Khi áp dụng nguyên tắc này. Mỗi nhà cung cấp (sự kiện) biết những gì được mong đợi của anh ta. với thông tin đó, anh ta có thể xác nhận nếu anh ta phá vỡ bất kỳ kẻ thù nào.
CGeense
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.