5 回答

TA貢獻1875條經(jīng)驗 獲得超3個贊
上面的回答中的方式是使用同步的 HTTP 請求,這樣的好處是簡單不容易出錯,缺點肯定就是效率會偏低和占用不必要的 CPU 資源。
講下我的思路:
首先,A->B 這塊,既然使用的是 SpringBoot,了解下 SpringMVC 的異步模式(關(guān)鍵類:
DefferedResult
,WebAsyncTask
)B->C 這塊,既然 B->C 是發(fā)送 HTTP 請求,那么可以考慮異步的 HTTP 操作(可以簡單了解下 okhttp 或者 httpclient 中的異步操作)。使用一個線程專門發(fā)送異步 HTTP 請求,在異步 HTTP 的回調(diào)中,可以將請求的結(jié)果寫入到消息隊列(如果業(yè)務(wù)不復(fù)雜可以直接使用
BlockingQueue
);另一個線程不停的(或者每隔一小段時間)從隊列中取出消息并進行消費:即根據(jù)訂單號將結(jié)果進行歸檔,通過某個訂單號對應(yīng)的已歸檔請求的個數(shù)來判斷是否將結(jié)果返回給 A。至于線程的管理,如果將異步 HTTP 請求交給了 okhttp 或者 httpclient,那么之外涉及的線程不多,可能沒有必要使用 akka —— 可以考慮下 SpringMVC 內(nèi)置的線程池。

TA貢獻2037條經(jīng)驗 獲得超6個贊
不能讓C提供一個批量激活的接口嗎?
當(dāng)然估計是不能,那我說下我的想法,其實業(yè)務(wù)場景不復(fù)雜,可以直接用線程處理,在所有線程處理完之前阻塞住主線程,大概代碼如下:
//n張卡
List<Card> cardList = new ArrayList<>();
//線程池處理請求
ExecutorService executorService = Executors.newFixedThreadPool(8);
final CountDownLatch cdl = new CountDownLatch(cardList.size());
final List<String> result = new ArrayList<>();
for (Object card : cardList) {
executorService.execute(new Runnable() {
@Override
public void run() {
//請求C并拿到響應(yīng)
result.add(post(card));
cdl.countDown();
}
});
}
cdl.await();
添加回答
舉報