亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

導(dǎo)讀:微服務(wù)架構(gòu)下的支付系統(tǒng),由于其需要在性能和一致性之間做很多權(quán)衡,帶來設(shè)計(jì)和實(shí)現(xiàn)的復(fù)雜性。Airbnb的支付系統(tǒng)需要對接全球很多個(gè)國家的支付系統(tǒng),因此帶來很大的復(fù)雜性。本文詳細(xì)論述了Airbnb如何使用分布式事務(wù)的相關(guān)技術(shù)來保證支付系統(tǒng)的數(shù)據(jù)一致性和性能,十分值得一讀。

過去幾年中,Airbnb一直在將其基礎(chǔ)架構(gòu)遷移到SOA。相比單體應(yīng)用,SOA提供了許多優(yōu)勢,例如支持開發(fā)人員專業(yè)化和加速迭代的能力。然而,這也對計(jì)費(fèi)和支付程序提出了挑戰(zhàn),因?yàn)镾OA使維護(hù)數(shù)據(jù)完整性變得更加困難。對服務(wù)API的調(diào)用,該服務(wù)對下游服務(wù)進(jìn)行進(jìn)一步的API調(diào)用,其中每個(gè)服務(wù)改變狀態(tài)都可能具有副作用,等同于執(zhí)行復(fù)雜的分布式事務(wù)。

為了確保所有服務(wù)之間的數(shù)據(jù)一致性,可以使用兩階段提交之類的協(xié)議。如果不用這樣的協(xié)議,數(shù)據(jù)一致性就難以保證。在分布式系統(tǒng)中請求不可避免地會失敗(連接會在某些時(shí)候丟失并超時(shí),尤其是對于包含多個(gè)網(wǎng)絡(luò)請求的事務(wù)。

分布式系統(tǒng)中使用三種不同的常用技術(shù)來實(shí)現(xiàn)最終的一致性:讀修復(fù),寫修復(fù)和異步修復(fù)。每種方法各有利弊。三種方式在我們的支付系統(tǒng)中都有使用。

異步修復(fù)通過服務(wù)器負(fù)責(zé)運(yùn)行數(shù)據(jù)一致性檢查來實(shí)現(xiàn),例如表掃描,lambda函數(shù)和cron job。此外,從服務(wù)器到客戶端的異步通知廣泛用于支付行業(yè),以保持客戶端的一致性。異步修復(fù)以及通知可以與讀寫修復(fù)技術(shù)結(jié)合使用,提供第二道防線,并在解決方案復(fù)雜性方面起到作用。

本文中描述的解決方案使用了寫修復(fù),其中從客戶端到服務(wù)器的每次寫入調(diào)用都嘗試修復(fù)不一致狀態(tài)。寫修復(fù)要求客戶端更加智能(稍后我們將對此進(jìn)行擴(kuò)展討論),并允許重復(fù)發(fā)出相同的請求,而不必維護(hù)狀態(tài)(除了重試)。因此,客戶端可以按自己的需求來達(dá)到最終的一致性,從而使他們能夠控制用戶體驗(yàn)。在實(shí)現(xiàn)寫修復(fù)時(shí),冪等性是一個(gè)非常重要的屬性。

 

什么是冪等?

API請求具有冪等性即客戶端可以重復(fù)進(jìn)行相同的調(diào)用,結(jié)果將是相同的。換句話說,發(fā)出多個(gè)相同的請求應(yīng)該與發(fā)出單個(gè)請求具有相同的效果。

這種技術(shù)通常用于涉及資金流動的計(jì)費(fèi)和支付系統(tǒng),即支付請求必須完全處理一次(也稱為“確切一次交付”)。重要的是,如果多次調(diào)用移動資金操作,系統(tǒng)最多只能移動一次資金。這對Airbnb Payments API至關(guān)重要,以避免多次支付。

冪等性允許來自客戶端的多個(gè)相同請求使用API的自動重試機(jī)制來達(dá)到最終一致性。這種方式在具有冪等性的客戶端 - 服務(wù)器中是常見的,并且在我們的系統(tǒng)中也是如此。

下圖說明了重復(fù)請求和理想冪等行為的簡單場景。無論收費(fèi)多少,客戶最多支付一次費(fèi)用。

支付核心系統(tǒng)設(shè)計(jì):Airbnb的分布式事務(wù)方案簡介

 

問題描述

保證我們的支付系統(tǒng)最終的一致性至關(guān)重要。冪等性是在分布式系統(tǒng)中實(shí)現(xiàn)這一點(diǎn)的理想機(jī)制。在SOA世界中,我們將不可避免地遇到問題。例如,假如服務(wù)沒有響應(yīng),客戶端將如何恢復(fù)?如果Response丟失或客戶超時(shí)怎么辦?如果競爭條件導(dǎo)致用戶點(diǎn)擊“預(yù)訂”兩次呢?我們的需求包括:

  • 我們需要一個(gè)通用但可配置的冪等解決方案,而不是實(shí)現(xiàn)針對特定用例的自定義解決方案,以便在Airbnb的各種支付服務(wù)中使用。

  • 雖然正在迭代基于SOA的支付產(chǎn)品,但我們無法在數(shù)據(jù)一致性上妥協(xié)。

  • 我們需要超低延遲,因此構(gòu)建單獨(dú)的冪等服務(wù)不能滿足延遲要求。最重要的是,該服務(wù)將遇到上述問題。

  • 隨著Airbnb使用SOA擴(kuò)展其工程組織,讓每個(gè)開發(fā)人員專注于數(shù)據(jù)完整性和最終的一致性是非常低效的。我們希望業(yè)務(wù)開發(fā)免受這些麻煩,保證他們能夠?qū)W⒂诋a(chǎn)品開發(fā)并更快地進(jìn)行迭代。

