Spring Boot的微服務分散聚集模式教程與原始碼 - vinsguru

banq發表於2020-12-24

本教程演示分散聚集模式( Scatter Gather Pattern),它是分散式系統體系結構的企業整合模式之一。

讓我們考慮一個需要完成一組任務以完成業務工作流程的應用程式。如果這些任務彼此不依賴,那麼按順序執行它們就沒有意義。我們可以並行執行這些任務。

Spring Boot的微服務分散聚集模式教程與原始碼 - vinsguru分散收集模式可幫助我們分發這些任務,以實現任務/訊息/事件的並行處理,然後最終將響應彙總為單個響應,如上所示。

 

案例說明

一個使用者預訂機票的機票預訂應用程式。該應用程式將資訊傳送給所有航空公司,找到他們的票價,然後進行回覆。

Spring Boot的微服務分散聚集模式教程與原始碼 - vinsguru

由於我們的應用程式依賴於第三方API,並且我們需要為使用者提供最佳的使用者體驗,因此我們將向所有航空公司釋出使用者請求,無論在特定的超時時間內做出回應,我們都會收集所有結果並向我們顯示前5名交易使用者。

主應用程式甚至不知道有多少航空公司正在監聽請求。即使某些航空公司的服務無法正常執行,也不會影響我們的飛行應用程式。

 

案例SpringBoot實現

我們的專案依賴於超快速的NATS訊息伺服器。因此,要新增此依賴項:

<dependency>
    <groupId>io.nats</groupId>
    <artifactId>jnats</artifactId>
    <version>2.6.8</version>
</dependency>

釋出聚集模式的實現服務類ScatterGatherService:

@Service
public class ScatterGatherService {

    @Autowired
    private Connection nats;

    public Mono<FlightSearchResponse> broadcast(FlightSearchRequest flightSearchRequest){
        // create inbox
        String inbox = nats.createInbox();
        Subscription subscription = nats.subscribe(inbox);
        return Flux.generate((SynchronousSink<FlightSchedule[]> fluxSink) -> receiveSchedules(fluxSink, subscription))
                    .flatMap(Flux::fromArray)
                    .bufferTimeout(5, Duration.ofSeconds(1))
                    .map(list -> {
                        list.sort(Comparator.comparing(FlightSchedule::getPrice));
                        return list;
                    })
                    .map(list -> FlightSearchResponse.of(flightSearchRequest, list))
                    .next()
                    .doFirst(() -> nats.publish("flight.search", inbox, ObjectUtil.toBytes(flightSearchRequest)))
                    .doOnNext(i -> subscription.unsubscribe());
    }

    private void receiveSchedules(SynchronousSink<FlightSchedule[]> synchronousSink, Subscription subscription){
        try{
            Message message = subscription.nextMessage(Duration.ofSeconds(1));
            ObjectUtil.toObject(message.getData(), FlightSchedule[].class).ifPresent(synchronousSink::next);
        }catch (Exception e){
            synchronousSink.error(e);
        }
    }

} 
 

演示

傳送一個請求:http://localhost:8080/flight/Houston/LasVegas,收到如下所示的回覆:

{
   "searchRequest":{
      "from":"Houston",
      "to":"LasVegas"
   },
   "schedules":[
      {
         "date":"2021-01-02",
         "price":72,
         "airline":"DELTA"
      },
      {
         "date":"2020-12-28",
         "price":87,
         "airline":"UNITED_AIRLINE"
      },
      {
         "date":"2021-01-02",
         "price":109,
         "airline":"FRONTIER"
      },
      {
         "date":"2021-01-08",
         "price":229,
         "airline":"UNITED_AIRLINE"
      },
      {
         "date":"2021-01-02",
         "price":408,
         "airline":"DELTA"
      }
   ]
}

成功證明在我們的微服務架構中使用分散收集模式可以有效地並行處理任務並最終彙總結果。

原始碼可在此處獲得

更詳細點選標題見原文。

相關文章