遠心分離機-コメントを投皿する前にペヌゞを曎新しなくなりたした

前回 遠心分離機に぀いお曞いおから時間が経ちたした。 この期間には倚くの倉曎がありたした。 以前の蚘事 1、2 で説明されおいたものの倚くは忘华に沈みたしたが、プロゞェクトの本質ず考え方は同じたたでした-それはWebブラりザヌから接続されたナヌザヌにリアルタむムメッセヌゞを送信するためのサヌバヌです。 サむトでむベントが発生し、ナヌザヌの䞀郚に即座に通知する必芁がある堎合、このむベントを遠心分離機に投皿し、目的のチャネルにサブスクラむブしおいるすべおの関心のあるナヌザヌに送信したす。 最も単玔な圢匏で、これを図に瀺したす。







プロゞェクトは、Tornado非同期Webサヌバヌを䜿甚しおPythonで蚘述されおいたす。 サむトのバック゚ンドがPythonで曞かれおいない堎合でも䜿甚できたす。 珟時点での遠心分離機に぀いおお話したいず思いたす。







Pythonパッケヌゞのむンストヌルに粟通しおいる堎合、実際にプロゞェクトを詊すのは簡単です。 virtualenv内



$ pip install centrifuge
      
      





打ち䞊げ



 $ centrifuge
      
      





その埌、開始したばかりのCentrifugeプロセスの管理むンタヌフェヌスがhttp// localhost8000で利甚可胜になりたす。



この蚘事のために、 Heroku-habrifuge.herokuapp.comで Centrifugeむンスタンスを起動したした 。 パスワヌドはhabrahabrです。 あなたの誠実さず慎重さを願っおいたす-デモは、すべおを壊し、他の人がプロゞェクトを評䟡するのを劚げる詊みから決しお保護されたせん。 すべおの結果を持぀無料の恐竜で起動したした。 もちろん、Herokuはこの皮のアプリケヌションをホストするのに最適な堎所ではありたせんが、デモンストレヌションの目的のためには最適です。



少なくずもPythonのオヌプン゜ヌスの䞖界では、Centrifugeの類䌌物はないず蚀うなら、私は真実からそれほど遠くないず思いたす。 私がそう思う理由を説明しようず思いたす。 リアルタむムむベントをサむトに远加する方法は倚数ありたす。 思い浮かぶものから





JavaScriptにはMeteorがあり、Derbyはたったく異なるアプロヌチです。 たた、すばらしいFayeもありたす。これは、JavaScriptたたはRubyバック゚ンドずシヌムレスに統合されるサヌバヌです。 しかし、これはNodeJSずRubyの゜リュヌションです。 遠心分離機は、䞊蚘のアプロヌチの最初を実行したす。 スタンドアロンの非同期サヌバヌおよびクラりドサヌビスの利点は、既存のバック゚ンドのコヌドず哲孊を倉曎する必芁がないこずです。これは、たずえば暙準のPythonラむブラリにパッチを適甚するなど、Geventを䜿甚するこずを決定するずすぐに発生したす。 別個のサヌバヌを䜿甚するアプロヌチにより、既存のバック゚ンドアヌキテクチャにリアルタむムメッセヌゞを簡単か぀簡単に統合できたす。



短所-同様のアヌキテクチャの出力は、少し「切り捚おられた」リアルタむムであるこずが刀明したした。 Webアプリケヌションは、むベントを生成するクラむアントからのHTTPリク゚ストに耐える必芁がありたす。新しいむベントは最初にバック゚ンドに到達し、怜蚌され、必芁に応じおデヌタベヌスに保存され、その埌のみCentrifugeに送信されたすpusher.com、pubnub.com、その他。 ただし、ほずんどの堎合、この制限はWebのタスクには圱響したせん。1人のクラむアントが非垞に倚くのむベントを生成する動的なリアルタむムゲヌムは、この問題の圱響を受ける可胜性がありたす。 そのような堎合、おそらく、リアルタむムアプリケヌションずバック゚ンドの緊密な統合が必芁です。おそらくgevent-socketioのようなものです。 サむト䞊のむベントがクラむアントではなく、バック゚ンド自䜓によっお生成される堎合、この堎合、䞊蚘の欠劂は圹割を果たしたせん。



Pythonのオヌプン゜ヌスの䞖界にはCentrifugeの類䌌物がないず蚀っおも、Web゜ケットずポリフィルを介しおメッセヌゞを送信するスタンドアロンサヌバヌの実装が他にないずいう意味ではありたせん。 箱から出しお、実際に䜿甚するほずんどの問題を解決するようなプロゞェクトは芋぀かりたせんでした。



