Cliquez sur la renommée, ou comment exciter un robot et ... d'autres



Il était une fois, une conversation clandestine a eu lieu devant une boutique lointaine et lointaine :
NB: -         ? 

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

 NB: -      ,     ? 

GURU : - google yandex , . . , .

 NB: -       ? 

GURU : - ?… ...
NB a cessé de demander, craignant apparemment d'ennuyer un interlocuteur clairement plus expérimenté.
GURU roula des yeux, comme s'il soulignait l'épuisement du sujet proxy et se tut ...

Bien sûr, GURU savait qu'une requête de recherche (par exemple, par le mot: proxy) conduirait très prochainement NB à obtenir l'adresse souhaitée: liste des ports. Mais après les premières expériences, NB , tout aussi rapidement, comprendra:

  • Toutes les adresses de sa liste ne fonctionnent pas;
  • Tous les mandataires ne sont pas également bons;
  • «Coller» un site manuellement via un proxy est une tâche qui requiert une volonté considérable;
  • Un «mauvais» mandataire nuira à la situation, car le site peut être suspecté par des scripts de géants dans l'habillage.


Dans cet article, je vais parler de la façon dont improvisé (et surtout universel) signifie
(sans utiliser de logiciel propriétaire spécifique, tel que ZennoPoster , etc ...)
construire un outil automatisé pour obtenir une liste de procurations «vraiment adaptées» et les utiliser pour organiser des visites (automatisées) des promus
site à l'aide du navigateur Chrome .

En suivant les instructions, vous obtiendrez un outil prêt à l'emploi qui vous permettra de:

  • «Cliquez» sur (visiter) le site cible de manière entièrement automatique, sans crainte de compromis;
  • émuler pleinement le comportement de l'utilisateur;
  • organiser toutes les visites selon un calendrier (scénario);
  • faire tout ce qui précède dans le nombre de fois nécessaire pour avancer.

Et bien que tout mon travail (ainsi que la recherche) ait pris une semaine, vous n'aurez pas besoin de deux jours pour construire un tel outil, ayant une connaissance de base de la ligne de commande , PHP et JavaScript .


Cependant, avant de faire défiler ci-dessous le diagramme suivant , je dirai quelques mots sur la raison pour laquelle ce matériel est préparé et pour qui.

Le matériel sera utile si vous voulez comprendre comment les constructions (? Ou constructeurs?) Sont arrangées avec lesquelles vous pouvez construire une application relativement rapidement, facilement et sans coût, adaptable aux changements de charge. Si vous êtes intéressé par la possibilité de construire une application basée sur un bus de service ( ESB ).

Le texte sera utile si vous souhaitez vous familiariser avec l'utilisation de Docker pour les systèmes de construction instantanée . Ou si vous êtes simplement intéressé par Selenium Server et les nuances de la réception de contenu / manifestation d'activité HTTPx.
Pour "utiliser immédiatement", lire attentivement tout cela ne vaut pas la peine. Le code est sûr.
Passez directement à la configuration de l'outil fini. La configuration prend moins de 20 minutes.
Le manuel suppose que vous avez 2 machines à votre disposition avec Ubuntu 18.04 installé.
L'un pour l'infrastructure ( docker ), l'autre pour le contrôle des processus ( processus ).

Il est supposé que les packages suivants sont déjà installés sur docker :
git, docker, docker-compose

Il est supposé que les packages suivants sont déjà installés sur le processus :
git, php-common, php-cli, php-curl, php-zip, php-memcached, compositeur
Si vous avez des questions à ce stade, je vous suggère de passer 15 minutes à lire l'intégralité du matériel.

docker

 #    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-. 

processus

 #      . #      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 

Attendez, regardez ce qui se passe via le panneau Web (http: // ip-address-docker-machines: 8080).
Le résultat sera disponible dans la file d'attente localisée .

Concassage et planification




Le diagramme ci-dessus décrit la séquence des étapes du processus, le résultat attendu pour chaque étape et les ressources qui seront nécessaires pour créer chaque pièce (détails: Tâche 2 , Tâche 3 , Tâche 4,5,6 ).

Dans mon cas, tout se passe sur deux machines Ubuntu 18.04 . L'un d'eux contrôle le processus. De l'autre, plusieurs conteneurs Docker d'infrastructure sont en cours d'exécution.

Excuses et échecs


Tout le code du package se compose de trois parties.
L'un d'eux n'est pas le mien (je note que c'est un code soigné et beau). La source de ce code est packagist.org .

J'en ai moi-même écrit un autre, j'ai essayé de le rendre compréhensible et j'ai consacré environ une semaine à cette partie du code.