此外,代碼可讀性,可測試性和故障排除能力的相當(dāng)大的權(quán)衡被認(rèn)為是非主導(dǎo)因素。

 

解決方案

我們希望能夠唯一地識別每個(gè)請求。此外,我們需要準(zhǔn)確跟蹤和管理特定請求在其生命周期中的位置。

我們在多種支付服務(wù)中實(shí)施并使用了“Orpheus”,這是一種通用的冪等庫。Orpheus是傳說中的希臘神話英雄。

我們選擇了實(shí)現(xiàn)冪等庫作為解決方案,因?yàn)樗峁┑脱舆t,同時(shí)仍然提供高速變更的產(chǎn)品代碼和低速變更的系統(tǒng)管理代碼之間的隔離。在高層次上,它包含以下:

  • 冪等key被傳遞到框架中,表示單個(gè)冪等請求

  • 始終從主數(shù)據(jù)庫讀取和寫入(為了一致性)冪等信息表

  • 通過使用JAVA lambda組合數(shù)據(jù)庫事務(wù),確保原子性

  • 錯(cuò)誤被分類為“可重試”或“不可重試”

接下來我們將詳細(xì)說明具有冪等性保證的復(fù)雜分布式系統(tǒng)如何能夠自我修復(fù)并達(dá)到最終一致。我們還將介紹一些該方案應(yīng)該注意的設(shè)計(jì)權(quán)衡和帶來的額外的復(fù)雜性。

 

最小化數(shù)據(jù)庫提交

冪等系統(tǒng)的關(guān)鍵要求之一是只產(chǎn)生兩個(gè)結(jié)果,即成功或失敗,具有一致性。否則,數(shù)據(jù)有偏差可能導(dǎo)致數(shù)小時(shí)排查錯(cuò)誤時(shí)間和付款出問題。由于數(shù)據(jù)庫提供ACID屬性,因此數(shù)據(jù)庫事務(wù)可以有效地用于原子寫入,確保一致性。一次數(shù)據(jù)庫提交可以保證其作為一個(gè)單元的一致性。

Orpheus假設(shè)每個(gè)標(biāo)準(zhǔn)API請求都分為三個(gè)不同的階段:Pre-RPC,RPC和Post-RPC。

“RPC”是指客戶端向遠(yuǎn)程服務(wù)器發(fā)出請求并等待該服務(wù)器響應(yīng)的過程。在支付API的上下文中,我們將RPC稱為對下游服務(wù)的請求,其可以包括外部支付服務(wù)和收單銀行等。簡而言之,如下是每個(gè)階段發(fā)生的事情:

  • Pre-RPC:付款請求的詳細(xì)信息記錄在數(shù)據(jù)庫中。

  • RPC:請求通過網(wǎng)絡(luò)對外部服務(wù)進(jìn)行實(shí)時(shí)處理,并收到響應(yīng)。這是一個(gè)執(zhí)行冪等計(jì)算或RPC的過程(例如,如果是重試嘗試,則首先查詢事務(wù)狀態(tài))。

  • Post-RPC:來自外部服務(wù)的響應(yīng)的詳細(xì)信息記錄在數(shù)據(jù)庫中,包括其是否成功以及錯(cuò)誤請求是否可重試。

