2015-05-14 58 views
0

我有一個棘手的問題,我正在運行的web服務。我用一種很好的方式解決了這個問題,但我想知道我能做些什麼更好的事情。同步來自多臺機器的外部Web請求

基本上我正在運行一個Java web服務(在AWS Elastic Beanstalk中,所以跨多個服務器)。該服務返回其緩存的結果,但如果請求的輸入不存在於緩存(SQL Server數據庫)中,則該服務必須調用外部供應商。這花錢,所以我想確保這個調用在多個機器上不重複,如果他們恰好在同一時間接收到請求(即在第一臺機器收到供應商響應並將其寫入數據庫之前)。

目前我正在處理這個問題,通過在進行外部調用之前向數據庫中寫入「IsPending = 1」行,然後將該行更新爲「IsPending = 0」並在呼叫返回時填充接收的數據。在任何機器發出外部呼叫之前,它會檢查數據庫中的待處理行。如果找到一個,它會在活動線程上重複調用.sleep(),每等待一次(當前爲30ms)後再次檢查DB。如果它過度等待,它只是爲自己打電話(但到目前爲止,這並非真的必須發生)。

所以雖然這種解決方案大多可以工作,但它顯然相當複雜,並不能解決100%的情況。正如我之前提到的,我正在使用AWS,因此我有他們的工具供我使用。我很想知道是否有更好的方法來解決這個問題。謝謝!

+0

您的解決方案聽起來不錯。 – ZhongYu

+0

如何使用隊列?當您的本地數據庫中不存在條目時,將請求放入隊列中,只有一個進程(服務器)將讀取該請求,並且其他服務器始終輪詢數據庫。此外,可以使用Lamda函數+觸發器自動讓您的實例知道隊列請求何時完成,並從整個解決方案中刪除輪詢? –

回答

1

您可以在查找供應商價值時持有的交易上使用交易隔離級別Connection.TRANSACTION_SERIALIZABLE。使用它將鎖定數據庫行並阻止該行的所有選擇,直到您提交事務。數據庫將處理所有等待您,並且可以將異常情況作爲鎖等待超時SQLException處理。

+0

這是我希望得到的那種答案。我將繼續前進。感謝您的建議! – thomas

0

您可以在應用程序中設計一個編排層來處理與外部服務的所有交互。

  • 來自多臺機器的請求會通過此層訪問來自外部服務的信息。
  • 這些請求可以按順序同步,以便只有一個外部請求正在執行,而其他請求則進入等待狀態。

此方法的其他好處是,如果您對外部服務格式進行任何更改,或者您決定將其全部替換爲另一個位置,則可以單獨更新。

+0

我已經考慮過這個問題,但是我覺得如果編排層在一臺機器上運行,這纔有意義。我需要能夠在高負載時水平擴展我的應用程序,並且每個級別至少保留兩臺機器(因此一臺機器停機並不會降低我的服務)。 – thomas

相關問題