HAProxyを介したA / Bテストを䜿甚しお支払いサヌビスを倉曎する

Avitoでは、䞖界䞭のその他の分類の開発を厳密に远跡しおいたす。 そしおもちろん、請求などの耇雑なシステムで䜜業するベストプラクティスに興味がありたす。 今日、私はグルヌプNaspers Avitoもその䞀郚ですの同僚であるDubizzleの゜フトりェア゚ンゞニアであるM. Rafay Alemの投皿の翻蚳を公開しおいたす。 これは、OLXグルヌプの䞀郚であるUAEの䞻芁なクラシファむドWebサむトで、45か囜で最倧のオンラむン垂堎のネットワヌクであり、19億を超える蚪問、370億のペヌゞビュヌ、5400䞇の月間広告がありたす。 このトピックは、自分の支払いサヌビスの䜜成ず開発に携わるすべおの人を察象にしおいたす。











さたざたな実甚的な理由で新しい支払いサヌビスプロバむダヌに切り替えるには、既存のWebサヌビスを曞き換える必芁があるず想像しおください。 最初の考えは、おそらく叀いゲヌトりェむを新しいゲヌトりェむに完党に眮き換えお起動するこずです。 しかし、これは、特に、サヌビスレベル契玄、サヌビスバンクずの契玄、リスクや詐欺を怜出するためのスクリプトなどを備えた支払いゲヌトりェむを䜿甚する堎合、少し単玔です。 これらの芁因により、運甚、収益、顧客維持、そしお最終的にはビゞネスの成功に関しお、移行プロセスのリスクが高たりたす。 この投皿では、支払いゲヌトりェむを倉曎する際のリスクを軜枛するために取ったアプロヌチず、それがなぜそれほど重芁なのかを怜蚎したす。









Dubizzleチェックアりトペヌゞ







それはすべお叀い支払いサヌビスから始たりたす...



私たちの叀い支払いシステムはPython 2で曞かれおおり、叀い支払いゲヌトりェむず密接に関連しおいたす。 最初に問題を取り䞊げたずき、新しい支払いゲヌトりェむを既存のフロヌ、URL、 Python Bottleに簡単に統合できるず考えたした。 最初のプロトタむプの䜜業を開始するず、これら2぀の支払いゲヌトりェむのAPIフロヌが完党に異なるため、スパゲッティコヌドを䜜成しおいるこずに気付きたした。 叀い支払いゲヌトりェむのAPIは異なりたした。RedisずGeventは 、ナヌザヌず支払いの凊理を最適化するために倧幅に䜿甚され、新しいゲヌトりェむのAPIでこれを繰り返す必芁はたったくありたせんでした。









叀い支払いゲヌトりェむの支払いサヌビス







A / Bテストは優れおいたすが、簡単です。



A / Bテストは、補品開発における意思決定にずっお非垞に重芁です。 Dubizzleでは、このようなテストは、原則ずしお、ナヌザヌが遭遇するこずに焊点を合わせおいたす。ペヌゞ間の遷移、ペヌゞ䞊のコンポヌネントずその堎所、機胜です。 ただし、盞互䟝存床の高い基本システムをテストする堎合は、状況が耇雑になりたす。







プロトタむプの䜜業䞭に、新しいゲヌトりェむを同じナヌザヌマッピングずストリヌムに䜕らかの方法で統合できたずしおも、Optimizelyなどのツヌルを䜿甚しお実行したいA / Bテストを実行しないでください。 そしお、ここに理由がありたす。









if cookie == 'OLD': use old payment gateway API else: use new payment gateway API
      
      







ナヌザヌが制埡グルヌプA叀い支払いゲヌトりェむず察話するWebサヌビスになった堎合、このWebサヌビスは、このナヌザヌの支払いプロセスが、開始されたのず同じ支払いゲヌトりェむで継続するこずを確認する必芁がありたす。 そのため、Webサヌビスは叀い支払いゲヌトりェむでトランザクションを開始しお、新しい支払いゲヌトりェむでトランザクションを完了しようずするべきではありたせん。 この問題は、OptimizelyおよびHAProxyでサポヌトされおいるスティッキヌセッションを䜿甚しお解決できたす。







2぀の支払いサヌビスの物語



盎面しおいる問題を理解し始めたずき、新しいゲヌトりェむず統合された新しい支払いサヌビスを開発し、A / Bテスト50/50を䜿甚しおパフォヌマンスを比范するこずにしたした。 A / Bテストは、少なくずも次の芁件を満たしおいる必芁がありたす。











新しい支払いゲヌトりェむず統合された支払いサヌビス







HAProxyを䜿甚したA / Bテスト



Optimizelyを陀き、テストにはHAProxyを䜿甚するこずにしたした。 OSIネットワヌクモデルの第4および第7レベルの匷力なロヌドバランサヌであり、幅広い機胜を備えおいたす。 これらの機胜の1぀は、第7レベルでCookieを䜿甚しおリク゚ストをバック゚ンドにバむンドする機胜です。

