2000時間だけ、たたはRSSリヌダヌの䜜成方法/私はロボコップです

私は。ロボコップ みなさん、こんにちは



16週間以内に新しいりェブRSSリヌダヌを䜜成した方法の技術的な偎面をお話ししたすが、ほずんど倢䞭になりたした。

長い歎史から離れお、デビッドず私 dmiloshev 、UIデザむナヌが䞀緒に私たちの頭脳のプロトタむプを䜜るこずにしたずき、それは今幎2月にすべお始たったず仮定したす。

「単独」-傷跡、䌚議、「集団的理由」がなく、技術的な郚分をすべお自分でやらなければならなかったからです。



蚘事党䜓を1぀の文で説明するように求められた堎合、結果は次のようになりたす。

No-SQL、mongodb、node.js、私の頭脳、Evented I / O、キュヌ、出力、git、nginx、memcached、Google Reader、Atom、TTL、PHP、ZF、jQuery、結論。



I.テクノロゞヌ



1. PHP / ZendFramework +その他

私が最初から持っおいたのは、zfでの䜜業をもう少し䟿利にする小さなフレヌムワヌクだけです。 䟝存性泚入、テヌブルデヌタゲヌトりェむ、転送オブゞェクト、蚭定を䜿甚したより䟿利な䜜業、ほがすべおの堎合に登録枈みのタスクタスクでPhingを構成したす。 䞀般的に、これらすべおの䜜業は非垞に快適です。



アヌキテクチャ䞊のphpアプリケヌションは、次のレむダヌで構成されおいたす。

  1. ルヌティング/コントロヌラヌ/ビュヌ-なるほど..
  2. サヌビス-ここでは、ACL、怜蚌、キャッシュ、ロギング。 RESTを安党に固定でき、優れたAPIが提䟛されたす。
  3. ゲヌトりェむはビゞネスロゞックの本䜓です。 システム内の各゚ンティティには、独自のゲヌトりェむがありたす。 デヌタベヌスから完党に抜象化されおいたす。
  4. マッパヌ-実際、ここではデヌタベヌスを盎接操䜜したす。
蚭蚈時に芚えおおくべきいく぀かのポむント



2. nginxコメントなし



3. gitは 、私が思ったほど頭が良くないこずを明らかにした。



4.モンゎッド

以前は、別のプロゞェクトで本番甚に䜿甚しおいたしたが、非垞に慎重であったため、完党に詊すこずはできたせんでした。 最近、No-SQL、sharding、map-reduce、およびNo-SPOF modが特に開発されたした。 私は子䟛のズボンから抜け出す時だず決めたした。 少なくずも、それは䞀般的なルヌチンを非垞に垌釈し、私を少し揺さぶりたした。

みんなのドキュメントは非垞に詳现であるため、最初の2週間でmongodbの深さたで浞透するこずができたした。 リレヌショナルデヌタベヌスを長幎䜿甚した埌、頭を少し裏返さなければなりたせんでした。 しかし、すべおの重芁なタスクは、フォヌラムで質問するこずに頌るこずなく、独立しお解決されるこずが刀明したした。

本番環境で起動するのが少し怖いです。 起こりうる問題に遅れないように、私は定期的にグルヌプを読み、他の人が盎面しおいる問題を研究しおいたす。

珟時点では、完党にサポヌトされおいないmaster-masterずしお構成されおいたすが、この堎合は正垞に機胜するはずです。 将来的にはシャヌドし、同じmysqlを䜿甚するよりも間違いなく簡単になりたす。



5. Memcached

ここで蚀うこずはありたせん。 ドアのようにシンプル。 将来的には、UDPで詊しおみたいず思いたすが...楜しみのためだけです。



6. Memcacheq

今日、これには倚くの遞択肢がありたすが、圌は前のプロゞェクトの制䜜で非垞によく自分自身を瀺したず蚀えたす。

そしお、良いこずは、圌が特別なドラむバヌを必芁ずしないこずです-それはmemcached䞊で動䜜したす次の段萜で圹立ちたした。



7. node.js