為了保持?jǐn)?shù)據(jù)完整性,我們遵循兩個(gè)基本規(guī)則:

  • 在Pre-RPC和Post-RPC階段,沒有遠(yuǎn)程服務(wù)交互

  • RPC階段中沒有數(shù)據(jù)庫交互

我們希望避免將網(wǎng)絡(luò)調(diào)用與數(shù)據(jù)庫操作混在一起。在pre-RPC和post-RPC階段網(wǎng)絡(luò)調(diào)用(RPC)易受攻擊的,并可能導(dǎo)致連接池快速耗盡和性能下降之類的不良后果。簡而言之,網(wǎng)絡(luò)調(diào)用本質(zhì)上是不可靠的。因此,我們將Pre和Post-RPC階段處理數(shù)據(jù)庫事務(wù)。

我們還想要說明單個(gè)API請求可能包含多個(gè)RPC。 Orpheus支持多RPC請求,但在這篇文章中,我們只想用簡單的單RPC案例來說明我們的思考過程。

如下面的示例圖所示,所有Pre-RPC和Post-RPC階段中的數(shù)據(jù)庫提交都合并為一個(gè)數(shù)據(jù)庫事務(wù),這確保了原子性 。動機(jī)是系統(tǒng)應(yīng)該以可恢復(fù)的方式出現(xiàn)故障。例如,如果在多次數(shù)據(jù)庫提交過程中有幾次失敗,那么系統(tǒng)地跟蹤每個(gè)失敗發(fā)生的位置將非常困難。請注意,所有網(wǎng)絡(luò)通信(RPC)都與數(shù)據(jù)庫事務(wù)明確分開。

支付核心系統(tǒng)設(shè)計(jì):Airbnb的分布式事務(wù)方案簡介

這里的數(shù)據(jù)庫提交包括冪等庫的數(shù)據(jù)庫提交和應(yīng)用程序數(shù)據(jù)庫提交,所有這些提交都組合在同一個(gè)代碼塊中。 如果不小心組織,這里的代碼就會非常混亂。 我們認(rèn)為產(chǎn)品開發(fā)人員不應(yīng)該負(fù)責(zé)保證冪等庫的操作。

 

Java Lambdas 組合事務(wù)

值得慶幸的是,Java lambda表達(dá)式可以將多個(gè)提交無縫地組合成單個(gè)數(shù)據(jù)庫事務(wù),也不會影響可測試性和代碼可讀性。

下面是一個(gè)示例,簡化了Orpheus的使用,其中Java lambdas如下:

public Response processPayment(InitiatePaymentRequest request, UriInfo uriInfo) throws YourCustomException {
 return orpheusManager.process( request.getIdempotencyKey, uriInfo, // 1. Pre-RPC  -> { // Record payment request information from the request object PaymentRequestResource paymentRequestResource = recordPaymentRequest(request); return Optional.of(paymentRequestResource); }, // 2. RPC (isRetry, paymentRequest) -> { return executePayment(paymentRequest, isRetry); }, // 3. Post RPC - record response information to database (isRetry, paymentResponse) -> { return recordPaymentResponse(paymentResponse); });}
這是源代碼的簡化版本:
public <R extends Object, S extends Object, A extends IdempotencyRequest> Response process( String idempotencyKey, UriInfo uriInfo, SetupExecutable<A> preRpcExecutable, // Pre-RPC lambda ProcessExecutable<R, A> rpcExecutable, // RPC lambda PostProcessExecutable<R, S> postRpcExecutable) // Post-RPC lambda throws YourCustomException { try { // Find previous request (for retries), otherwise create IdempotencyRequest idempotencyRequest = createOrFindRequest(idempotencyKey, apiUri); Optional<Response> responseoptional = findIdempotencyResponse(idempotencyRequest);
 // Return the response for any deterministic end-states, such as // non-retryable errors and previously successful responses if (responseOptional.isPresent) { return responseOptional.get; }
 boolean isRetry = idempotencyRequest.isRetry; A requestObject = ;
 // STEP 1: Pre-RPC phase: // Typically used to create transaction and related sub-entities // Skipped if request is a retry if(!isRetry) { // Before a request is made to the external service, we record // the request and idempotency commit in a single DB transaction requestObject = dbTransactionManager.execute( tc -> { final A preRpcResource = preRpcExecutable.execute; updateIdempotencyResource(idempotencyKey, preRpcResource);
 return preRpcResource; }); } else { requestObject = findRequestObject(idempotencyRequest); }
 // STEP 2: RPC phase: // One or more network calls to the service. May include // additional idempotency logic in the case of a retry // Note: NO database transactions should exist in this executable R rpcResponse = rpcExecutable.execute(isRetry, requestObject);
 // STEP 3: Post-RPC phase: // Response is recorded and idempotency information is updated, // such as releasing the lease on the idempotency key. Again, // all in one single DB transaction S response = dbTransactionManager.execute( tc -> { final S postRpcResponse = postRpcExecutable.execute(isRetry, rpcResponse); updateIdempotencyResource(idempotencyKey, postRpcResponse);
 return postRpcResponse; });
 return serializeResponse(response); } catch (Throwable exception) { // If CustomException, return error code and response based on // ‘retryable’ or ‘non-retryable’. Otherwise, classify as ‘retryable’ // and return a 500. }}

我們沒有實(shí)現(xiàn)嵌套數(shù)據(jù)庫事務(wù),而是將Orpheus和應(yīng)用程序中的數(shù)據(jù)庫指令組合成單個(gè)數(shù)據(jù)庫事務(wù),傳遞Java 閉包。

開發(fā)人員必須預(yù)先考慮好,才能保代碼的可讀性和可維護(hù)性。 他們還需要始終如一地評估適當(dāng)?shù)囊蕾囮P(guān)系和數(shù)據(jù)傳遞。 現(xiàn)在需要將API調(diào)用重構(gòu)為三個(gè)部分,這可能會限制開發(fā)人員編寫代碼的方式。 實(shí)際上,某些復(fù)雜的API調(diào)用實(shí)際上很難有效地分解為三步。 我們的服務(wù)實(shí)現(xiàn)了一個(gè)有限狀態(tài)機(jī),每次轉(zhuǎn)換都是使用StatefulJ的冪等步驟,可以在API調(diào)用中安全地復(fù)用冪等調(diào)用。

 

處理異常 - 重試還是不重試?

使用像Orpheus這樣的框架,服務(wù)器應(yīng)該知道何時(shí)可以重試請求,而何時(shí)不行。要做到這一點(diǎn),應(yīng)該以細(xì)致的處理異常,異常被分類為“可重試”或“不可重試”兩大類。這無疑為開發(fā)人員增加了一層復(fù)雜性,如果他們錯(cuò)誤使用,就會產(chǎn)生副作用。

例如,假設(shè)下游服務(wù)暫時(shí)宕機(jī),經(jīng)常被錯(cuò)誤地標(biāo)記為“不可重試”。這樣請求將無限期地“失敗”,并且后續(xù)重試請求將永遠(yuǎn)返回不可重試錯(cuò)誤。相反,如果異常被標(biāo)記為“可重試”(而實(shí)際應(yīng)該是“不可重試”且需要人工干預(yù)),則可能會發(fā)生雙重付款。

通常,我們認(rèn)為由網(wǎng)絡(luò)和基礎(chǔ)架構(gòu)問題(5XX HTTP狀態(tài))導(dǎo)致的意外運(yùn)行時(shí)異常是可重試的。我們希望這些錯(cuò)誤是暫時(shí)的,我們希望稍后重試相同的請求最終會成功。

我們將驗(yàn)證錯(cuò)誤(例如無效輸入和狀態(tài)(例如,您無法退還退款))分類為不可重試(4XX HTTP狀態(tài)) - 我們預(yù)計(jì)同一請求的所有后續(xù)重試都會以相同方式失敗。因此創(chuàng)建了一個(gè)自定義的通用異常類來處理這些情況,默認(rèn)為“不可重試”,對于其他情況,它們被歸類為“可重試”異常。