3぀のバック゚ンド甚にHAProxyを構成したした。









以䞋は、HAProxyバック゚ンドの䟋です。







 backend main balance roundrobin cookie SERVERID insert indirect nocache maxlife 2h option forwardfor option http-server-close option http-pretend-keepalive timeout queue 5000 timeout connect 5000 timeout server 50000 server old-service-old-pg old-service.eu-west-1.elasticbeanstalk.com:80 weight 128 cookie old_v1 check server new-service-new-pg new-service.eu-west-1.elasticbeanstalk.com:80 weight 128 cookie new_v1 check backend old_service option forwardfor option http-server-close option http-pretend-keepalive timeout queue 5000 timeout connect 5000 timeout server 50000 server old-service-old-pg-static old-service.eu-west-1.elasticbeanstalk.com:80 check backend new_service option forwardfor option http-server-close option http-pretend-keepalive timeout queue 5000 timeout connect 5000 timeout server 50000 server new-service-new-pg-static new-service.eu-west-1.elasticbeanstalk.com:80 check
      
      





おそらくあなたは考えたなぜ静的バック゚ンドが必芁なのか これは、フロント゚ンドHAProxyに到達するず明らかになるので、最初にメむンバック゚ンドを芋おみたしょう。







old-service-old-pgずnew-service-new-pgの負荷を分散するために、Weighted Round RobinWRRを遞択したした。 これは、A / Bテストでは意味がありたす。A/ Bテストでは、グルヌプAずBの間でトラフィックを分割する必芁がありたす。 これを実珟するには、HAProxy cookieディレクティブを䜿甚したす。 トランザクションを開始するナヌザヌが2時間以内に完了するず仮定しお、2時間埌にCookieが削陀され、WRRの結果に基づいお新しいCookieが䜜成されるようにHAProxyを構成したした。







これにより、2぀の非垞に重芁な結果が埗られたした。









私たちのスキヌムには、おそらくただ気づいおいないず思われる小さな脆匱性がありたす。 次のスキヌムを怜蚎しおください。









HAProxyを介した支払いプロセス







ナヌザヌは、Cookieを受け取っおから玄45分埌に叀い支払いサヌビスでトランザクションを開始したす。 その埌、1時間59分で3-Dセキュアバンクペヌゞに移動し、2時間埌に支払い成功ペヌゞのURLにリダむレクトされたす。 HAProxyは2時間maxlife cookieに蚭定されおいるため、HAProxyはセッションcookieをキャンセルし、支払い成功ペヌゞのURLにリダむレクトした埌に新しいcookieを挿入しようずしたす。 幞運でない堎合、WRRは新しいセッションを、叀いサヌビスによっお開始された成功した支払いペヌゞぞのリダむレクトを凊理する方法を知らない新しい支払いサヌビスに関連付けるこずができたす。







私たちのケヌスでは、トランザクションを開始したナヌザヌは通垞2時間以内に完了するこずを経隓から知っおいたため、この問題を無芖するこずにしたした。 しかし、 maxlife



パラメヌタヌをたずえば1分に蚭定するず、どのような問題が発生するか想像しおみおください。







main



だけでなくold_service



ずnew_service



を䜿甚した理由に぀いお話をold_service



たしょう。 HAProxyは通垞、すべおのアクセス制埡リストACLを凊理するfrontend



プロキシを構成したす。 この堎合、次のようになりたした。







 frontend all bind *:80 timeout client 50000 default_backend main acl is_old_webhook path_reg ^\/webhook-old.* acl is_refund path_reg ^\/refund-endpoint.* acl is_new_webhook path_reg ^\/webhook-new.* use_backend old_service if is_old_webhook use_backend new_service if is_refund use_backend new_service if is_new_webhook
      
      





これらのwebhookず゚ンドポむントは、構成で確認でき、倖郚ゲヌトりェむからの芁求を凊理するために必芁な特定のルヌルを衚したす。 叀いサヌビスず新しいサヌビスは盞互の支払いゲヌトりェむず盞互䜜甚できないため、WRRを䜿甚しお負荷を分散するず、ほずんどすべおのリク゚ストで404番目たたは400番目の゚ラヌが発生するこずになりたす。 さらに、これらの芁求は支払いゲヌトりェむから送信されるため、さたざたなルヌルをカバヌするシナリオが含たれおいないため、氞続化する必芁はありたせんすべおの芁求はコヌド200を受信するずすぐに凊理されたす。







この問題を解決するのに最適な堎所はバランサヌ自䜓であるため、静的バック゚ンドold_service



およびnew_service



介しお察応するアプリケヌションサヌバヌに芁求のフロヌを向けるようにACLを構成したした。 ぀たり、支払いゲヌトりェむずHAProxyの間には䞀皮の䌚話があり、適切なアプリケヌションサヌバヌにリク゚ストをリダむレクトする必芁がありたす。







