by Talia Nassi | on 09 MAY 2022 | in Amazon EventBridge, Events, Serverless | Permalink | Share
Hai lựa chọn phổ biến khi xây dựng ứng dụng là kiến trúc request-response và kiến trúc event-driven. Trong kiến trúc yêu cầu-phản hồi, các thành phần của ứng dụng giao tiếp thông qua các cuộc gọi API. Khách hàng gửi một yêu cầu và mong đợi một phản hồi trước khi thực hiện công việc tiếp theo. Trong kiến trúc dựa trên sự kiện, khách hàng tạo ra một sự kiện và có thể ngay lập tức chuyển sang công việc tiếp theo của mình. Các phần khác nhau của ứng dụng sau đó phản ứng với sự kiện theo nhu cầu.
Trong bài viết này, bạn sẽ tìm hiểu về những lý do cần xem xét chuyển từ kiến trúc yêu request-response sang kiến trúc event-driven.
Thách thức của kiến trúc request-response
Khi bắt đầu xây dựng một ứng dụng mới, nhiều nhà phát triển thường mặc định sử dụng một kiến trúc request-response. Một kiến trúc request-response có thể tích hợp chặt chẽ các thành phần và các thành phần đó giao tiếp thông qua các cuộc gọi đồng bộ. Mặc dù phương pháp yêu cầu-phản hồi thường dễ bắt đầu hơn, nhưng nó có thể trở nên khó khăn khi ứng dụng của bạn phát triển với độ phức tạp cao hơn.
Trong bài viết này, tôi sẽ xem xét một ứng dụng thương mại điện tử ví dụ sử dụng kiến trúc yêu cầu-phản hồi và minh họa các thách thức của việc tích hợp chặt chẽ. Sau đó, tôi sẽ chỉ cho bạn cách xây dựng cùng một ứng dụng với một kiến trúc dựa trên sự kiện có thể mang lại cho bạn khả năng mở rộng, khả năng chịu lỗi và tốc độ phát triển của nhà phát triển được tăng lên.
Sự phối hợp chặt chẽ giữa các microservices
Trong một ứng dụng thương mại điện tử tiêu biểu sử dụng một API đồng bộ, khách hàng gửi một yêu cầu để đặt hàng và dịch vụ đặt hàng gửi yêu cầu xuống dòng cho dịch vụ hóa đơn. Nếu thành công, dịch vụ đặt hàng sẽ phản hồi với một thông báo thành công hoặc số xác nhận.
Trong giai đoạn ban đầu này, đây là một kết nối đơn giản giữa hai dịch vụ. Thách thức đến khi bạn thêm nhiều dịch vụ khác tích hợp với dịch vụ đặt hàng.
Nếu bạn thêm một dịch vụ hoàn tất và một dịch vụ dự báo, dịch vụ đặt hàng sẽ có nhiều trách nhiệm và độ phức tạp hơn. Dịch vụ đặt hàng phải biết cách gọi API của mỗi dịch vụ, từ cấu trúc cuộc gọi API đến cú pháp gọi lại của API. Nếu có bất kỳ thay đổi không tương thích ngược với các API, nhóm dịch vụ đặt hàng phải cập nhật chúng. Hệ thống chuyển tiếp các đợt lưu lượng lớn đến phụ thuộc của dịch vụ đặt hàng, mà có thể không có các khả năng mở rộng giống nhau. Ngoài ra, các dịch vụ phụ thuộc có thể truyền lại lỗi lên tới ngăn xếp của khách hàng.
Xử lý lỗi và thử lại
Bây giờ, bạn thêm các dịch vụ mới xuống dòng cho việc hoàn tất và vận chuyển đơn hàng vào ứng dụng thương mại điện tử.
Trong kịch bản lý tưởng, mọi thứ hoạt động như dự kiến: Dịch vụ đặt hàng kích hoạt việc lập hóa đơn, các hệ thống thanh toán, và cập nhật dự báo. Khi thanh toán được xác nhận, điều này kích hoạt việc hoàn tất và đóng gói đơn hàng, và sau đó thông báo cho dịch vụ vận chuyển để yêu cầu thông tin theo dõi.
Tuy nhiên, nếu trung tâm hoàn tất không thể tìm thấy sản phẩm vì chúng đã hết hàng, thì dịch vụ hoàn tất có thể phải thông báo cho dịch vụ lập hóa đơn, sau đó hoàn ngược thanh toán hoặc phát hành hoàn trả. Nếu hoàn tất thất bại, thì hệ thống kích hoạt vận chuyển cũng có thể thất bại. Dự báo cũng phải được cập nhật để phản ánh sự thay đổi. Luồng làm việc phục hồi này chỉ là để giải quyết một trong nhiều “lối đi không may” tiềm năng có thể xảy ra trong ứng dụng thương mại điện tử được định hình bởi API này.
Sự phối hợp chặt chẽ giữa các nhóm phát triển
Trong một ứng dụng tích hợp đồng bộ, các nhóm phải phối hợp mọi dịch vụ mới được thêm vào ứng dụng. Điều này có thể làm chậm quá trình phát hành tính năng mới của mỗi nhóm phát triển. Hãy tưởng tượng nhóm của bạn làm việc trên dịch vụ thanh toán nhưng bạn không được thông báo rằng một nhóm khác đã thêm một dịch vụ phần thưởng mới. Bây giờ nếu dịch vụ hoàn tất gặp lỗi thì điều gì sẽ xảy ra?
Dịch vụ hoàn tất có thể điều phối tất cả các dịch vụ khác. Nhóm thanh toán của bạn nhận được một thông báo và bạn hủy bỏ thanh toán, nhưng bạn có thể không biết ai xử lý thử lại và logic lỗi. Nếu dịch vụ phần thưởng thay đổi nhà cung cấp và có một API mới, và không thông báo cho nhóm của bạn, bạn có thể không nhận thức được dịch vụ mới.
Cuối cùng, việc phối hợp các hoạt động và luồng công việc này có thể trở nên khó khăn khi hệ thống trở nên phức tạp hơn và quản lý thêm các dịch vụ. Đây là một trong những lý do mà việc chuyển sang kiến trúc event-driven có thể mang lại lợi ích.
Lợi ích của kiến trúc dựa trên sự kiện
Kiến trúc dựa trên sự kiện có thể giúp giải quyết các vấn đề của sự phối hợp chặt chẽ giữa các microservices, xử lý lỗi và thử lại, và phối hợp giữa các nhóm phát triển.
Sự phối hợp chặt chẽ giữa các microservices
Trong kiến trúc event-driven, người xuất bản phát ra một sự kiện, sau đó sự kiện được xác nhận bởi bus sự kiện. Bus sự kiện định tuyến các sự kiện đến các bên đăng ký, những bên này xử lý các sự kiện với logic kinh doanh tự chứa. Không có giao tiếp trực tiếp giữa người xuất bản và các bên đăng ký.
Các ứng dụng không liên kết cho phép các nhóm hoạt động độc lập hơn, điều này có thể tăng tốc độ của họ. Ví dụ, với một tích hợp dựa trên API, nếu nhóm của bạn muốn biết về một thay đổi đã xảy ra trong microservice của một nhóm khác, bạn có thể phải yêu cầu nhóm đó thực hiện một cuộc gọi API đến dịch vụ của bạn. Do đó, bạn có thể phải tính đến quyền xác thực, phối hợp với nhóm khác về cấu trúc của cuộc gọi API. Điều này gây ra sự trao đổi giữa các nhóm, làm chậm lại thời gian phát triển. Với một ứng dụng dựa trên sự kiện, bạn có thể đăng ký nhận các sự kiện được gửi từ microservice của bạn và xe buýt sự kiện (ví dụ, Amazon EventBridge) sẽ chịu trách nhiệm định tuyến sự kiện và xử lý xác thực.
Xử lý lỗi và thử lại
Một lý do khác để chuyển sang kiến trúc event-driven là để xử lý lưu lượng không đoán trước. Các trang web thương mại điện tử như Amazon.com có lượng lưu lượng biến đổi tùy thuộc vào ngày. Khi bạn đặt một đơn hàng, một số việc xảy ra.
Trước tiên, Amazon kiểm tra thẻ tín dụng của bạn để đảm bảo rằng có đủ tiền trong tài khoản. Sau đó, Amazon phải đóng gói hàng hóa và tải lên xe tải. Tất cả điều này xảy ra tại một trung tâm hoàn tất của Amazon. Không có cuộc gọi API đồng bộ cho phần mềm cơ sở dữ liệu của Amazon để đóng gói và gửi sản phẩm. Sau khi hệ thống xác nhận thanh toán của bạn, giao diện người dùng cuối (front end) tổ chức một số thông tin mô tả sự kiện và đưa số tài khoản của bạn, thông tin thẻ tín dụng và những gì bạn đã mua vào một sự kiện được đóng gói và đưa nó lên đám mây và vào một hàng đợi. Sau đó, sau đó, một phần mềm khác sẽ loại bỏ sự kiện khỏi hàng đợi và bắt đầu đóng gói và giao hàng.
Điểm then chốt về quy trình này là các quy trình này có thể chạy ở các tốc độ khác nhau. Thông thường, tốc độ mà khách hàng đặt đơn hàng và tốc độ mà các nhà kho có thể đóng gói hộp gần như tương đương nhau. Tuy nhiên, vào những ngày bận rộn như Ngày Prime, khách hàng đặt đơn hàng nhanh hơn nhiều so với tốc độ hoạt động của các nhà kho.
Các ứng dụng thương mại điện tử, như Amazon.com, phải có khả năng mở rộng để xử lý lưu lượng không đoán trước. Khi một khách hàng đặt đơn hàng, một bus sự kiện như Amazon EventBridge nhận sự kiện và tất cả các dịch vụ micro hạ lưu có thể chọn sự kiện đơn hàng để xử lý. Bởi vì mỗi dịch vụ micro có thể thất bại một cách độc lập, không có điểm thất bại đơn lẻ.
Sự phối hợp linh hoạt giữa các nhóm phát triển
Các kiến trúc dựa trên sự kiện thúc đẩy sự độc lập của các nhóm phát triển nhờ sự liên kết lỏng lẻo giữa người xuất bản và người đăng ký. Ứng dụng có thể đăng ký nhận các sự kiện với yêu cầu định tuyến và logic kinh doanh riêng biệt so với người xuất bản và các người đăng ký khác. Điều này cho phép người xuất bản và người đăng ký thay đổi một cách độc lập với nhau, cung cấp nhiều linh hoạt hơn cho kiến trúc tổng thể.
Các ứng dụng không liên kết cũng cho phép bạn xây dựng các tính năng mới nhanh hơn. Thêm tính năng mới hoặc mở rộng các tính năng hiện có có thể đơn giản hơn với các kiến trúc dựa trên sự kiện vì bạn chỉ cần thêm sự kiện mới hoặc sửa đổi các sự kiện hiện có. Quá trình này loại bỏ sự phức tạp trong ứng dụng của bạn.
Kết luận
Trong bài viết này, bạn sẽ tìm hiểu về những thách thức trong việc phát triển ứng dụng với kiến trúc request-response. Trong kiến trúc request-response, khách hàng phải gửi một yêu cầu và đợi nhận được phản hồi trước khi tiếp tục công việc tiếp theo của mình. Khi ứng dụng phức tạp hóa, kiến trúc chặt chẽ này có thể gây ra vấn đề. Kiến trúc dựa trên sự kiện có thể tăng cường khả năng mở rộng, sự chịu lỗi và tốc độ phát triển bằng cách tách rời các thành phần của ứng dụng của bạn.
Để biết thêm nội dung về serverless, hãy truy cập serverlessland.com.