至關(guān)重要的是,每個(gè)請求的請求有效負(fù)載保持不變并且永遠(yuǎn)不會發(fā)生變化,否則會破壞冪等請求的定義。

支付核心系統(tǒng)設(shè)計(jì):Airbnb的分布式事務(wù)方案簡介

當(dāng)然,需要謹(jǐn)慎處理更復(fù)雜的邊緣情況,例如在不同的上下文中適當(dāng)?shù)靥幚鞵ointerException。 例如,由于數(shù)據(jù)庫鏈接暫時(shí)出問題而返回的空值與來自客戶端或來自第三方請求中的錯(cuò)誤空字段不同。

 

客戶端

正如本文開頭所提到的,在寫修復(fù)系統(tǒng)中客戶端需要更加智能。 在與使用像Orpheus這樣的冪等性庫的服務(wù)進(jìn)行交互時(shí),它必須做到:

  • 為每個(gè)新請求傳遞一個(gè)唯一的冪等鍵; 重試的時(shí)候重用相同的冪等鍵。

  • 在調(diào)用服務(wù)之前將這些冪等鍵保留在數(shù)據(jù)庫中(以后用于重試)。

  • 正確成功響應(yīng)后取消冪等鍵(或者置空)。

  • 確保不允許在重試中改變請求有效負(fù)載。

  • 根據(jù)業(yè)務(wù)需求仔細(xì)設(shè)計(jì)和配置自動重試策略(使用指數(shù)退避或隨機(jī)等待時(shí)間(“抖動”)以避免驚群問題)。

 

如何選擇冪等鍵?

選擇冪等鍵是至關(guān)重要的 - 客戶可以根據(jù)要選擇保證請求級冪等性或?qū)嶓w級冪等性。使用什么鍵將取決于業(yè)務(wù),但請求級冪等性是最直接和最常見的。

對于請求級冪等性,應(yīng)從客戶端選擇隨機(jī)且唯一的鍵,以確保整個(gè)實(shí)體集合級別的冪等性。例如,如果我們想要為預(yù)訂允許多種不同的付款方式,我們只需要確保冪等鍵是不同的。 UUID是一個(gè)很好的示例格式。

實(shí)體級冪等性比請求級冪等性更加嚴(yán)格。假設(shè)我們要確保ID為1234的10美元付款只能退還5美元,由于我們可以在技術(shù)上兩次提交5美元的退款申請,所以希望使用基于實(shí)體模型的冪等鍵來確保實(shí)體級的冪等性。示例格式為“payment-1234-refund”。因此,對于唯一付款的每個(gè)退款請求都將在實(shí)體級別保證冪等(付款1234)。

 

每個(gè)API請求都有到期租約

由于多次用戶點(diǎn)擊或客戶端激進(jìn)的重試策略,可能會觸發(fā)多個(gè)相同的請求。 由于競態(tài)條件,可能會導(dǎo)致多次支付。 為了避免這些情況,在框架的幫助下,每個(gè)API請求都需要獲取冪等鍵上的數(shù)據(jù)庫行級鎖。 這授予給定請求進(jìn)一步繼續(xù)的租約或許可。

租約帶有到期時(shí)間,以涵蓋服務(wù)器端存在超時(shí)的情況。 如果沒有響應(yīng),則在當(dāng)前租約到期后才重試API請求。 應(yīng)用程序可以根據(jù)需要配置租約到期和RPC超時(shí)時(shí)間。 經(jīng)驗(yàn)法則是具有比RPC超時(shí)更長的租約到期時(shí)間。

Orpheus還為冪等鍵提供了一個(gè)最大可重試窗口,以提供安全網(wǎng),以避免意外系統(tǒng)行為導(dǎo)致的惡意重試。

 

記錄到Response

我們還記錄Response,以維護(hù)和監(jiān)控冪等行為。 當(dāng)客戶端對已達(dá)到確定性最終狀態(tài)的事務(wù)(例如,不可重試的錯(cuò)誤(例如,驗(yàn)證錯(cuò)誤)或成功響應(yīng))發(fā)出相同的請求時(shí),Response將記錄在數(shù)據(jù)庫中。

