クリック名声、またはロボットなどを興奮させる方法





むかしむかし、遠く離れた店の前で盗聴された会話が行われました

NB: -         ?
      
      





GURU : - «» . . . , ...







 NB: -      ,     ?
      
      





GURU : - google yandex , . . , .







 NB: -       ?
      
      





GURU : - ?… ...





NBは質問をやめ、明らかに経験豊富な対談者を困らせることを恐れた。

まるでプロキシトピックの枯渇を強調し、沈黙しているかのように、 GURUは目を転がしました...



もちろん、 GURUは、検索クエリ(たとえば、単語:プロキシによる)によって、 NBがすぐに目的のアドレス:ポートリストを取得することを知っていました。 しかし、最初の実験の後、 NBは同じくらい迅速に理解します。






この記事では、即興(そして最も重要なことには普遍的)の意味について説明します

ZennoPosterなどの特定の専用ソフトウェアを使用せずに...)

「本当に適切な」プロキシのリストを取得し、それらを使用してプロモートへの(自動化された)訪問を整理するための自動化ツールを構築する

Chromeブラウザを使用したサイト。



指示に従って、次のことを可能にする既製のツールを取得します。





そして、私の研究はすべて(研究と一緒に)1週間かかりましたが、 コマンドラインPHP 、およびJavaScriptの基本的な知識があれば、このようなツールを作成するのに2日間は必要ありません。




ただし、 次の図の下にスクロールする前に、この資料がなぜ誰のために準備されているかについて少し説明します。



構成(または、コンストラクター)がどのように配置されているかを理解したい場合、この資料は役立ちます。これにより、負荷の変化に適応し、コストをかけずに比較的迅速かつ簡単にアプリケーションを構築できます。 サービスバス( ESB )に基づいてアプリケーションを構築する可能性に関心がある場合。



このテキストは、 Dockerを使用してインスタントビルディングシステムを使用する方法を知りたい場合に役立ちます。 または、 Selenium Serverと、コンテンツの受信/ HTTPxアクティビティの兆候に興味があるだけの場合。

「すぐに使用する」ために、思慮深くこれをすべて読むことは価値がありません。 コードは確かです。
完成したツールのセットアップに直行します。 セットアップにかかる時間は20分未満です。
このマニュアルでは、Ubuntu 18.04がインストールされた2台のマシンを自由に使用できることを前提としています。

1つはインフラストラクチャ( docker )用で、もう1つはプロセス制御( process )用です。



次のパッケージが既にdockerにインストールされていると想定されます。

git、docker、docker-compose


次のパッケージがプロセスに既にインストールされていると想定されます

git、php-common、php-cli、php-curl、php-zip、php-memcached、コンポーザー
この時点で質問がある場合は、資料全体を15分間読むことをお勧めします。



ドッカー



 #    root-. # ,     TCP-: # 11300, 11211, 4444, 5930, 8080, 8081, 8082, 8083 #        # " root-"    git clone \ https://oauth2:YRGzV8Ktx2ztoZg_oZZL@git.ituse.ru/deploy/esb-infrastructure.git cd esb-infrastructure docker-compose up --build -d #      3     #   . #       web-.
      
      





処理



 #      . #      process-   , #     -  php- git clone \ https://oauth2:YRGzV8Ktx2ztoZg_oZZL@git.ituse.ru/deploy/clicker-noserver.git cd clicker-noserver composer update #  .       "XXXXXXXX" mv app/settings.php.dist app/settings.php #   . gnome-terminal \ --tab -e 'bash -c "php app/src/Process/noserver/singleProcess.php curl"' \ --tab -e 'bash -c "php app/src/Process/noserver/singleProcess.php timezone"' \ --tab -e 'bash -c "php app/src/Process/noserver/singleProcess.php whoer"' #  . ,     , #  : - log/list.proxy php app/src/Utils/givethejob.php ./log/list.proxy
      
      