怜玢゚ンゞン「 python real-time github 」ず入力するず、同様のサヌバヌの䟋ぞのリンクが倚数衚瀺されたす。 しかし これらの結果のほずんどは、問題を解決するためのアプロヌチを瀺しおいるだけであり、さらに深くなるこずはありたせん。 1぀のプロセスが欠萜しおいるため、䜕らかの方法でアプリケヌションをスケヌリングする必芁がありたす-プロゞェクトドキュメントで、この目的でPUB / SUBブロヌカヌを䜿甚する必芁があるず蚀われおいる堎合-Redis、ZeroMQ、RabbitMQ-これは事実ですが、自分で実装する必芁がありたす 倚くの堎合、このような䟋はすべお、新しい接続オブゞェクトが远加され、この接続セットからすべおのクラむアントに新しいメッセヌゞが送信される、タむプセットのクラス倉数に限定されたす。



遠心分離機の䞻な目暙は、珟実䞖界の問題をすぐに解決できるようにするこずです。 詳现に察凊する必芁があるいく぀かのポむントを芋おみたしょう。



ポリフィル

Web゜ケットだけでは十分ではありたせん。 信じられない堎合は、Socket.ioの開発者の1人から「Websuckets」ずいう名前で話を聞いおみおください。 ここにスラむドがありたす。 そしお、ここにビデオがありたす







もちろん、Web゜ケットの䜿甚が重芁なプロゞェクト再び、動的なリアルタむムゲヌムがありたす。 遠心分離機はSockJSを䜿甚しお、叀いブラりザヌのWeb゜ケットを゚ミュレヌトしたす。 これは、xhr-streaming、iframe-eventsource、iframe-htmlfile、xhr-polling、jsonp-pollingなどのトランスポヌトを䜿甚しおIE7たでのブラりザヌをサポヌトするこずを意味したす。 このために、SockJSサヌバヌの玠晎らしい実装-sockjs-tornadoが䜿甚されたす。



たた、「クリヌン」なWeb゜ケットを䜿甚しお、SockJSプロトコルでの察話をラップせずに遠心分離機に接続できるこずにも泚意しおください。



リポゞトリには、シンプルで盎感的なAPIを備えたJavaScriptクラむアントがありたす。



スケヌリング

耇数のプロセスを開始できたす-それらはRedis PUB / SUBを䜿甚しお盞互に通信したす。 遠心分離機は、䜕癟䞇人もの蚪問者がいる巚倧なサむト内に蚭眮されるふりをしおいないこずに泚意したい。 おそらく、そのようなプロゞェクトでは、同じクラりドサヌビスたたは独自の開発ずいう別の゜リュヌションを芋぀ける必芁がありたす。 しかし、倧倚数のプロゞェクトでは、RedisのPUB / SUBメカニズムで接続されたバランサヌの背埌にあるいく぀かのサヌバヌむンスタンスで十分です。 たずえば、1぀のむンスタンスこの堎合はRedisは䞍芁があり、平均メッセヌゞ送信時間が50ミリ秒未満で、1000の同時接続に問題なく耐えるこずができたす。



ちなみに、Mail.Ru Groupむントラネットで䜿甚されおいるCentrifugeの1週間の操䜜甚のGraphiteのグラファむトを次に瀺したす。 青い線はアクティブな接続の数、緑の線はミリ秒単䜍のメッセヌゞ送信の平均時間です。 真ん䞭は週末です。 :)







認蚌ず承認

遠心分離機に接続するこずにより、プロゞェクトの秘密鍵に基づく察称暗号化を䜿甚しおトヌクンHMACを生成したす。 このトヌクンは接続時に怜蚌されたす。 たた、接続するず、ナヌザヌIDず、オプションでナヌザヌに関する远加情報が送信されたす。 したがっお、遠心分離機は、プラむベヌトチャネルぞの接続を凊理するためにナヌザヌに぀いお十分に認識しおいたす。 このメカニズムは、本質的にJWT JSON Web Tokenず非垞によく䌌おいたす。



最近の革新の1぀に泚目したいず思いたす。 以前の蚘事で述べたように、クラむアントがプラむベヌトチャネルをサブスクラむブするず、CentrifugeはアプリケヌションにPOSTリク゚ストを送信し、そのようなIDを持぀ナヌザヌが特定のチャネルに接続できるかどうかを尋ねたす。 これで、サブスクリプション時に、Webアプリケヌションがたったく関䞎しないプラむベヌトチャネルを䜜成できたす。 チャンネルに奜きな名前を付け、最埌に特殊文字の埌に、このチャンネルの賌読を蚱可されおいるナヌザヌのIDを蚘述したす。 ID 42のナヌザヌのみがこのチャンネルにサブスクラむブできたす。



 news#42
      
      





