CalltouchサービスでのTarantool実装の経験

画像







情報技術の現代世界では、大企業も中小企業も全員が多数の異なるAPIを持っています。 フォールトトレランスは、多くのベストプラクティスにもかかわらず、ほとんどの場合、クライアント要求を正しく処理し、障害から回復し、障害によって失われた要求の処理を続行する100%の能力を保証しません。 この問題は、非常に大規模な企業ではなく、インターネット上の大企業でも発生します。







私はCalltouch働いています。主な目標は、サービスのフォールトトレランスを実現し、顧客がAPIサービスに対して行ったデータと要求を管理できるようにすることです。 障害後にサービスを迅速に復元し、問題のあるサービスに対する要求を処理する機能が必要です。 障害の瞬間から処理を開始します。 これにより、私たちの側で顧客の要求を失うことはほとんど不可能な状態に近づくことができます。







市場で提供されているソリューションを分析することで、優れたパフォーマンスと、データ管理と処理の実質的に無限の可能性を発見しました-技術的および財政的リソースの要件はごくわずかです。







背景



CalltouchにはAPIサービスがあり、Webインターフェースでレポートを作成するためのデータを含む顧客からのリクエストを受け取ります。 このデータは非常に重要です。マーケティングで使用され、その損失は予期しないサービス作業につながる可能性があります。 誰もがそうであるように、時には新機能をレイアウトまたは追加した後、サービスに問題が発生し、しばらくの間誤動作が発生する場合があります。 したがって、障害発生時にAPIサービスに配信されなかったデータを含むリクエストを非常に迅速に処理する能力が必要です。 バックアップだけでバランスを取ることは、いくつかの理由で十分ではありません。







  1. サービスに必要なメモリ量には、新しい機器が必要になる場合があります。
  2. 機器のコストは現在高くなっています。
  3. 誰もキラーリクエストのエラーから安全ではありません。


かなり単純なタスク(要求の保存とそれらへの迅速なアクセス)は、予算のコストが高くなります。 この点で、私たちはすべての着信リクエストを非常に迅速にアクセスして保存できる方法について調査することにしました。







リサーチ



受信データを保存する方法にはいくつかのオプションがありました。







最初のオプション







nginxログを使用してクエリをデータとともに保存し、それらを何らかの場所に配置します。 問題が発生した場合、APIサービスはどこかに保存されているデータにアクセスし、その後必要な処理を行います。







2番目のオプション







複数の場所でHTTPリクエストを複製します。 さらに、どこかにデータを追加する追加サービスを作成します。







後続の処理のためにログを介してデータを保存するようにWebサーバーを構成すると、欠点があります。 このソリューションはそれほど安くはなく、データへのアクセス速度は非常に遅くなります。 ログファイル、集計、およびデータストレージを操作するには、追加のサービスが必要になります。 さらに、新しいサービスの導入、運用担当者のトレーニング、新しい機器の購入の可能性のために、多大な金銭的費用が必要になります。 そして最も重要なことは、以前にそのような解決策がなかった場合、実装の時間を見つける必要があります。 これらの理由により、私たちはすぐに最初のオプションを放棄し、2番目のオプションを実装する可能性を探り始めました。







実装



nginxgoreplaylwanから選択しました







goreplayは私たちが必要とするすべてをすぐにできるので、最初の倒れたワン。 @post_actionまたはgoreplayでnginxを選択するだけです。 Goreplayはこのスキームのベンチマークでしたが、リクエストを停止して、リクエストを保存する場所と方法を検討することにしました。







ストレージは、ある時点まで特に考えることはできませんでした。 すでに処理されたデータとまだ処理されていないデータの間のフィードバックが必要でした。 リクエストを複製するAPIは、クライアント側からのリクエストでIDを提供しませんでした。 そして、そのような状況が発生しました:私は着信リクエストの追加データを代用する能力が必要でした。 これにより、未処理のデータだけでなく、すべてのデータがデータベースに取り込まれるため、処理済みのデータと未処理のデータの間でフィードバックを受け取ることができます。 次に、何らかの方法で、すべての受信データを処理する必要があります。