Webパネル(http:// docker-machineのIPアドレス:8080)で何が起こっているかを見てください。

結果は、検索されたキューで利用可能になります。



粉砕と計画







上記の図は、プロセスステップのシーケンス、各ステップの予想結果、および各パーツの作成に必要なリソースを説明しています(詳細: タスク2タスク3タスク4,5,6 )。



私の場合、すべてが2台のUbuntu 18.04マシンで発生します。 それらの1つがプロセスを制御します。 一方、いくつかのインフラストラクチャDockerコンテナが実行されています。



言い訳と失敗



すべてのパッケージコードは3つの部分で構成されています。

それらの1つは私のものではありません(これはきちんとした美しいコードです)。 このコードのソースはpackagist.orgです。



私自身も別の記事を書いて、それを理解できるようにし、コードのこの部分に約1週間を費やしました。



残りは「困難な歴史的遺産」です。 コードのこの部分は、かなり長い時間をかけて作成されました。 プログラミングのスキルがあまりなかった頃を含めて。



これがまさに私のGitLab上のリポジトリと私のSatis上のパッケージの場所の理由です。 GitHub.comおよびpackagist.orgで公開するにはこのコードを処理し、より詳細なドキュメントを作成する必要があります。



コードのすべての部分は無制限に使用できます。 リポジトリとパッケージは永久に利用可能になります。



ただし、コードを再公開するときは、私またはこの記事へのリンクを投稿してくれたことに感謝します。



アーキテクチャについて少し



ツールの作成に使用されたアプローチは、特定の各タスクを解決するためのユーティリティを作成(または既製のユーティリティを使用)することです。 さらに、解決するタスクに関係なく、各ユーティリティにはすべてに共通の2つのプロパティがあります。





この原則によって作成されたソリューションでは、プロセスステップごとに実行中のタスクハンドラー(ワーカー)の数を変更できます。 各ステップのワーカー数が異なると、前のステップの処理タスクの長さにより、後続のステップの「0」ダウンタイムが発生します。



プロセスの結果の単位(この場合は検証済みのプロキシ)の取得に費やされる時間は、外部要因(不適切なプロキシの数、外部リソースの応答時間など)に依存します。



各プロセスステップのワーカー数を変更することにより、この依存関係を実行中のワーカー数への依存関係に変換します(つまり、関連するコンピューティングとチャネルの容量に応じて)。



個々の独立した部分の動作を同期するには、メッセージングキューサーバーを単一のデータバスとして使用すると便利です。 これにより、完了したステップの結果をキューに蓄積し、入力として適切なタイミングで「次のステップ」ユーティリティに渡すことができます。



メッセージングキュー。 MQおよびESB



下位レベル( MQ )としてbeanstalkdを使用します。 小型、軽量、構成不要、debパッケージおよびDockerコンテナーで使用可能。目立たないハードワーカーです。 論理レベル( ESB )はPHPでコードを実装します



実装には2つのクラスが使用されます。 esbTaskおよびnextStepWorker



esbTask



 class esbTask //   ,     { // immutable-; // "" (   ESB-),  payload //    //     "" .... }
      
      





このクラスのインスタンスは、プロセスのステップを通じてPaylodを「アドレス指定」するのに役立ちます。 ESBの概念は、いくつかの原則/パターンを適用します。 そのうちの2つは個別に注意する価値があります。



キューに入れられたオブジェクトはjsonで表され、ここに隠されています...
 // json- esbTask { //    (   esbTask) "_type":"App\\\\rebean\\\\payloads\\\\ESBtaskQueue", //  "task":"task:queue@XXX.XXX.XXX.XXX:11300", //    () "replyto":[ "othertask1:nextqueue1@yyy.XXX.XXX.XXX:11300", "othertask2:nextqueue2", "othertask3:nextqueue3", ], //    () "onerror":[ "error:errorsstep@zzz.XXX.XXX.XXX:11300", "error:errorsstep1", "error:errorsstep2", "error:errorsstep3" ], //     () "onstop":[ "stop:stopstep@kkk.XXX.XXX.XXX:11300", "stop:stopstep1", "stop:stopstep2", "stop:stopstep3" ], //   "payload":{ .... }, //   ... () "till":[ .... ], //     ... () //        // -  (LINUX-TimeStamp) "since":[ 1540073089.8833, ], // -     "points":1, //  .     "groupid":"" }
      
      







nextStepWorker



キューに表示される各メッセージは、それを担当するワーカーによって処理されます。 これを行うには、次の一連の関数が実装されます。



 class nextStepWorker extends workerConstructor { //       //     esbTask //    () //    MQ- (beanstalkd) //     (Memcached) //     (MySQL) // : -  (  - ); -    stop-; -      (log, event, mq) .... }
      
      





プロセスの各段階のワーカーは、このクラスに基づいて実装されます。 処理、アドレス指定、およびルートの次のステップの送信のルーチン全体で、クラスが処理します。



各問題の解決策は次のとおりです。



  1. esbTaskを取得してワーカーを実行します。
  2. 結果をペイロードに保存してロジックを実装します。
  3. ワーカーの実行を完了します(緊急または通常-問題ではありません)。


ステップが完了すると、結果は適切な名前でキューに入れられ、次のワーカーが処理を開始します。



一度やってください。 空室状況を確認する



実際、問題を解決するワーカーを作成することは、1つのメソッドの実装です。 問題2を解決するワーカーの実装例(簡略化) 次のとおりです。



 // app/src/Process/worker/curlChecker.php .... class curlChecker extends nextStepWorker { const PROXY_INFO = 'https://api.ipfy.me?format=json&geo=true'; const PROXY_TIMEOUT = '40'; const COMMAND = "curl -m %s -Lx http://%s:%s '%s'"; public function logic() { //    .  ..   payload extract($this->context()); //  defaults    payload  $curltimeout = $curltimeout ?? self::PROXY_TIMEOUT; $curlchecker = $curlchecker ?? self::PROXY_INFO; //     $line = sprintf( static::COMMAND, $curltimeout, $host, $port, $curlchecker ); exec($line, $info); //      // ( ,  stop-) $info = arrays::valid_json(implode('', info)); if (empty($info)) throw new \Exception("Bad proxy: $host:$port!", static::STATUS_STOP); //    payload $this->enrich(['info']) ->sets(compact('info')); } }
      
      





数行のコードとすべてが行われ、次の段階に「出向」されます。



TimeZoneを定義します。 TimeZoneDBとその目的...



着信リクエストの詳細なテストでは、ブラウザウィンドウの時間とリクエストの送信元IPアドレスが存在する時間を比較します。



カウンターからの疑いを避けるために、ローカルプロキシ時間を知る必要があります。



時間を見つけるために、プロセスの前のステップの結果から緯度と経度を取得し、ブラウザウィンドウの将来のインスタンスが動作するタイムゾーンに関するデータを取得します。 これらのデータは、時間の分野の専門家から提供されます。



この問題を解決するための単純化されたワーカー( タスク3 )は、 前のものと完全に類似してます。 唯一の違いはリクエストURLです。 ファイルでフルバージョンを見つけることができます:

// app / src / Process / worker / timeZone.php


インフラストラクチャについて少し



説明したbeanstalkdに加えて、ツールには以下が必要です。





これらすべてを迅速にデプロイするには、Docker( Ubuntuにインストールする方法 )が非常に便利です。



そして、彼にとっての「オーケストラ」はdocker-compose(インストール用のコマンド)...
 sudo apt-get -y update sudo apt-get -y install docker-compose
      
      







これらのツールを使用すると、親OSの個別の「コンテナ」で既に構成および構成された(以前の誰かによって)サーバー/プロセスを実行できます。 詳細については、 これまたはこの記事を参照することをお勧めします。



だから...



インフラストラクチャを開始するには、コンソールでいくつかのコマンドが必要です。



 #   ,    docker- #     (   ) #    sudo -s git clone \ https://oauth2:YRGzV8Ktx2ztoZg_oZZL@git.ituse.ru/deploy/esb-infrastructure.git \ panels cd panels docker-compose up --build -d #   .
      
      





アドレスXXX.XXX.XXX.XXXのマシンでコマンドが正常に実行された結果、

次の一連のサービスが提供されます。

-XXX.XXX.XXX.XXX:11300-beanstalkd

-XXX.XXX.XXX.XXX:11211-Memcached

-XXX.XXX.XXX.XXX:4444-Selenium サーバー

-XXX.XXX.XXX.XXX:5930-Chromeでの動作を制御するVNCサーバー

-XXX.XXX.XXX.XXX:8081-Memcachedと通信するためのWebパネル(管理者:パス)

-XXX.XXX.XXX.XXX:8082-beanstalkdと通信するためのWebパネル

-XXX.XXX.XXX.XXX:8083-VNCと通信するためのWebパネル(パスワード:シークレット)

-XXX.XXX.XXX.XXX:8080-一般的なWebパネル



「すべてが適切に配置されているかどうかを確認する」、「コンテナへのコンソールに入る」、「インフラストラクチャを停止する」は、スポイラーのコマンドです。
 #   ,    docker-, #    ..../panels/ #    docker-compose ps # Name Command State Ports # ------------------------------------------------------------------------------------------------------------------------ # beanstalkd /usr/bin/beanstalkd Up 0.0.0.0:11300->11300/tcp # chrome start-cron Up 0.0.0.0:4444->4444/tcp, 0.0.0.0:5930->5900/tcp # memcached docker-entrypoint.sh memcached Up 0.0.0.0:11211->11211/tcp # nginx docker-php-entrypoint /sta ... Up 0.0.0.0:8443->443/tcp, 0.0.0.0:8080->80/tcp, # 0.0.0.0:8082->8082/tcp, 0.0.0.0:8083->8083/tcp, 9000/tcp # vnc /usr/bin/supervisord -c /e ... Up 0.0.0.0:8081->8081/tcp #       chrome docker exec -ti chrome /bin/bash #       docker-compose stop && docker rm $(docker ps -a -q)
      
      





タスク4,5、6-1つのユーティリティに結合



タスクの細分化を詳細に見て( 上記の図 )、残りのタスクの1つ( タスク6 )のみが外部リソースに依存していることを確認するのは簡単です。 「無条件に保証された」ランタイムでタスクを実行すると(制御されていない要因とは無関係)、プロセス全体の速度に追加のプラスは追加されません。 この点で、これらのタスク( 4,5,6 )は1人のワーカーに結合されました。 ワーカーファイルの名前は次のとおりです。

// app / src / Process / worker / whoerChecker.php


Chromeの設定を行います。 プラグイン



Chromeはプラグインで柔軟に構成されます。



Chromeのプラグインは、 manifest.jsonファイルを含むアーカイブです。 彼はプラグインについて説明します。 アーカイブには、プラグインに必要なJavaScript、html、cssおよびその他のファイルのセットも含まれています( 詳細 )。



この場合、 JavaScriptファイルの1つがChrome作業ウィンドウのコンテキストで実行され、必要なすべての設定が有効になります。



プラグインテンプレートを取得し、適切な場所でテスト対象のプロキシサーバーの必要なデータ(相互作用プロトコル、アドレス、ポート、またはタイムゾーン)を置き換えるだけです。



アーカイブを作成するコードのスニペット:



 // app/src/Chrome/proxyHelper.php .... class proxyHelper extends sshDocker{ .... // $name -  - // $files - [ ... '   -' => '', ...] protected function buildPlugin(string $name, array $files) { $this->last = "$this->cache/$name"; if (!file_exists("$this->last")) { $zip = new \ZipArchive(); $zip->open("$this->last", \ZipArchive::CREATE | \ZipArchive::OVERWRITE); foreach ($files as $n => $data) { $zip->addFromString(basename($n), $data); } $zip->close(); } $this->all[] = $this->last; $this->all = array_unique($this->all); return $this; } .... }
      
      





プロキシチューニングプラグインのテンプレートは、 職業を愛する人々の仕事の結果の貯金箱で見つかり、プロトコル部分が変更され、リポジトリに追加されました。



ウィンドウ時間の変更



実行中のChromeインスタンスのグローバル時間を変更するには、 window.Dateを同様の機能を備えたクラスで置き換える必要がありますが、正しいタイムゾーンで有効です。



サンポジュスティラの作品に本当に感謝しています。 このスクリプトはUIの自動テスト用に作成されましたが、少し改良が加えられました。



ここにあなたの注意を引きたいと思うニュアンスがあります。 manifest.jsonで説明されているスクリプトのコンテキストに関連付けられています。



完全な秘密は、グローバルコンテキスト(プラグインのメインスクリプトが起動され、設定が設定されているもの、たとえばネットワークに接続されているもの)が、ページがロードされるタブのコンテキストから分離されることです。



経験的に、グローバルコンテキストでのクラスのプロトタイプへの影響がタブの変更につながっていないことがわかりました。 ただし、すでにロードされているページにスクリプトを登録し、他のページよりも先に実行することで、問題は解決しました。



ソリューションは、次のコードフラグメントで表されます。



 // app/chromePlugins/timeShift/content.js //     var s = document.createElement('script'); //        s.src = chrome.extension.getURL('timeshift.js'); //      (document.head || document.documentElement).appendChild(s);
      
      





プロキシ設定



Chromeでプロキシを設定するのは簡単なので、スポイラーでjsコードを非表示にします
 // app/chromePlugins/proxy/background.js var config = { mode: "fixed_servers", rules: { singleProxy: { scheme: "%scheme", host: "%proxy_host", port: parseInt(%proxy_port) }, bypassList: ["foobar.com"] } }; chrome.proxy.settings.set({value: config, scope: "regular"}, function () { }); function callbackFn(details) { return { authCredentials: { username: "%username", password: "%password" } }; } chrome.webRequest.onAuthRequired.addListener( callbackFn, {urls: ["&gtall_urls&lt"]}, ['blocking'] );
      
      







Chromeプラグインのパス



すべてのプラグインはスキームに従って名前が付けられ、プロセスを制御するマシンの一時フォルダーに追加されます。
//プロキシプラグインの命名スキーム:

proxy- [アドレス]-[ポート]-[プロトコル]>。zip

タイムシフト-["-" | ""]-[shift_in_minutes_from_GMT] .zip


次に、これらのプラグインを、インフラストラクチャを担当するマシンで実行されているドッカーコンテナにインストールする必要があります。



これはsshで行います。 これを行うために、私はphpseclibに出会いました (後で後悔しました)。図書館の異常な振る舞いに魅了されて、私はそれを研究するために一日を過ごしました。



ここでのsshコンソールクライアントはより良く機能し、より速く動作しますが、仕事はすでに完了しています。



低レベル(SFTPおよびSSHを使用)の場合、基本クラスが責任を負います(以下)。このクラスを置き換えると、phpseclibがコンソールクライアントに置き換えられます。



 // app/src/Chrome/sshDocker.php //    (DOCKER_HOST, DOCKER_USER, DOCKER_PASS) //   : app/settings.php //      .... class sshDocker { .... //  .     docker //    .         // : app/techs.php const EXEC_DOCKER = DOCKER_BIN_PATH . "/docker exec -i %s %s"; .... //     sudo    (  ),  DOCKER_USER -  protected function sudo(string $command, string $expect = '.*'){...} //     Docker-,      //       -    self::EXEC_DOCKER protected function execDocker(string $command, string $expect){...} .... }
      
      





ベースのsshDockerおよび既知のproxyHelperクラスから派生し、プラグインを生成するだけでなく、インフラストラクチャコンテナの一時フォルダーに配置します。



 // app/src/Chrome/proxyHelper.php .... class proxyHelper extends sshDocker { .... public static function new(string $docker, $plugins) { return (new self($docker, $plugins)) ->setupPlugins(); } .... }
      
      





設定でChomeを起動



Selenium Serverは、カスタマイズされたChromeの起動を支援します



Selenium Serverは、特にWEBインターフェイスのテスト用にFaceBookチームによって作成されたフレームワークです



フレームワークにより、開発者はブラウザーウィンドウで(ChromeまたはFirefoxを使用してユーザーアクションをプログラムでエミュレートできます



Selenium Serverは多くの言語での使用に適合しており、テストスクリプトを記述するための事実上の標準ツールです。



プロジェクトで使用する新しいリリースを取得する最良の方法:



 composer require facebook/webdriver
      
      





Selenium Serverオブジェクト(RemoteWebDriver)のメインインスタンスの従来の構成は、私には冗長に見えました。
 // URL- $url = "https://example.com/books/196/empire-v-povest-o-nastoyashem-sverhcheloveke"; // URL,     (Selenium Server) $server = 'http://' . DOCKER_HOST . '/wd/hub'; //   ,      $options = new ChromeOptions(); $options->addArguments(array( '--disable-notifications' )); //    - $capabilities = DesiredCapabilities::chrome(); $capabilities->setCapability(ChromeOptions::CAPABILITY, $options); //        5000     URL $driver = RemoteWebDriver::create($server, $capabilities, 5000); $page = $driver->get($url);
      
      







そのため、これらすべてを少し減らして、ニーズに合わせて構成を最適化しました。



 // app/src/Process/worker/whoerChecker.php .... class whoerChecker extends nextStepWorker { //    : app/settings.php // URL Selenium Server const SELENIUM_SERVER = CHVM; //  - const DOCKER_NAME = DOCKER_NAME; .... public function config() .... //        : // $driver = RemoteWebDriver::create($server, $capabilities, 5000); $chrome = Chrome::driver( static::SELENIUM_SERVER, Chrome::capabilities(static::DOCKER_NAME, $plugins), 5000 ); .... } ....
      
      





目はすぐに$プラグインにしがみつきます。$ pluginsは、プラグインの構成を担当するデータ構造です。各ディレクトリおよびプラグインJavaScriptファイルのプレースホルダーを置換します。



構造はapp / plugs.phpファイルに記述されており、グローバルオプションapp / settings.phpの一部です。
 // app/plugs.php const PLUGS = [ 'timeshift' => [ 'path' => PROJECTPATH . '/app/chromePlugins/timeShift', 'files' => ['manifest.json', 'timeshift.js', 'content.js'], 'fields' => ['%addsminutes' => 'timeshift'] ], 'proxy' => [ 'path' => PROJECTPATH . '/app/chromePlugins/proxy', 'files' => ['manifest.json', 'background.js'], 'fields' => [ '%proxy_host' => 'host', '%proxy_port' => 'port', '%scheme' => 'scheme', '%username' => 'user', '%password' => 'pass' ] ] ];
      
      







Selenium WebDriverを使用したページの解析は非常に簡単です。



 .... $url = 'https://__/_-_'; $page = $chrome->get($url); .... //   xPath-   $xpath = '/html[1]/body[1]/div[1]/div[1]/div[1]/div[2]/div[1]/div[1]/div[1]/div[1]/strong[1]'; $element = page->findElement(WebDriverBy::xpath($xpath)); .... //   $text = $element->getText(); // HTML- $html = $element->>getAttribute('innerHTML'); ....
      
      





すでに書いたように、これらのアクションはすべて、3番目のステップ(タスク4,5,6)のユーティリティによって実装されます

// app / src / Process / worker / whoerChecker.php

Selenium Serverでの作業の説明を締めくくり、この技術を産業規模(1000〜3000ページのオープニング)で使用する場合、Selenium Serverとのセッションが誤っ終了することは珍しくありません。ウィンドウには所有者がいません。そして、そのようなウィンドウはたくさん蓄積する可能性があります。



「ブローチ」と戦ういくつかの方法が検討されました。 「食べて」2日間働きます。最も効果的なのはcronでした。正しくインストールされ、ドッカー・コンテナ内の設定は個別のタスクになって、慎重かつ詳細に説明renskiyをONLYこのトピック捧げた記事で(私は驚きました)。



元のDockerイメージの自動再構築と、ブローチを閉じて未使用のプラグインをクリーンアップするためのいくつかのスクリプトのインストールについては、インフラストラクチャリポジトリーであるdocker-compose.ymlで説明していますクリーニング頻度は、同じリポジトリのkillcronファイルで設定されます。



WebRTC



すでに正しい時間を設定しており、ブラウザのトラフィックがプロキシを通過するという事実にもかかわらず、私たちはまだ検出することができます。



時間差(ブラウザとIPアドレス)に加えて、「プロキシの背後に座っている」ことの匿名化のソースがさらに2つあります。これらは、ブラウザに埋め込まれたフラッシュおよびWebRTCテクノロジーです。ブラウザはFlashが無効になっていますがWebRTC 無効はありません。



両方の失敗の可能性の理由は同じです-ユビキタスで機敏なUDPパケットです。以下のためのWebRTC:二つのポートである347819302



クロムコンテナーからのスカウトの流出を停止するには、インフラストラクチャコンテナーを備えたホストマシンにiptablesルールを適用します。



 iptables -t raw -I PREROUTING -p udp -m multiport --dports 3478,19302 -j DROP
      
      





同じproxyHelperがこのタスクを実装します。



残りの労働者



目標-匿名プロキシを介したターゲットサイトの「クリック」の実装を成功させるには、もう1人のワーカーが必要です。whoerCheckerの



短縮バージョンになります。書かれたすべてを使用して、自分でそれを行うことは難しくないと思います。



キューに入るのプロセス全体の結果位置は、各匿名認証されたプロキシサーバーのアドレスの「度」に関するデータが含まれています。



カウンターと「対戦」するとき、覚えておくべき主なことは匿名性であり、ロボットの訪問に夢中にならないことです。中に組み込まれているスケジュールでの活動の組織に機会を提供する「クリックを夢中にしていない」の原則の遵守esbTask(フィールド以来、当社のESBのエンベロープ)。



すべてを注意深く試してみるとターゲットサイトのyandexメトリックは次の図のようになります。







すべてをまとめる方法



だから、与えられた:





この「指定」では、通常libeventReact PHPを使用しますこれらすべてにいくつかのツールが追加されており、プロセスの各ステージのハンドラーインスタンスの数(指定された制限内)を自動的に制御できます。



ただし、記事のサイズとトピックの詳細を考えると、これらすべてを別の記事で説明させていただきます。この記事はnoserverテクノロジーです。将来のものは「サーバー」です。
Dear Reader、出版日はあなたの興味に関連しています。
. , ,… . , , , , , .



habr , . , , .



. , " server ", README.md .


noserver」では、1つのインスタンスが1つのキューを処理します(1つの処理ステップ)。このアプローチは、ワーカーをデバッグするときに使用する精神怒らせるだけです。



必要な処理速度に応じて、「手動」で好きなだけコピーを開始できます。



次のようになります。



 // app/src/Process/noserver/singleProcess.php //   ,    //   include __DIR__ . '/../../../settings.php'; use App\ESB\pipeNcacheService; use App\arrayNstring\queueDSN; use App\arrayNstring\timeSpent; use App\arrayNstring\progressString; //    $path = __DIR__ . '/../worker'; //   $queues = array_keys(WORKERS); $queue = $argv[1] ?? end($queues); $queue = strtolower($queue); if (!in_array($queue, $queues)) die("php $argv[0] <queue_name>" . PHP_EOL); //  - $progress = new progressString("Listenning... Idle: ", 40, 20); // ,      $stopwatch = timeSpent::start(); //    beanstalkd- list($worker, $task) = WORKERS[$queue]; $procid = ['procid' => posix_getpid()]; //   beanstalkd  Memcached, //     ( ) $dsn = new queueDSN($task, $queue, ...QUEUE_SERVER); //     ESB- $pnc = new pipeNcacheService($dsn); $pipe = $pnc->getPipe(); echo "Start listener for queue: $queue." . PHP_EOL; echo "Press Ctrl-C to stop listener." . PHP_EOL; //      //       while (true) { try { $job = $pipe->watch($queue) ->reserve(1); $now = new DateTime(); $opts = json_encode($pipe->getPayload($job) + $procid); $pipe->delete($job); echo PHP_EOL . "Task recived at: " . $now->format('H:i:s') . " Starting worker: $worker. "; $stopwatch = timeSpent::start(); exec("php $path/$worker $opts", $out); echo "Finished. Time spent: $stopwatch" . PHP_EOL; $stopwatch = timeSpent::start(); } catch (Throwable $exception) { echo $progress($stopwatch('%I:%S', null, $now)); } }
      
      





ワーカーの奇妙な始まりは印象的です...ワーカーのそれぞれがPHPオブジェクトであるという事実にもかかわらず、私はexec(...)を使用しました



これは、「noserver用に個別のワーカーを作成したり、「serverモードで起動する目的でワーカーを変更したりしないように、時間を節約するために行われました



構成と展開に関するいくつかの言葉



構成定数



インスタンスの設定ファイルはapp / settings.phpです。リポジトリを複製した直後に作成する必要があります。これを行うには、ファイル名をapp / settings.php.distに変更しますすべての定数は内部的に記述されています。特に



app / settings.phpには、他の定数を持つファイルが含まれます。

- アプリ/ queues.phpはキューとジョブの名前が含まれている

- アプリを/ plugs.php説明クローム -plaginov

- アプリ/ techs.phpは、計算された定数が含まれています



公益事業



プロセスの結果の処理とタスクの配置の利便性のために、いくつかのユーティリティがあります。ユーティリティはコマンドラインから起動します。引数の説明が提供されます。位置:app / src / Utils

 backup.php-キューをファイルに保存します
    clear.php-キューを消去します
    exporter.php-保存されたキューを持つファイルからエクスポートします 
                     ペアのアドレス:ポート
    givethejob.php-プロセスにタスクを投稿します 
                     (ソース-アドレス:ポートコンボボックス)。
                     リストから一部のアドレスを除外できます
    restore.php-保存されたキューを復元します 


労働者の微調整



手書きのワーカーを使用する場合、次の構成オプションを使用すると便利な場合があります。



 // app/src/Process/worker/curlChecker.php .... $worker = new curlChecker( [ //    curlChecker::WORKER => 'curlchecker', //  beanstalkd curlChecker::PIPE_HOSTPORT => implode(':', QUEUE_SERVER), //  Memcached curlChecker::CACHE_HOSTPORT => implode(':', MEMCACHED), // ,    . //    -   curlChecker::DB_SCRIPT => __DIR__ . '/../../../confdb.php', // ,       // (        -) curlChecker::INFO_START => CURL_START, // ,        // (        -) curlChecker::INFO_END => CURL_END, //  ,     //    //        curlChecker::INFO_ADDS_END => ['host', 'port'] ], ['setupworker', 'config', 'logic'] ); ....
      
      







展開



このマニュアルでは、Ubuntu 18.04がインストールされた2台のマシンを自由に使用できることを前提としています

1つはインフラストラクチャ(docker用で、もう1つはプロセス制御(process)用です。



ドッカー



 #    root-. # ,     TCP-: # 11300, 11211, 4444, 5930, 8080, 8081, 8082, 8083 #   . sudo -s apt -y update apt -y install git snap snap install docker apt -y install docker-compose # C       # " root-"    cd ~ git clone \ https://oauth2:YRGzV8Ktx2ztoZg_oZZL@git.ituse.ru/deploy/esb-infrastructure.git cd esb-infrastructure docker-compose up --build -d #      3     #   . #       web-.
      
      





処理



 #      . #   . sudo apt -y update sudo apt -y install git php-common php-cli php-curl php-zip php-memcached composer # C     process-   , #     -  php- cd /var/www git clone \ https://oauth2:YRGzV8Ktx2ztoZg_oZZL@git.ituse.ru/deploy/clicker-noserver.git cd clicker-noserver composer update #  .       "XXXXXXXX" mv app/settings.php.dist app/settings.php #   . gnome-terminal \ --tab -e 'bash -c "php app/src/Process/noserver/singleProcess.php curl"' \ --tab -e 'bash -c "php app/src/Process/noserver/singleProcess.php timezone"' \ --tab -e 'bash -c "php app/src/Process/noserver/singleProcess.php whoer"' #  . ,     , #  : - log/list.proxy php app/src/Utils/givethejob.php ./log/list.proxy
      
      





Webパネル(http:// docker-machineのIPアドレス:8080)で何が起こっているかを見てください。

結果は、キュー内で利用できるようになりますあります



そして結論として



驚いたことに、この記事の作成と編集は、コード自体の作成よりも時間がかかりました。



私の意見では、Message QueueEnterprise Service Busの 2つのイデオロギーではない場合、すべてが逆になる可能性があります(時間差は数倍大きくなる可能性があります)



設計段階でさまざまな部分の負荷が明確ではない、アプリケーションを作成するための提示されたアプローチをお役に立てれば幸いです。



ありがとう



All Articles