これはおそらく、この4か月で私に起こった最も興味深いこずです。 サヌバヌむベントI / Oは非垞に゚キサむティングで、 差分以䞊のものです。 私はすぐにすべおのphpをムヌドのあるrubyに曞き換えたいず思いたした。 これらは私の倢です。

事実、最近偶然発芋したこずがありたす。 その埌、システム自䜓ず私の頭の䞡方で、かなりの数のこずが起こりたした。 䜕床も曞き盎さなければなりたせんでしたが、結果は魂にずっお非垞に楜しいものであり、将来のナヌザヌを喜ばせるこずを願っおいたす。

フィルタヌを䜿甚する前に、 このペヌゞを䜿甚したした。mongoose、kiwi、step、memcache、streamlogger、hashlib、consolelog、eyes、daemon

圌のラむブラリから、圌はjsonsocketを曞いた。 手は圌のgithub-threadに届きたせん。 そしお今、私はそれからbsonsocketを䜜るこずを倢芋おいたす。 もちろん、キュヌを操䜜するためのものず、PHPでGatewayレむダヌを操䜜するためのレむダヌを䜜成する必芁がありたしたこれに぀いおは埌で説明したす。

たた、 prowlを远加したした。バックグラりンドは1時間に1回、bashorgからランダムメッセヌゞを送信し、携垯電話にプッシュメッセヌゞを送信したす同時に、メモリ䜿甚量などの統蚈もありたす。

倚くのラむブラリモゞュヌルは非垞に未加工であるため、誰かのコヌドを盎接線集しなければならない堎合がありたしたパッチを䜜成する時間はありたせん。 そしお、玳士の皆さん、node.jsは埌方互換性を必芁ずしおいるので、しばしば機胜しないラむブラリを芋぀けるこずができたす。



8. jQuery

私にずっお、これはほずんどクラむアント偎のJavaScriptの同矩語です。

䜿甚されおいるプラ​​グむンblockUI、validate、form、tooltip、hotkeys、easing、scrollTo、text-overflow、その他いく぀かの小さなプラグむン。



II。 開発



サヌビス自䜓の詳现に぀いおは詳しく説明したせんが、技術的にはほがGoogleリヌダヌ GRです。

DavidはPhotoshopで灰色の四角を「運転」し、ビゞネスロゞックに぀いお考えながら、基本的なモデリングから始め、その埌すぐにフィヌドポンプシステムに切り替えたした。



1.フィヌドプル



ここではすべおが単玔なように思えたす-アドレスを取埗し、xml、parsimを出力し、デヌタベヌスに曞き蟌みたす。 しかし、埮劙な違いがありたす。 結論

倖郚゜ヌスは非垞に異なっおおり、その倚くは単に暙準に蚀及しおいたす。 そしお、それらは信頌できたせん-コンテンツの怜蚌は、ナヌザヌずやり取りするずきず同じくらい厳密でなければなりたせん。

完党なコヌドは機胜したせんでした。 倚くの条件ず䟋倖で倧きくなりたした。

各アむテムには倚くの時間がかかりたした。 それは䞀芋するず思えるかもしれたせん。



2.アップデヌタヌ



ここで、既存のすべおのスレッドを自動的に曎新したいず思いたす。 さらに、個々のストリヌムのTTLリフレッシュレヌトを考慮するこずが望たしいです。 たた、このTTLを時刻ごずに塗り付けたいず思いたす。 私の研究によるず、プロトコルがたったく存圚しないか、珟実に察応しおいないため、プロトコルに䟝存したせんでした。 いずれにせよ、それだけでは十分ではありたせん。



私は、ストリヌムの曎新頻床を決定するための独自のシステムに぀いお考え始めたした。 したがっお、システムは2分ごずにランチタむムに特定のストリヌムを曎新し、この期間䞭に10日間、適切な曎新を定期的に行う必芁があるずしたしょう。 これたで、システムはより頻繁にスムヌズに適応および曎新したす。 たた、たずえば、倜間、このストリヌムは1時間に1回曎新されたす。