持久化Response確實(shí)是個(gè)性能權(quán)衡,保證客戶端能夠在后續(xù)重試時(shí)獲得快速響應(yīng),但此表將隨應(yīng)用程序吞吐量增長而增長。 如果我們不小心,該表會變得很臃腫。 解決方案是定期刪除超過特定時(shí)間范圍的數(shù)據(jù),但過早刪除數(shù)據(jù)也會產(chǎn)生負(fù)面影響。 除此之外,開發(fā)人員應(yīng)該謹(jǐn)慎,不要對Response實(shí)體和結(jié)構(gòu)進(jìn)行向后不兼容的更改。

 

使用主庫

在使用Orpheus讀取和寫入冪等信息時(shí),我們選擇直接從主庫執(zhí)行操作。在分布式數(shù)據(jù)庫系統(tǒng)中,在一致性和延遲之間存在權(quán)衡。由于我們無法容忍高延遲或讀取未提交的數(shù)據(jù),因此使用主庫對我們來說是最有意義的。如果數(shù)據(jù)庫系統(tǒng)沒有配置為強(qiáng)一致性(我們的系統(tǒng)由MySQL支持),那么使用副本進(jìn)行這些操作實(shí)際上可能會對冪等性產(chǎn)生不利影響。

例如,假設(shè)支付服務(wù)將其冪等信息存儲在從庫中。客戶端向支付服務(wù)提交付款請求,該請求最終成功,但客戶端由于網(wǎng)絡(luò)問題而未收到響應(yīng)。雖然當(dāng)前存儲在服務(wù)主庫中的響應(yīng)最終將最終寫入從庫,但是,由于有同步延遲,客戶端可能會進(jìn)行重試,由于同步延遲,服務(wù)可能會錯(cuò)誤地再次執(zhí)行付款,從而導(dǎo)致重復(fù)付款。下面的例子說明了僅僅幾秒鐘的復(fù)制延遲可能會對Airbnb造成重大財(cái)務(wù)影響。

支付核心系統(tǒng)設(shè)計(jì):Airbnb的分布式事務(wù)方案簡介

由于復(fù)制延遲導(dǎo)致重復(fù)支付

支付核心系統(tǒng)設(shè)計(jì):Airbnb的分布式事務(wù)方案簡介

使用主庫避免重復(fù)支付

當(dāng)使用單個(gè)主數(shù)據(jù)庫保證冪等性時(shí),可伸縮性會成為主要問題。我們通過按照冪等鍵對數(shù)據(jù)庫進(jìn)行分片來緩解這個(gè)問題。我們使用的冪等鍵具有高基數(shù)和均勻分布,使分片更加高效。

 

最后的想法

許多解決方案都可以緩解分布式系統(tǒng)中的一致性挑戰(zhàn)。 Orpheus是適用于我們的幾種產(chǎn)品之一,因?yàn)樗哂衅毡樾院洼p量級這樣的特性。開發(fā)人員可以在使用新服務(wù)時(shí)簡單地導(dǎo)入類庫,并且將冪等邏輯保存在獨(dú)立于應(yīng)用程序之外的單獨(dú)的抽象層。

如果不引入一些復(fù)雜性,就不可能實(shí)現(xiàn)最終的一致性。客戶端需要存儲和處理冪等鍵并實(shí)現(xiàn)自動重試機(jī)制。開發(fā)人員需要額外的上下文,并且在實(shí)現(xiàn)Java lambda時(shí)必須如外科外科手術(shù)一樣精確。處理異常時(shí)必須慎重。此外,由于當(dāng)前版本的Orpheus經(jīng)過了實(shí)戰(zhàn)考驗(yàn),我們也在不斷尋找改進(jìn)之處:改進(jìn)請求負(fù)載匹配以便進(jìn)行重試,改進(jìn)對數(shù)據(jù)庫模式更改和嵌套遷移的支持,在RPC階段主動限制數(shù)據(jù)庫訪問等等。

原文地址:

https://medium.com/airbnb-engineering/avoiding-double-payments-in-a-distributed-payments-system-2981f6b070bb

本文由方圓翻譯。轉(zhuǎn)載本文請注明出處,歡迎更多小伙伴加入翻譯及投稿文章的行列,詳情請戳公眾號菜單「聯(lián)系我們」。

分享到:
標(biāo)簽:Airbnb
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定