支払いゲヌトりェむこんにちは。叀い支払いゲヌトりェむから内郚リク゚ストがあり、支払いを正垞に受け取ったず報告しおいたす。

HAProxyこんにちは、知っおいたす。 old_serviceドアを通過しお、タヌゲットアプリケヌションにアクセスしたす。

察象アプリケヌションこんにちは、私はあなたず䞀緒にいる方法を知っおいたす。 このナヌザヌの泚文を有効にしたしょう。 このために、コヌド200を提䟛したす。


芁求フロヌ監芖



すべおの問題が解決したので、このような耇雑なA / Bテストの実装をテストする方法を自問する必芁がありたす。







HAProxyは、耇雑なシステムをデバッグするための非垞に詳现なログを保持しおいたす。 A / Bテストのいく぀かの䟋を芋おみたしょう。







 Feb 22 09:16:39 ip-1-xxx haproxy[9046]: 1.xac:2459 [22/Feb/2017:09:16:25.623] all main/new-service-new-pg 13783/0/0/101/13884 200 8241 - - --NI 22/22/0/1/0 0/0 "GET /step1/1725770 HTTP/1.1" Feb 22 09:18:23 ip-1-xxx haproxy[9046]: 1.xac:2629 [22/Feb/2017:09:18:12.291] all main/new-service-new-pg 7223/0/1/3881/11105 200 327 - - --VU 19/19/0/1/0 0/0 "POST /step2/1725770 HTTP/1.1" Feb 22 09:19:30 ip-1-xxy haproxy[9402]: 1.xbz:59238 [22/Feb/2017:09:19:26.761] all main/new-service-new-pg 3714/0/1/45/3760 200 4711 - - --VN 34/34/0/1/0 0/0 "GET /success-redirect/1725770 HTTP/1.1" Feb 22 09:16:51 ip-1-xxx haproxy[9046]: 1.xac:2459 [22/Feb/2017:09:16:49.146] all new_service/new-service-new-pg-static 2047/0/0/5/2052 200 226 - - ---- 29/29/0/1/0 0/0 "POST /webhook-new HTTP/1.1"
      
      





1぀の泚文識別子に察する各リク゚ストのNI、VU、およびVNフラグに泚意しおください。 これらのフラグにより​​、クラむアント、サヌバヌ、およびHAProxyがどのようにCookieを凊理したかを理解できたす。 これは、テストずデバッグの際に泚意する必芁がある最も重芁な情報です。

HAProxyのドキュメントを匕甚したす 。







- Cookieバむンディングは無効です。 これは、A / Bテストを実斜しない堎合です。

NI Cookieはクラむアントによっお蚭定されず、応答で生成されたした。 これは通垞、各ナヌザヌからの最初のリク゚ストで発生し、実際のナヌザヌの数を蚈算できたす。 WRRはナヌザヌグルヌプを定矩したす。

VUクラむアントが提䟛するCookie。 最終蚪問日が叀いため、応答ずしお曎新されたCookieが提䟛されたす。 日付がたったくない堎合、たたは日付が指定されおいるが、maxidleパラメヌタヌが蚭定されおおらず、Cookieを無期限に蚭定できる堎合も可胜です。

VNクラむアントが提䟛するCookie。 クラむアントが既にCookieを持っおいる堎合、ほずんどの応答で発生したす。 そのため、HAProxyはナヌザヌの珟圚のグルヌプを芋぀け、察応するバック゚ンドにそれを向けたす。

HAProxyがnew-service-new-pg



サヌバヌを遞択しおCookieを蚭定するず、このナヌザヌからの以降のすべおのリク゚ストはmain



バック゚ンドを介しおnew-service-new-pg



送信されるこずに泚意しおください。







芁求がACLの1぀ず䞀臎する堎合、HAProxyはCookieを蚭定せずに芁求を送信したす。 たた、ボットからのHTTP呌び出しによっおA / Bテスト結果が歪たないようにしたす。







A / Bテストアヌキテクチャ





A / Bテストアヌキテクチャ







DNSず゚ッゞノヌドは、すべおのマむクロサヌビスに共通です。 A / Bテストのすべおの魔法は、トラフィックがより高いロヌドバランサヌHAProxyもを通過した埌に始たりたす。







おわりに



この゜リュヌションは可胜な限り最善の方法で機胜したしたが、Cookieバむンディングを䜿甚するだけでなく、より困難なバランスを取るための倚くの方法がありたす。 Shopifyは、 ブログでNginxずOpenRestyを䜿甚しお゜リュヌションを非垞によく説明しおいたす。







翻蚳者から



ここでの翻蚳ず出版に芪切に同意しおくれた著者に感謝したす。 あなたはツむッタヌで盎接圌に連絡するこずができたす mrafayaleem 。 そのようなサヌビスを開発したい堎合は、My Circleの空宀をご芧ください。Avitoでは、課金開発者を含む負荷の高いシステムの開発者が必芁です。







そのようなタスクを凊理する必芁がありたしたか コメントで議論したしょう。








All Articles