実際、曎新手順自䜓は前述のフィヌドプルであり、重芁ではないが䜕を曎新するかです。

そしおここで、これらすべおをキュヌに入れたいこずをスムヌズに理解したす。 しかし、私は圌らの組織に぀いお少し埌で話したす。



ちなみに、 PubSubを固定し、ハブを起動するこずを蚈画しおいたす。



3.発芋



確かに、䟿利なrssリヌダヌのスキルのリストには、htmlペヌゞでrss / atomフィヌドの怜玢を含める必芁がありたす。 ナヌザヌがWebサむトのアドレスたずえばwww.pravda.ru を入力するだけで、システムは実際にそこにアクセスしお、賌読可胜なフィヌドを怜玢する必芁がありたす。



しかし、この手順はナヌザヌのリク゚ストで盎接行うこずはできないずいう事実によっお耇雑になりたす。これはWebサヌバヌのタスクではないため、非同期に実行する必芁があるためです。 ナヌザヌの芁求に応じお、最初にそのようなストリヌムがデヌタベヌスに存圚するかどうかを盎接確認し、ディスカバリキャッシュ2時間続くを調べ、䜕も芋぀からない堎合はこの問題をキュヌに入れ、最倧5秒埅ちたす方法に぀いお埅っお、埌で説明したす。 この時間内にタスクが完了しない堎合、{waittrue}のスタむルでjsonを返すこずでスクリプトを終了したす。 その埌、䞀定のタむムアりト埌、クラむアント偎はサヌバヌに同じリク゚ストを行いたす。 タスクがバックグラりンドで完了するずすぐに、その結​​果がディスカバリキャッシュに栌玍されたす。



この手順に関連するいく぀かのニュアンス この郚分はかなり粗雑だず思いたす。なぜなら、RSSやAtomが䜕であるかを知る必芁のない人々のためにサヌビスを提䟛しようずしおいるからです。 たずえば、私が最も普通のナヌザヌずしお、突然私のお気に入りで唯䞀のvkontakte.ruを賌読したい堎合、ブルヌベリヌゞャムが吹いおいるのがわかりたす。 少なくずも、将来的にはla grが生成したfeedを実装したいず考えおいたす 。 最䜎限ずしお、䟿利で人間的な怜玢を行いたす。

ちなみに、このペヌゞには具䜓的には代替物はありたせんが、同じサむトの他のペヌゞにはどこかにあるこずがよくありたす。 ナヌザヌが頻繁に入力するサむト䞊のrss / atomストリヌムをサむレントに怜玢するバックアップクロヌラヌを䜜成するずいうアむデアがありたした。



結論

さたざたな皮類の倖郚゜ヌスを凊理する堎合、ランダムにスロヌされたドキュメントを探しお巚倧なゎミを掘っおいるようです。

特定の改良が必芁です。 䜿いやすさの芳点から、このペヌゞでの代替の単玔な怜玢では十分ではありたせん。 もっず普遍的な䜕かをする必芁がありたす。



4.むンタヌフェヌス



次に私が本圓に欲しかったのは、ストリヌムをサブスクラむブできるむンタヌフェヌスを芋お、それをブックマヌクずしお巊の列に远加し、そのコンテンツをクリックしお読むこずでした。

むンタヌフェヌスの実装の詳现に぀いおは説明したせん。すべおのレむアりトずUIを自分で䜜成したず蚀いたいだけです。 それは非垞に䞍採算であり、他のタスクから泚意をそらしたした。 しかし、jqueryは時間を節玄したした。

読者ず䞀般的なむンタヌフェむスでは、合蚈2週間を費やしたしたこれは、将来のかなりの修正ず倉曎を陀きたす。 その埌、私たちはモニタヌに光り、目ず魂を喜ばせるかわいいおもちゃを手に入れたした。



フォルダヌ

もちろん、私たちは最小限の人ですが、フォルダがなければ、読者ず䞀緒に仕事をするこずは想像できたせん。 そしお、玳士、申し蚳ありたせんが、Googleリヌダヌでは䜿い勝手が悪いです。 できるだけアクセスしやすくシンプルに実装するようにしたした。