リクエストIDを取り除くために、Webサーバー側にUUIDを持つヘッダーを追加し、そのようなAPIリクエストをプロキシすることを決定しました-処理後のAPIサービスは、データベースで複製したリクエストを変更/削除します。 現時点では、nginxはさまざまなデータベースへの書き込み機能を含む多くのモジュールをサポートしているため、ngrexを優先してgoreplayを放棄しています。 これにより、データ処理スキームが簡素化され、この技術的な問題を解決する際の補助サービスの数が削減されます。 追加の言語を学習し、要件を満たすためにgoreplayを変更するのに時間を費やす必要はありません。







最も簡単なオプションは、nginxのモジュールを使用することです。これは、着信リクエストのすべてのコンテンツを何らかのデータベースに書き込むことができます。 私は、設定に追加のコードとプログラミングが本当に好きではありません。 Tarantoolモジュールは 、最も柔軟性が高く、私たちに適していることがわかりました;追加のアクションなしで、Tarantoolのすべてのデータをプロキシできます。







例として、単純な構成と、Tarantool用の小さなLuaスクリプトを取り上げます。このスクリプトでは、着信リクエストのすべてのボディがログに記録されます。 サービスの相互作用を次の図に示します。







画像







そのためには、一連のモジュールとTarantoolを備えたnginxが必要です。







nginxへの追加モジュール:









Tarantoolを使用するためのnginxのアップストリーム設定の例:







upstream tnt { server 127.0.0.1:3301 max_fails=1 fail_timeout=1s; keepalive 10; }
      
      





post_actionを使用したTarantoolデータプロキシ構成:







 location @send_to_tnt { tnt_method http_handler; tnt_http_rest_methods all; tnt_pass_http_request on pass_body parse_args pass_headers_out; tnt_pass tnt; } location / { uuid4 $req_uuid; proxy_set_header x-request-uuid $req_uuid; add_header x-request-uuid $req_uuid always; proxy_pass http://127.0.0.1:8080/; post_action @send_to_tnt; }
      
      





nginxからの入力を受け入れるTarantoolのサンプルプロシージャ:







 box.cfg { log_level = 5; listen = 3301; } log = require('log') box.once('grant', function() box.schema.user.grant('guest', 'read,write,execute', 'universe') box.schema.create_space('example') end) function http_handler(req) local headers = req.headers local body = req.body if not body then log.error('no data') return false end if not headers['x-request-uuid'] then log.error('header x-request-uuid not found') return false end local s, e = pcall(box.space.example.insert, box.space.example, {headers['x-request-uuid'], body}) if not s then log.error('can not insert error:\n%s', e) return false end return true end
      
      





このソリューションは、Luaコードのサイズが小さく、nginxの構成が単純であると考えることができます。 ここでAPIを使用する部分は意味をなさないため、実装バリアントで行う必要があります。 Tarantoolでこのマスターマスタレプリケーションスキームを簡単に拡張し、nginxまたはtwemproxyを使用して複数のノード間で負荷分散を行うことができます。







post_actionは、リクエストがAPIに到着して処理される数ミリ秒後にTarantoolにデータを送信するため、スキームに1つの警告があります。 APIがCalltouchと同じくらい速い場合、Tarantoolへのリクエストの前に、いくつかの削除リクエストまたはタイムアウトを行う必要があります。 タイムアウトの代わりに複数のリクエストを選択したため、サービスは遅延なく、以前と同じように機能します。







おわりに



結論として、nganxとnginx_upstream_moduleモジュールだけがTarantoolと一緒になって、HTTP要求の処理で信じられないほどの柔軟性とシンプルさ、基本サービスの動作を中断することなくデータへの高速アクセス、および既存のインフラストラクチャに実装された場合の大幅な変更を実現できるという事実を追加できます。 タスクの範囲-複雑な統計の作成から通常のクエリの保存まで。 通常のWebサービスとして使用し、nginxとTarantoolのこのモジュールに基づいてAPIを実装できることは言うまでもありません。







Calltouchの将来の開発として、いくつかのフィルターを介してさまざまなデータにほぼ瞬時にアクセスできるインターフェイスを作成する可能性に注目します。 合成負荷の代わりにテストで実際のクエリを使用します。 問題が発生したときにアプリケーションをデバッグします-品質を改善し、エラーを排除します。 データの高い可用性と作業の柔軟性が得られる場合、さまざまな製品にTarantoolを実装するためのわずかなコストで、サービスの数とその品質を高めることができます。








All Articles