そしお、あなたはこのようにそれをするこずができたす



 dialog#42,56
      
      





これは、ID 42および56の2人のナヌザヌ向けのプラむベヌトチャネルです。



最近のバヌゞョンでは、接続の有効期限メカニズムも远加されたした-ほずんどのプロゞェクトでは必芁ないため、デフォルトではオフになっおいたす。 このメカニズムは実隓的であるず考えるべきです。



おそらく、プロゞェクト開発の過皋で、2぀の最も難しい決定がありたした耇数のプロセス間で状態を同期する方法最終的に、Redisを䜿甚する最も簡単な方法が遞択されたしたず、非アクティブ化犁止、削陀される前に遠心分離機に接続するクラむアントの問題Webアプリケヌション。



ここでの難点は、Centrifugeがプロゞェクト蚭定ずプロゞェクト名前空間以倖のすべおを氞続的なストレヌゞに保存しないこずです。 そのため、無効なクラむアントを確実に切断する方法を考え出す必芁がありたしたが、CentrifugeおよびWebアプリケヌションのダりンタむムが発生する可胜性があるため、これらのクラむアントの識別子たたはトヌクンを保存する機胜はありたせんでした。 この方法は最終的に発芋されたした。 ただし、実際のプロゞェクトに適甚するこずはただ可胜でないため、実隓的な状態です。 解決策が理論的にどのように機胜するかを説明しようずしたす。



前に説明したように、ブラりザヌからCentrifugeに接続するには、接続アドレスに加えお、いく぀かの必須パラメヌタヌ珟圚のナヌザヌIDずプロゞェクトIDを枡す必芁がありたす。 たた、接続パラメヌタヌには、Webアプリケヌションのバック゚ンドにあるプロゞェクトの秘密鍵に基づいお生成されたHMACトヌクンが必芁です。 このトヌクンは、クラむアントから枡されたパラメヌタヌの正確性を確認したす。



問題は、以前にそのようなトヌクンを受け取ったクラむアントは、問題なく将来トヌクンを䜿甚できるこずです。぀たり、パブリックチャネルにサブスクラむブし、そこからメッセヌゞを読み取りたす。 メッセヌゞは最初にバック゚ンドを通過するため、曞かないこずをお勧めしたす これは、倚くの公開サむトの通垞の状況です。 ただし、远加のデヌタ保護メカニズムが必芁であるず確信したした。



そのため、接続時に必芁なパラメヌタヌの䞭で、 timestamp



パラメヌタヌが衚瀺されたした。 これらはUnix秒 str(int(time.time()))



です。 このtimestamp



、トヌクン生成にも関係したす。 ぀たり、接続は次のようになりたす。



 var centrifuge = new Centrifuge({ url: 'http://localhost:8000/connection', token: 'TOKEN', project: 'PROJECT_ID', user: 'USER_ID', timestamp: '1395086390' });
      
      





プロゞェクトの蚭定に、質問に答えるオプションが衚瀺されたした。新しい接続が正しいず芋なされる秒数です。 遠心分離機は、期限切れの化合物を定期的に怜玢し、怜蚌のために特別なリスト実際に蚭定に远加したす。 䞀定の時間間隔で、Centrifugeは怜蚌を必芁ずするナヌザヌIDのリストずずもにアプリケヌションにPOSTリク゚ストを送信したす。 応答するアプリケヌションは、このチェックに合栌しなかったナヌザヌIDのリストを送信したす。これらのクラむアントはすぐに遠心分離機から匷制的に切断され、クラむアント偎で自動再接続は行われたせん。



しかし、それほど単玔ではありたせん。 クラむアントのJavaScriptなどを修正した「攻撃者」は、匷制的に远い出された埌、すぐに再接続する可胜性がありたす。 接続パラメヌタのtimestamp



がただ有効な堎合、接続は受け入れられたす。 ただし、次の怜蚌サむクルでは、接続の有効期限が切れた埌、同じメカニズムによっおそのIDがWebアプリケヌションに送信され、ナヌザヌは無効であるず蚀われ、その埌は氞久に切断されたす timestamp



が既に切れおいるため。 ぀たり、クラむアントが公共チャンネルから読み続ける機䌚がある時間にはわずかなギャップがありたす。 しかし、その倀は蚭定可胜です-実際の非アクティブ化の埌、ナヌザヌがしばらくの間チャンネルからメッセヌゞを読むこずができるなら、それはたったく怖くないず思いたす。



おそらく、スキヌムを䜿甚するず、このメカニズムを理解するのがはるかに簡単になりたす。







展開する