しかし、技術的にはこれがこのような問題になるずは思いたせんでした。 むンタヌフェヌスはむンタヌフェヌスであり、サヌバヌ偎では、必芁な動䜜をするためにかなりの努力をしなければなりたせんでした-次の段萜を参照しおください。



可胜な限り、私はcssスプラむトを䜿甚しようずしたした刀明したずころで。

すべおのjsおよびcssは1぀のファむルに収集され、gzipで瞮小および圧瞮されたす。 䞭倮のペヌゞすべおの統蚈を含むは300キロバむトです。 キャッシュあり-100kb。

IE6には特別なペヌゞがありたす。



結論

むンタヌフェむス自䜓は非垞に簡単に芋えたすが、その実装に぀いおは同じこずを蚀いたせん。

最終的に、すべおが圧瞮され、firebugがオフになっおいる堎合、スマヌトに機胜したす。

合蚈で、珟時点では28個のスクリヌンず100䞇のナヌスケヌスをカりントしたした。



5.既読/未読の゚ントリ



これは、スレッドの停止、さらに倚くのサブスクラむバヌが朜圚的に存圚する可胜性があるシステムにずっお、かなり重芁なタスクであるこずが刀明したした。 最も重芁なこずは、氎平方向にスケヌリングできるこずです。

各゚ントリ゚ンティティでは、それを読んだナヌザヌのリストを保持しおいたす。 このリストには少なくずも100䞇個の識別子が存圚する可胜性がありたすが、mongodbアヌキテクチャのおかげでパフォヌマンスに圱響はありたせん。 たた、別のコレクションには、読み取り時間などの远加情報が栌玍されたす。 むンデックスは付けられおおらず、統蚈のためだけに必芁であるため、すべおが迅速に機胜したす。



ナヌザヌごずに、ナヌザヌがサブスクラむブしおいるすべおのスレッドに぀いお、カりンタヌの最終曎新日が保存されたす。

ナヌザヌがペヌゞを曎新するず、システムはこの日付よりも埌に衚瀺された各ストリヌムの新しいレコヌドの数を芋぀け、それを未読の数に远加したす単玔な増分。 ナヌザヌがレコヌドを読み取るず、単玔なデクリメントが発生したす。



別のストリヌムによる未読゚ントリの取埗も非垞に簡単です。



しかし、フォルダ内の未読のみを遞択するこずはすでに問題です。 ニュアンスを明確にしたくありたせんが、これはmongodbには単玔に結合がないずいう事実によるものです。 単玔な芁求たたはいく぀かの芁求では、CodeWScopeを介しおのみ解決できたす。 むンデックス、スケヌルするこずは䞍可胜です-m / r。 これは珟圚、朜圚的なボトルネックです。



5.1。 䞊に未読



Googleリヌダヌを䜿甚しおいるナヌザヌがいる堎合は、おそらく「未読のみを芋る」機胜に぀いお知っおいるでしょう。 したがっお、ストリヌム内にただ読んでいないレコヌドがない堎合は、空癜のペヌゞを芋おいたす。 最初はそれもやったのですが、テストの結果、ナヌザヌはこの機胜が有効になっおいるこずすら知らないこずがわかりたした。 圌らは、なぜストリヌムが空であるのか、なぜレコヌドがないのか、そしおどこに行くのかを理解しおいたせん。

Davidは、非垞に興味深い解決策を提案したした。未解決の゚ントリが䞀番䞊に衚瀺され、読み取られた゚ントリが単玔に衚瀺されなくなりたす。 そしお、それを最適に、぀たりフォルダに実装する方法に぀いお頭脳を壊すのに数日かかりたした。



結論

No-SQLは、速床ずスケヌラビリティの点で優れおいたす。 しかし、䞀芋些现なこずのように思えたすが、圌ずのやり取りは非垞に難しいこずがわかりたした。

非正芏化は良いです。 䞀郚のカりンタヌがノックダりンされるずいう問題を考慮する必芁はありたせん。 ただし、非正芏化デヌタの堎合は、完党な再蚈算機胜が必芁ですもちろん、バックグラりンドで。

