遠程調用由于涉及到服務器和客戶端等多個節點以及需要通過網絡通訊等,會引入更多的故障可能。本地調用的語義都是恰好一次,不會多也不會少。而遠程調用的語義就比較復雜,依據三個選擇將產生不同的語義:
1)重發請求消息:客戶端是否重發請求,直到收到應答或者認定服務器故障為止
2)過濾重復消息:當客戶端重發請求時候,服務器是否過濾重復的請求
3)重傳結果:服務器是否保存結果消息的歷史,以便服務器不用重新執行操作就能重傳結果。
對這三個選擇的不同組合將產生三種可能的遠程調用語義:
重發請求消息 過濾重復消息 重傳結果 語義
否 不適用 不適用 或許
是 否 重新執行操作 至少一次
是 是 重傳結果 至多一次
或許調用語義:遠程方法可能執行一次,或者根本不執行(在消息遺漏或者服務器崩潰的情況下)
至少一次調用語義:遠程方法要嘛至少執行一次并返回結果,要嘛返回一個異常。因為啟用了重發請求消息,服務器也重新執行操作,因此遠程調用至少執行一次,除非服務器崩潰;但是,由于服務器重新執行操作,如果調用不是冪等的,那么多次重復執行將產生副作用疊加,可能不符合預期需求。對于冪等操作,至少一次調用語義是可以接受的。
至多一次調用語義:在此語義下,服務器會過濾重復的請求,并且緩存執行的結果重傳而非重新執行。因此遠程調用同樣也是返回調用結果,或者一個異常。在返回結果的情況下,可以確認服務器恰好執行一次,與本地調用語義一樣,不會有副作用疊加。如果返回異常,就是通知調用者沒有返回結果,遠程調用要嘛執行了一次,要嘛根本沒有執行??傊?,遠程調用至多執行一次。
Java RMI的調用語義是至多一次。
1)重發請求消息:客戶端是否重發請求,直到收到應答或者認定服務器故障為止
2)過濾重復消息:當客戶端重發請求時候,服務器是否過濾重復的請求
3)重傳結果:服務器是否保存結果消息的歷史,以便服務器不用重新執行操作就能重傳結果。
對這三個選擇的不同組合將產生三種可能的遠程調用語義:
重發請求消息 過濾重復消息 重傳結果 語義
否 不適用 不適用 或許
是 否 重新執行操作 至少一次
是 是 重傳結果 至多一次
或許調用語義:遠程方法可能執行一次,或者根本不執行(在消息遺漏或者服務器崩潰的情況下)
至少一次調用語義:遠程方法要嘛至少執行一次并返回結果,要嘛返回一個異常。因為啟用了重發請求消息,服務器也重新執行操作,因此遠程調用至少執行一次,除非服務器崩潰;但是,由于服務器重新執行操作,如果調用不是冪等的,那么多次重復執行將產生副作用疊加,可能不符合預期需求。對于冪等操作,至少一次調用語義是可以接受的。
至多一次調用語義:在此語義下,服務器會過濾重復的請求,并且緩存執行的結果重傳而非重新執行。因此遠程調用同樣也是返回調用結果,或者一個異常。在返回結果的情況下,可以確認服務器恰好執行一次,與本地調用語義一樣,不會有副作用疊加。如果返回異常,就是通知調用者沒有返回結果,遠程調用要嘛執行了一次,要嘛根本沒有執行??傊?,遠程調用至多執行一次。
Java RMI的調用語義是至多一次。