Le reste est un «héritage historique difficile». Cette partie du code a été créée sur une période assez longue. Y compris à une époque où je n'avais pas beaucoup de compétences en programmation.

C'est précisément la raison de l'emplacement des référentiels sur mon GitLab et des packages sur mes Satis . Pour être publié sur GitHub.com et packagist.org, ce code nécessitera un traitement et une documentation plus approfondie.

Toutes les parties du code sont ouvertes pour une utilisation illimitée. Les référentiels et packages seront disponibles pour toujours.

Cependant, lors de la réédition du code, je serai reconnaissant de poster un lien vers moi ou vers cet article.

Un peu d'architecture


L'approche qui a été utilisée pour créer notre outil est d'écrire (ou d'utiliser un utilitaire prêt à l'emploi) pour résoudre chaque tâche spécifique. De plus, chaque utilitaire, quelle que soit la tâche à résoudre, possède deux propriétés communes à tous:

  • l'utilitaire peut être lancé indépendamment des autres à partir de la ligne de commande avec des paramètres contenant la tâche;
  • l'utilitaire peut retourner le résultat de l'exécution à stdout (après avoir été configuré d'une certaine manière).

Une solution faite par ce principe vous permet de modifier le nombre de gestionnaires de tâches (travailleurs) en cours d'exécution pour chacune des étapes du processus. Un nombre différent de travailleurs pour chaque étape entraînera un temps d'arrêt de «0» pour les étapes qui suivent en raison de la longueur des tâches de traitement des étapes précédentes.

Le temps passé à obtenir une unité du résultat du processus (dans notre cas, il s'agit d'un proxy vérifié) dépend de facteurs externes (le nombre de proxy inappropriés, le temps de réponse d'une ressource externe, etc.).

En modifiant le nombre de travailleurs pour chacune des étapes du processus, nous transformons cette dépendance en dépendance du nombre de travailleurs en cours d'exécution (c'est-à-dire en fonction des capacités de calcul et de canal impliquées).

Pour synchroniser le fonctionnement de pièces indépendantes individuelles, il est pratique d'utiliser le serveur de file d'attente de messagerie comme un bus de données unique. Il vous permettra d'accumuler les résultats des étapes terminées dans la file d'attente et de les transmettre à l'utilitaire «étape suivante» au bon moment en entrée.

File d'attente de messagerie. MQ et ESB


En tant que niveau inférieur ( MQ ), nous utiliserons beanstalkd . Petit, léger, sans configuration, disponible dans le package deb et dans le conteneur Docker, un travailleur acharné discret. Le niveau logique ( ESB ) implémentera le code en PHP .

Deux classes seront utilisées pour l'implémentation. esbTask et nextStepWorker .

esbTask

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

Une instance de cette classe sert à «adresser» le paylod à travers les étapes du processus. Le concept ESB applique plusieurs principes / modèles. Deux d'entre eux méritent une attention particulière:

  • A propos du chemin (séquence d'étapes) du processus, à chaque moment du processus,
    personne ne sait sauf l'enveloppe à transmettre;
  • Chaque enveloppe a trois directions possibles des résultats:
    • l'étape suivante du processus (poursuite normale);
    • étape d'arrêt (cible d'arrêt - est sélectionnée par l'étape suivante, s'il est inutile de poursuivre le processus / la situation d'arrêt);
    • étape d'erreur (cible d'arrêt d'urgence - est sélectionnée à l'étape suivante, en cas d'erreur du travailleur).

L'objet en file d'attente est représenté dans json, caché ici ...
 // 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

Chaque message qui apparaît dans la file d'attente est traité par le travailleur qui en est responsable. Pour ce faire, l'ensemble de fonctions suivant est implémenté:

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

Les travailleurs pour chacune des étapes du processus sont implémentés sur la base de cette classe. Toute la routine de traitement, d'adressage et d'envoi de la prochaine étape de l'itinéraire, la classe s'en charge.

La solution à chacun de ces problèmes consiste à:

  1. Obtenez esbTask et exécutez le travailleur;
  2. Implémentez la logique en stockant les résultats dans la charge utile;
  3. Terminez l'exécution du travailleur (d'urgence ou normale - cela n'a pas d'importance).

Si les étapes sont terminées, le résultat sera mis en file d'attente avec le nom approprié et le prochain travailleur commencera le traitement.

Faites-le une fois. Vérifier la disponibilité


En fait, la création d'un travailleur pour résoudre l'un des problèmes est la mise en œuvre d'une méthode. Un exemple (simplifié) de la mise en œuvre d'un travailleur résolvant le problème 2 est le suivant:

 // 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')); } } 

Quelques lignes de code et tout est fait et «secondé» à l'étape suivante.

Définissez TimeZone. TimeZoneDB et à quoi ça sert ...


Un test approfondi des demandes entrantes implique de faire correspondre l'heure de la fenêtre du navigateur avec l'heure à laquelle l'adresse IP source de la demande existe.

Pour éviter toute suspicion de la part des compteurs, nous devons connaître l'heure du proxy local.

Pour connaître l'heure, nous prenons la latitude et la longitude des résultats de l'étape précédente du processus et obtenons des données sur le fuseau horaire dans lequel notre future instance de la fenêtre du navigateur fonctionnera. Ces données nous seront fournies par des professionnels du domaine du temps .

Un travailleur simplifié pour résoudre ce problème ( tâche 3 ) sera complètement similaire au précédent . La seule différence est l'URL de la demande. Vous pouvez trouver la version complète dans le fichier:
// app / src / Process / worker / timeZone.php

Un peu sur l'infrastructure


En plus du beanstalkd décrit, notre outil aura besoin de:

  • Memcached - pour les tâches de mise en cache;
  • Serveur Selenium - il est pratique d'exécuter Selenium Web Driver dans un conteneur séparé et vous pouvez surveiller le processus via VNC ;
  • Tableaux de bord pour la surveillance de Beanstald , Memcached et VNC .

Pour un déploiement rapide de tout cela, Docker ( Comment installer sur Ubuntu ) est très pratique.

Et «l'orchestrateur» pour lui est le docker-compose (commandes d'installation) ...
 sudo apt-get -y update sudo apt-get -y install docker-compose 