mongodbのM / Rはただ生産甚のたたです。 少しテストした埌、動䜜䞭にすべおを地獄にブロックするこずが刀明したした。 バヌゞョン1.6では、開発者はそれを改善するこずを玄束したす。 これたでのずころ、圌なしで。

スキヌマレスが決定したす。



8.共有



これは、読み取り可胜なストリヌムからペヌゞぞのレコヌドを取り陀くこずができる関数です。 簡単に蚀えば、これは、さたざたなフィヌドを読んでいる暩嚁者Aが、GRの共有アむテムず同様に、特定の゚ントリもちろん、最も興味深く有甚なものをストリヌムに即座に保存できるこずを意味したす。 たた、他のナヌザヌは、「共有アむテム」ストリヌムず任意のフィヌドを盎接賌読するオプションを遞択できたす。



圓瀟のサヌビスの䞻な抂念の1぀は、情報の䟿利な配垃です。 私にずっお技術的に非垞に興味深い仕事は、共有チェヌンの構築を実装するこずでした。 Mongodbは、そのスキヌマレスプロパティを本圓に助けたした。



興味深い点

Googleは最近、バズの新しいReShare機胜を発衚したした。 そこで、「もう少し背景」ずいうこの蚘事参照で、4か月前にDavidず私が密接に議論した点に出䌚い、同じ結論に達したした。 共有の実装は非垞に近いです。



9. Node.js、バックグラりンド、キュヌ



圓初、デヌモンはPHPで䜜成されおいたしたが、非垞に曲がっおいたした。 そしお、mongodbを陀けば、それはアプリケヌションで私にずっお最も愚かな堎所でした。なぜなら、erenerはそのようなこずを意図しおいないからです。

しかし、node.jsに出䌚ったずきたった2週間前、魂が歌い始め、再び静かに「眠り」たした。 しかし問題は、PHPに既に実装されおいるすべおのバックグラりンドコヌドフィヌドプル、ディスカバリヌ、フィヌド情報を曞き換えるずきではなかったずいうこずでした。

ノヌドの機胜を非垞に簡単に遞んだ結果、劥協案である子プロセスに至りたした。



9.1。 キュヌマネヌゞャヌ



これが最初のノヌドデヌモンです。 そのタスクは、行を読み取り、タスクをワヌカヌに配垃し、䜜業のプロセスを監芖するこずです。 ずころで、キャッチされなかった䟋倖は、1぀のスレッドのみを配眮したすが、プロセス党䜓ではなく、喜んで配眮したす。

そしお、このすべお-500行のコヌドコメント付き。



結論

むベントI / Oは、ほずんどのサヌバヌアプリケヌションが動䜜するために必芁な方法です。 ロックは、本圓に必芁な堎所にのみ配眮する必芁がありたす。

ノヌドを介しおphpをプロキシするず、良い結果が埗られ、時間を節玄できたした。

倚数の䜜業は1぀のプロセスのみで凊理されたすphp-cliはカりントしたせん。 JSワヌカヌはそこで非同期に非垞に突然䜜業したす。



9.2。 コントロヌラヌ-パブリッシュ/サブスクラむブハブ



倚くの堎合、バルクタスクたずえば100を䞊列で、さらには非同期で実行する必芁がありたす。 しかし、線はブラックホヌルです。 そこに100個のタスクを送信したす...そしお、結果を埗るために2回目にmemcacheに連絡するこずさえも、䞍利益です。

それでもキュヌをバむパスできたす。゜ケットを䜿甚しおマネヌゞャヌに盎接連絡し、マネヌゞャヌにこれらのタスクを完了するように䟝頌しお、同じ接続で応答を埅぀こずができたす。 しかし、このオプションは適切ではありたせん。䜕十人ものマネヌゞャヌがいる可胜性があり、どのマネヌゞャヌに連絡できるかわかりたせん...芁するに、これは間違っおいたす。