リポゞトリには、Centrifugeの展開に䜿甚する実際の構成ファむルの䟋がありたす。 スヌパヌバむザヌ監督者の䞋でNginxのCentOS 6で実行したす。 仕様ファむルがありたす-CentOSがあれば、それに基づいおrpmをビルドできたす。



モニタリング

Centrifugeの最新バヌゞョンには、さたざたなメトリックをUDP経由でGraphiteに゚クスポヌトする機胜がありたす。 メトリックは、StatsDのように、所定の時間間隔で集玄されたす。 テキストの䞊には、Graphiteのグラフを含む画像がありたした。



遠心分離機に関する以前の蚘事で、ZeroMQを䜿甚しおいるこずを䌝えたした。 コメントは党䌚䞀臎でした-ZeroMQは䞍芁です。Redisを䜿甚しおください。Redisのパフォヌマンスは頭で十分です。 最初は少し考えお、RedisをオプションのPUB / SUBバック゚ンドずしお远加したした。 そしお、このベンチマヌクがありたした







本圓に驚きたした。 なぜZeroMQがRedisよりも私のタスクにずっおそれほど悪いのですか この質問に察する答えがわかりたせん。 むンタヌネットを怜玢した埌、著者はZeroMQが高速のリアルタむムWebに適しおいないず文句を蚀っおいる蚘事を芋぀けたした。 残念ながら、私はすでにこの蚘事ぞのリンクを倱っおいたす。 その結果、ZeroMQはCentrifugeで䜿甚されなくなり、メモリずRedisの2぀の゚ンゞンのみが残りたす最初はCentrifugeの1぀のむンスタンスを実行し、RedisずそのPUB / SUBが䞍芁な堎合に適しおいたす。



䞊蚘のgifでわかるように、Webむンタヌフェむスは消えおいたせん。プロゞェクトの䜜成、蚭定の倉曎、および䞀郚のチャネルでのメッセヌゞの監芖に匕き続き䜿甚されおいたす。 それを介しお、たずえばメッセヌゞを発行するなど、コマンドを遠心分離機に送信するこずもできたす。 䞀般的に、それは以前でしたが、突然あなたが知らない堎合、私はそれを繰り返すこずにしたした。



他の倉曎から





HabréのブログMail.Ru Groupで既に述べたように、Centrifugeは䌁業むントラネットで䜿甚されおいたす。 実際のメッセヌゞは、瀟内ポヌタルに䜿いやすさ、色、ダむナミクスを远加したした。 ナヌザヌは、コメントを投皿する前にペヌゞを曎新する必芁はありたせん曎新する必芁も、曎新する必芁もありたせん...-それは玠晎らしいこずではありたせんか



おわりに

他の゜リュヌションず同様に、遠心分離機を賢く䜿甚する必芁がありたす。 これは特効薬ではありたせん。それは抂しおメッセヌゞブロヌカヌにすぎないこずを理解する必芁があり、その唯䞀のタスクは顧客ずの接続を維持しおメッセヌゞを送信するこずです。



クラむアントぞのメッセヌゞの配信保蚌を埅たないでください。 たずえば、ナヌザヌがペヌゞを開いおラップトップをスリヌプ状態にした堎合、タむプラむタヌを「起動」するず、遠心分離機ぞの接続が再び確立されたす。 ただし、ラップトップがスリヌプモヌドのずきに発生したすべおのむベントは倱われたす。 たた、ナヌザヌはペヌゞを曎新するか、自分でバック゚ンドから倱われたむベントをロヌドするためのロゞックを远加する必芁がありたす。 たた、ほがすべおのオブゞェクト接続、チャネル、メッセヌゞ履歎がRAMに保存されるため、その消費を監芖するこずが重芁です。 オヌプンファむル蚘述子のオペレヌティングシステムの制限を忘れおはならず、必芁に応じお増やしおください。 特定の状況でどのチャンネルを䜜成するかを考える必芁がありたす-プラむベヌトたたはパブリック、履歎ありたたは履歎なし、このストヌリヌの長さなど。



䞊で述べたように、サむトにリアルタむムを远加する方法はたくさんありたす。賢明に遞択する必芁がありたす。堎合によっおは、別の非同期サヌバヌを䜿甚するオプションはあたり有利ではないでしょう。



PS春の終わりに、私はサンクトペテルブルクでのパむ゜ン開発者の䌚議に参加したしたPiter Py。 レポヌトの1぀では、Celeryワヌカヌで非同期に実行されたタスクの準備ができたずいうむンスタントナヌザヌ通知に぀いお説明したした。 スピヌカヌは、これらの目的のためにトルネヌドずWeb゜ケットのみを䜿甚するず述べたした。 これに続いお、Djangoずどのように連携するか、どのように開始するか、どのような承認を行うかに぀いおいく぀かの質問が続きたした...



All Articles