Ces outils vous permettent d'exécuter des serveurs / processus déjà configurés et configurés (par quelqu'un plus tôt) dans des «conteneurs» distincts du système d'exploitation parent. Pour plus de détails, je vous recommande de vous référer à tel ou tel article.

Alors ...

Pour démarrer l'infrastructure, vous avez besoin de plusieurs commandes dans la console:

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

Suite à l'exécution réussie de la commande sur la machine avec l'adresse XXX.XXX.XXX.XXX,
Vous recevrez l'ensemble de services suivant:
- XXX.XXX.XXX.XXX:11300 - beanstalkd
- XXX.XXX.XXX.XXX:11211 - Memcached
- XXX.XXX.XXX.XXX-00-00444 - Serveur Selenium
- XXX.XXX.XXX.XXX:5930 - serveur VNC pour contrôler ce qui se passe dans Chrome
- XXX.XXX.XXX.XXX:8081 - Panneau Web pour communiquer avec Memcached (admin: pass)
- XXX.XXX.XXX.XXX:8082 - Panneau Web pour communiquer avec beanstalkd
- XXX.XXX.XXX.XXX:8083 - Panneau Web pour communiquer avec VNC (mot de passe: secret)
- XXX.XXX.XXX.XXX:8080 - Panneau Web général

«Voir si tout est en place», «entrer dans la console pour le conteneur», «arrêter l'infrastructure» peuvent être des commandes dans le spoiler.
 #   ,    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) 

Tâches 4,5,6 - se combinent en un seul utilitaire


Après avoir examiné en détail l'écrasement des tâches ( diagramme ci-dessus ), il est facile de s'assurer qu'une seule des tâches restantes ( tâche 6 ) dépend d'une ressource externe. En effectuant des tâches avec des durées d'exécution «conditionnellement garanties» (indépendantes de facteurs non contrôlés), nous n'obtiendrons pas d'avantages supplémentaires à la vitesse de l'ensemble du processus. À cet égard, ces tâches ( 4,5,6 ) ont été combinées en un seul travailleur. Le fichier de travail est appelé:
// app / src / Process / worker / whoerChecker.php

Définissez les paramètres de Chrome. Plugins


Chrome est configuré de manière flexible avec des plugins.

Un plugin pour Chrome est une archive qui contient un fichier manifest.json . Il décrit le plugin. L'archive contient également un ensemble de JavaScript, html, css et autres fichiers nécessaires au plugin ( détails ).

Dans notre cas, l'un des fichiers JavaScript sera exécuté dans le contexte de la fenêtre de travail de Chrome et tous les paramètres nécessaires prendront effet.