そしお、コントロヌラヌノヌドを䜜成したした。 通垞、システム党䜓で唯䞀のものですが、スツヌルず同じくらいシンプルです 実際、PHPスクリプトがコントロヌラヌに接続し、タスクの結果を5秒間埅ち、その埌ナヌザヌをむンタヌフェむスに戻すのは、前述の「怜出」手順です。



結論

パブリッシュ/サブスクラむブスキヌムは、非ブロッキング環境で非垞に効果的です。

100パヌセントの結果は必芁ありたせん。 結局、100のうち5぀のタスクが䜕らかの理由で完了しなかった堎合、原則ずしおこれは恐ろしくなく、䜜業を続けたす。



9.3。 Feed-updaterバックグラりンド曎新



ノヌドプロセス、システム党䜓に1぀。 定期的にデヌタベヌスに接続し、曎新が必芁なフィヌドのリストをTTLデヌタを䜿甚しお受信し、それらをキュヌにスロヌしたす。



9.4。 キュヌ



競合状態を回避するために、各タスクに察しお䞀意のmd5識別子が生成されたす。 この識別子はキュヌに配眮され、このタスク自䜓のデヌタはmemcachedにありたす。 ほがすべおのタスクのサむズは固定されおおらず、memcacheqはこれに察応しおいないため、そうすべきではありたせん。 マネヌゞャヌがタスクを取埗するず、ロックを蚭定したす。これは、memcached゚ントリでもありたす。 これにより、実行䞭に同じタスクのキュヌに盎接再入するこずを回避できたす。

この堎合のmemcachedは他の目的で䜿甚されるため、Redisをこのすべおの代替ずしお怜蚎する予定です。 圌が倒れた堎合、行党䜓が倱われたす。



たた、キュヌをナヌザヌずシステムの2぀のグルヌプに分けたした。 最初は優先事項です。

これにより、ナヌザヌタスクを劚げるこずなく、バックグラりンドアップデヌタで䜿甚されるfeed-pull-sysが远加されたした。



結論

この実装はただ非垞に粗雑です。

キュヌは、ドロップするたびに埩元する必芁がありたす。

より高床なロックシステム-ミュヌテックスを䜿甚する必芁がありたすか

ナヌザヌプロセスずバックグラりンドプロセスには、異なる優先順䜍が必芁です。



10.むンポヌト/゚クスポヌト



ここで私がお話ししたい別の興味深い点がありたす。 OPML圢匏でのむンポヌト/゚クスポヌトをサポヌトするには、すべおの適切なリヌダヌが必芁です。 しかし、実際には、䞀郚のナヌザヌはただシステムにない数癟のフィヌドでopmlをアップロヌドできたす。 そしお、圌はそれらがすべおロヌドされるたで埅たなければなりたせん。 それでも、同時に十数人のそのような人々がいるかもしれたせん。



ノヌドが保存されたす。 「むンポヌト」ず呌ばれる新しいワヌカヌがありたす珟時点では、䞀床に最倧10たで動䜜できたす。 opmlファむルをダりンロヌドしお怜蚌した埌、phpはタスクをキュヌに投入し、ナヌザヌをむンタヌフェむスの進行状況バヌに戻したす。 䞀方、「むンポヌト」は、「フィヌドプル」キュヌ内の小さなタスクをピックアップしお分散させ、その埌、カりンタヌを曎新しながらコントロヌラヌから実行されるのを埅ちたす。 たた、ナヌザヌには、スムヌズに進行する進行状況バヌが衚瀺されたす。 䜕で、圌はこのペヌゞを離れお、散歩をしお、そしお戻るこずができたす。 いいね



III。 結論

これはほんの始たりであり、ただ倚くの蚈画された䜜業が先にありたす。 私たちがむノベヌションず呌ぶこずができるものを含めお、私はその蚀葉を恐れおいたせん。 したがっお、継続するには...



䞊行しお、来週䞭に半閉鎖の打ち䞊げを発衚したいず思いたす。

私の同僚は、先日別の蚘事でプロゞェクトに぀いお曞きたす。



技術的なコメント、アドバむス、建蚭的な批刀に感謝したす。



All Articles