Gần đây, lập trình phản ứng ngày càng mở rộng và được nhiều ngôn ngữ tiếp cận. Nhưng trong Java, liệu bạn có thấy mới mẻ không? Vậy thì loạt bài viết này là dành cho bạn!
Trong loạt bài này, tôi sẽ đề cập đến các vấn đề như lập trình phản ứng, Spring Webflux, Project Reactor và Netty.
Vấn đề:
Chúng ta mong muốn các ứng dụng của mình có thể mở rộng, sử dụng tài nguyên ngày càng hiệu quả, thời gian trễ phải tối thiểu và phản hồi nhanh chóng đối với các yêu cầu của chúng ta. Chúng ta xử lý các yêu cầu cạnh tranh (mỗi luồng tiêu thụ một chút bộ nhớ), các API truyền thống hoạt động theo cách đồng bộ và chặn.
Để giải quyết vấn đề này, chúng ta có các Callback và Future:
- Callback không dễ đọc và khó bảo trì, chúng phức tạp (có thể tạo ra “callback hell”) và không thể trả về bất kỳ giá trị nào.
- Future: trả về một instance của loại Future và khó mở rộng cho nhiều thao tác bất đồng bộ, từ Java 8 có Completable Future hỗ trợ lập trình chức năng và dễ dàng sử dụng các thao tác bất đồng bộ, tuy nhiên, không phải là lựa chọn tốt cho các cuộc gọi bất đồng bộ với nhiều mục.
Cách phát triển API thay thế
- Asynchronous and non-blocking
- Outside the on-demand thread model
- Decreases the number of threads created
Và lập trình reactive ra đời, vậy điều gì khác biệt ở nó?
- Asynchronous and non-blocking
- Luồng dữ liệu dưới dạng event/message
- Lập trình hướng chức năng.
- BackPressure trong luồng dữ liệu
Chúng ta hãy chú ý hơn đến phần luồng dữ liệu:
Dữ liệu có thể đến từ cơ sở dữ liệu, tệp tin bên ngoài, dịch vụ tích hợp, ứng dụng khác, v.v. Đối với mỗi mục của nguồn dữ liệu này, chúng ta có một event hoặc message được kích hoạt, sau khi thực hiện event/message đó, chúng ta có tin nhắn lỗi hoặc hoàn tất.
Ví dụ, đối với yêu cầu lưu dữ liệu, chúng ta có sự kiện onNext(Product):
List<Product> products = productRepository.getAllProducts();
Khi chúng ta gọi dữ liệu từ cơ sở dữ liệu chẳng hạn, cuộc gọi trả về và đối với mỗi mục, một sự kiện onNext(Product) được khởi chạy và khi hoàn tất việc liệt kê, chúng ta có sự kiện onComplete() để thông báo rằng yêu cầu của chúng ta đã kết thúc.
Nếu yêu cầu của chúng ta gặp lỗi thì sao?
Thay vì trả về sự kiện onComplete(), chúng ta sẽ có sự kiện OnError() và không có nội dung mong đợi.
Đặc tả Luồng Phản ứng
Là tập hợp các đặc tả cho việc sử dụng luồng, được tạo bởi các công ty như Pivotal và Netflix, trong đó có:
- Publishers: Publisher interface cung cấp một số lượng phần tử không giới hạn theo cách tuần tự và phát hành chúng theo yêu cầu nhận được từ các Subscribers (tôi sẽ giải thích tiếp theo). Publishers có thể phục vụ nhiều Subscribers động tại các thời điểm khác nhau.
public interface Publisher<T> { public void subscribe(Subscriber<? super T> s); }
- Subscriber: Chỉ nhận một cuộc gọi đến OnSubscribe sau khi bạn truyền một instance của Subscriber tới Publisher.subscribe(Subscriber). Không có thông báo nào được nhận cho đến khi Subscription.request(long) được gọi. Sau khi cuộc gọi bắt đầu: Một hoặc nhiều cuộc gọi onNext(Object) được khởi chạy cho đến khi đạt số lượng tối đa do Subscription.request(long) xác định. Một cuộc gọi lỗi onError(Throwable) duy nhất hoặc hoàn thành yêu cầu onComplete(). Yêu cầu này có thể được báo hiệu qua Subscription.request(long) bất cứ khi nào instance của Subscriber có thể xử lý thêm.
public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete(); }
Và Subscription:
public interface Subscription { public void request(long n); public void cancel(); }
- Processor: Đại diện cho một bước xử lý, vừa là Subscriber vừa là Publisher chấp nhận cả hai tiêu chuẩn.
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> { }
T là kiểu phần tử được báo hiệu tới Subscriber.
R là kiểu phần tử được báo hiệu tới Publisher.
Đây là phần đầu tiên của loạt bài viết, trong đó chúng ta đã nói về một số điểm và lợi ích của lập trình reactive, trong bài tiếp theo tôi sẽ đề cập đến lý do dẫn đến việc tạo ra Webflux và sự khác biệt của nó so với Spring MVC.
Nguồn: https://dev.to/kamilacode/spring-webflux-reactive-java-applications-part-1-330j