Nous avons juste besoin de prendre le modèle de plugin et de substituer les données nécessaires (protocole d'interaction, adresse et port ou fuseau horaire) pour le serveur proxy sous test aux bons endroits.

Un extrait de code qui rend l'archive:

 // 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; } .... } 

Le modèle du plugin de réglage du proxy a été trouvé dans la tirelire des résultats du travail des personnes qui aiment leur profession , changé dans la partie protocole et ajouté au référentiel.

Changement de temps de fenêtre


Pour modifier l'heure globale d'une instance Chrome en cours d'exécution, nous devons remplacer window.Date par une classe avec des fonctionnalités similaires, mais valide dans le bon fuseau horaire.

J'apprécie vraiment le travail de Sampo Juustila . Le script a été conçu pour les tests automatisés de l' interface utilisateur , mais après un petit raffinement a été appliqué.

Il y a une nuance ici sur laquelle je veux attirer votre attention. Il est associé au contexte des scripts décrits dans manifest.json .

Tout le secret est que le contexte global (celui dans lequel le script principal du plug-in est lancé et les paramètres définis, par exemple, connecté au réseau) est isolé du contexte de l'onglet dans lequel la page est chargée.

Empiriquement, il a été constaté que l'impact sur le prototype de la classe dans le contexte global n'a pas conduit à son changement dans l'onglet. Cependant, après avoir enregistré le script dans la page déjà chargée et l'avoir exécuté avant les autres, le problème a été résolu.

La solution est représentée par le fragment de code suivant:

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

Paramètres proxy


La configuration d'un proxy dans Chrome est si simple que je vais cacher le code js dans un spoiler
 // 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'] ); 


Chemin des plugins Chrome


Tous les plugins sont nommés selon le schéma et sont ajoutés au dossier temporaire de la machine qui contrôle le processus.
// schéma de nommage pour le plugin proxy:
proxy- [adresse] - [port] - [protocole]>. zip
Timeshift - ["-" | ""] - [shift_in_minutes_from_GMT] .zip

Ensuite, nous devons installer ces plugins dans un conteneur Docker qui s'exécute sur la machine responsable de l'infrastructure.

Nous le ferons avec 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


Chrome Selenium Server .

Selenium Server — -, FaceBook WEB-.

- ( 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); 


Et donc, j'ai légèrement réduit tout cela, optimisant la configuration pour mes besoins:

 // 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 ); .... } .... 

L'œil s'accroche immédiatement aux plugins $. $ plugins est une structure de données chargée de configurer les plugins. Pour chaque répertoire et pour remplacer les espaces réservés dans les fichiers JavaScript du plugin.

La structure est décrite dans le fichier app / plugs.php et fait partie des options globales 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' ] ] ]; 


L'analyse d'une page avec Selenium WebDriver est très simple.

 .... $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'); .... 

Comme je l'ai déjà écrit, toutes ces actions sont implémentées par l'utilitaire de la troisième étape ( tâche 4,5,6 ):
// app / src / Process / worker / whoerChecker.php
Selenium Server , , (1000 — 3000 ), , Selenium Server . . .

«» . «» 2 . cron . Docker- , renskiy , , ( ).

Docker- docker-compose.yml, . killcron, .

WebRTC


, , , .

( IP ), « ». flash WebRTC , . Flash , WebRTC — .

UDP -. WebRTC : 3478 19302 .

«» «chrome», - iptables:

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

proxyHelper.


— «» , .

whoerChecker . , , .

, located , «» .

«» . « » , esbTask ( since ESB ).

, yandex- .




, :

  • , « » ( ) esbTask json- , beanstalkd ;
  • ( MQ ), beanstalkd ;
  • Linux- (Process-);

«», , libevent React PHP . , , ( ) .

, , . — " noserver ". — " server ".
, .
. , ,… . , , , , , .

habr , . , , .

. , " server ", README.md .

" noserver ", ( ). .

«».

:

 // 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 , , .
app/queues.php
app/plugs.php Chrome -
app/techs.php


Pour faciliter le traitement des résultats du processus et le placement des tâches, il existe plusieurs utilitaires. Les utilitaires sont lancés à partir de la ligne de commande. Fourni avec des descriptions d'arguments. Situé: app / src / Utils .
 backup.php - enregistre les files d'attente dans un fichier
    clear.php - nettoie les files d'attente
    exporter.php - exporte à partir d'un fichier avec une file d'attente enregistrée 
                     adresse des paires: port
    givethejob.php - publie des tâches dans le processus 
                     (source - adresse: zone de liste déroulante des ports).
                     peut exclure certaines adresses de la liste
    restore.php - restaure une file d'attente enregistrée 

Affiner les travailleurs


Lors de l'utilisation de travailleurs écrits, il peut être pratique d'utiliser les options de configuration suivantes:

 // 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'] ); .... 


Déploiement


, 2 Ubuntu 18.04 .
( docker ), ( process ).

docker

 #    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-. 

process

 #      . #   . 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://ip---:8080).
located .


, , .

( ), : Message Queue Enterprise Service Bus .

, , .

Je vous remercie

Source: https://habr.com/ru/post/fr432038/


All Articles