A’ gluasad backend PHP gu bus sruthan Redis agus a’ taghadh leabharlann neo-eisimeileach le frèam

A’ gluasad backend PHP gu bus sruthan Redis agus a’ taghadh leabharlann neo-eisimeileach le frèam

Facal-toisich

Tha an làrach-lìn agam, a bhios mi a’ ruith mar chur-seachad, air a dhealbhadh gus aoigheachd a thoirt do dhuilleagan dachaigh inntinneach agus làraich pearsanta. Thòisich an cuspair seo inntinneach dhomh aig fìor thoiseach mo thuras prògramaidh; aig an àm sin chuir e iongnadh orm le bhith a’ lorg proifeiseantaich sgoinneil a bhios a’ sgrìobhadh mun deidhinn fhèin, na cur-seachadan agus na pròiseactan aca. Tha an cleachdadh a bhith gan lorg dhomh fhìn fhathast chun an latha an-diugh: air cha mhòr a h-uile làrach malairteach agus nach eil gu math malairteach, tha mi a’ leantainn orm a’ coimhead anns a’ bhun-stèidh a’ lorg cheanglaichean ris na h-ùghdaran.

Cur an gnìomh a 'bheachd

Cha robh anns a’ chiad dreach ach duilleag html air an làrach-lìn phearsanta agam, far an do chuir mi ceanglaichean le ainmean-sgrìobhte ann an liosta ul. Às deidh dhomh 20 duilleag a thaipeadh thar ùine, thòisich mi a’ smaoineachadh nach robh seo gu math èifeachdach agus cho-dhùin mi feuchainn ris a’ phròiseas a dhèanamh fèin-ghluasadach. Air stackoverflow, mhothaich mi gu bheil mòran dhaoine a’ comharrachadh làraich anns na pròifilean aca, agus mar sin sgrìobh mi parser ann am php, a chaidh dìreach tro na pròifilean, a’ tòiseachadh leis a’ chiad fhear (tha seòlaidhean air SO chun an latha an-diugh mar seo: `/ luchd-cleachdaidh / 1` ), air ceanglaichean a thoirt a-mach às an taga a bha thu ag iarraidh agus chuir e ann an SQLite e.

Canar an dàrna tionndadh ris an seo: cruinneachadh de dheichean de mhìltean de URLan ann an clàr SQLite, a ghabh àite an liosta statach ann an html. Rinn mi rannsachadh sìmplidh air an liosta seo. Air sgàth cha robh ann ach URLan, agus bha an rannsachadh dìreach stèidhichte orra.

Aig an ìre seo thrèig mi am pròiseact agus thill mi thuige às deidh ùine mhòr. Aig an ìre seo, bha an t-eòlas obrach agam mu thràth còrr is trì bliadhna agus bha mi a’ faireachdainn gum b’ urrainn dhomh rudeigin nas cunnartaiche a dhèanamh. A bharrachd air an sin, bha miann mòr ann a bhith a’ faighinn eòlas air teicneòlasan an ìre mhath ùr.

Tionndadh ùr-nodha

Am pròiseact air a chleachdadh ann an Docker, chaidh an stòr-dàta a ghluasad gu mongoDb, agus o chionn ghoirid, chaidh radish a chuir ris, a bha an toiseach dìreach airson caching. Tha aon de na microframeworks PHP air a chleachdadh mar bhunait.

duilgheadas

Bidh làraichean ùra air an cur ris le àithne tòcan a nì na leanas gu sioncronaich:

  • Luchdaich sìos susbaint le URL
  • Suidhich bratach a sheallas an robh HTTPS ri fhaighinn
  • A’ gleidheadh ​​brìgh na làraich-lìn
  • Tha an stòr HTML agus na cinn-cinn air an sàbhaladh san eachdraidh “clàr-amais”.
  • Parses susbaint, earrainnean Tiotal agus Tuairisgeul
  • A’ sàbhaladh dàta gu cruinneachadh air leth

Bha seo gu leòr airson dìreach làraich a stòradh agus an taisbeanadh ann an liosta:

A’ gluasad backend PHP gu bus sruthan Redis agus a’ taghadh leabharlann neo-eisimeileach le frèam

Ach cha robh am beachd air clàr-amais gu fèin-ghluasadach, seòrsachadh agus rangachadh a h-uile càil, a’ cumail a h-uile càil ùraichte, a’ freagairt gu math ris a’ phàtran seo. Fiù ‘s dìreach le bhith a’ cur dòigh lìn ris gus duilleagan a chuir ris bha feum air dùblachadh còd agus bacadh gus DDoS a sheachnadh.

San fharsaingeachd, gu dearbh, faodar a h-uile càil a dhèanamh gu sioncronaich, agus anns an dòigh lìn faodaidh tu dìreach an URL a shàbhaladh gus am bi an daemon monstrous a ’coileanadh a h-uile gnìomh airson na URLan bhon liosta. Ach fhathast, eadhon an seo tha am facal “ciudha” ga mholadh fhèin. Agus ma thèid ciudha a chuir an gnìomh, faodar a h-uile gnìomh a roinn agus a choileanadh co-dhiù asyncronach.

co-dhùnadh

Cuir ciudha an gnìomh agus dèan siostam air a stiùireadh le tachartas airson a h-uile gnìomh a ghiullachd. Agus tha mi air a bhith ag iarraidh Redis Streams fheuchainn airson ùine mhòr.

A’ cleachdadh sruthan Redis ann am PHP

Air sgàth Leis nach eil am frèam agam mar aon de na trì fuamhairean Symfony, Laravel, Yii, bu mhath leam leabharlann neo-eisimeileach a lorg. Ach, mar a thionndaidh e a-mach (air a 'chiad sgrùdadh), tha e do-dhèanta a bhith a' lorg fìor leabharlannan fa leth. Tha a h-uile dad co-cheangailte ri ciudha an dàrna cuid na phròiseact bho 3 a’ gealltainn còig bliadhna air ais, no ceangailte ris an fhrèam.

Tha mi air tòrr a chluinntinn mu Symfony mar sholaraiche de phàirtean feumail fa leth, agus tha mi mu thràth a’ cleachdadh cuid dhiubh. Agus faodar cuideachd cuid de rudan bho Laravel a chleachdadh, mar eisimpleir an ORM aca, às aonais an fhrèam fhèin.

symfony/teachdaire

Bha coltas math air a’ chiad thagraiche sa bhad agus gun teagamh chuir mi a-steach e. Ach bha e na bu duilghe eisimpleirean de chleachdadh a dhèanamh taobh a-muigh Symfony. Ciamar a chruinnicheas tu bus airson teachdaireachdan a chuir seachad bho ghrunn chlasaichean le ainmean uile-choitcheann gun bhrìgh, agus eadhon air Redis?

A’ gluasad backend PHP gu bus sruthan Redis agus a’ taghadh leabharlann neo-eisimeileach le frèam

Bha na sgrìobhainnean air an làrach oifigeil gu math mionaideach, ach cha deach iomradh a thoirt air an toiseach ach airson Symfony a’ cleachdadh an YML as fheàrr leotha agus dòighean draoidheil eile airson an neach nach robh na symphon. Cha robh ùidh sam bith agam anns a 'phròiseas stàlaidh fhèin, gu h-àraid rè saor-làithean na Bliadhn' Ùire. Ach bha agam ri seo a dhèanamh airson ùine ris nach robh dùil.

Chan e a bhith a’ feuchainn ri faighinn a-mach ciamar a chuireas tu siostam sa bhad a’ cleachdadh stòran Symfony ris an obair as miosa airson ceann-latha teann:

A’ gluasad backend PHP gu bus sruthan Redis agus a’ taghadh leabharlann neo-eisimeileach le frèam

Às deidh dhomh sgrùdadh a dhèanamh air a h-uile càil seo agus feuchainn ri rudeigin a dhèanamh le mo làmhan, thàinig mi chun cho-dhùnadh gu robh mi a ’dèanamh seòrsa de sheòrsa crutches agus cho-dhùin mi rudeigin eile fheuchainn.

soillseachadh / ciudha

Thionndaidh e a-mach gu robh an leabharlann seo ceangailte gu teann ri bun-structar Laravel agus dòrlach de eisimeileachd eile, agus mar sin cha do chaith mi mòran ùine air: chuir mi a-steach e, choimhead mi air, chunnaic mi na h-eisimeileachd agus chuir mi às e.

yiisoft/yii2-ciudha

Uill, an seo chaidh gabhail ris sa bhad bhon ainm, a-rithist, ceangal teann ri Yii2. B’ fheudar dhomh an leabharlann seo a chleachdadh agus cha robh e dona, ach cha do smaoinich mi air gu bheil e gu tur an urra ri Yii2.

An còrr

Bha a h-uile càil eile a lorg mi air GitHub nam pròiseactan neo-earbsach, seann-fhasanta agus air an trèigsinn às aonais rionnagan, forcaichean agus àireamh mhòr de gheallaidhean.

Till gu symfony/teachdaire, mion-fhiosrachadh teicnigeach

B’ fheudar dhomh an leabharlann seo obrachadh a-mach agus, às deidh dhomh beagan ùine a bharrachd a chaitheamh, bha e comasach dhomh. Thionndaidh e a-mach gu robh a h-uile dad gu math pongail agus sìmplidh. Gus am bus a chuir air falbh, rinn mi factaraidh bheag, oir ... Bha còir agam grunn thaidhrichean a bhith agam agus le diofar làimhseachadh.

A’ gluasad backend PHP gu bus sruthan Redis agus a’ taghadh leabharlann neo-eisimeileach le frèam

Dìreach beagan cheumannan:

  • Bidh sinn a’ cruthachadh luchd-làimhseachaidh teachdaireachd a bu chòir a bhith dìreach air an gairm
  • Bidh sinn gan pasgadh ann an HandlerDescriptor (clas bhon leabharlann)
  • Bidh sinn a’ pasgadh na “Tuairisgeulan” sin ann an eisimpleir HandlersLocator
  • A’ cur HandlersLocator ris an eisimpleir MessageBus
  • Bidh sinn a’ toirt seachad seata de `SenderInterface` gu SendersLocator, anns a’ chùis agamsa de chlasaichean `RedisTransport`, a tha air an rèiteachadh ann an dòigh fhollaiseach
  • A’ cur SendersLocator ris an eisimpleir MessageBus

Tha modh `-> dispatch()` aig MessageBus a bhios a’ coimhead suas an luchd-làimhseachaidh iomchaidh anns an HandlersLocator agus a’ dol seachad air an teachdaireachd thuca, a’ cleachdadh an ‘SenderInterface’ co-fhreagarrach airson a chuir air a’ bhus (sruthan Redis).

Ann an rèiteachadh an t-soithich (anns a’ chùis seo php-di), faodar am pasgan slàn seo a rèiteachadh mar seo:

        CONTAINER_REDIS_TRANSPORT_SECRET => function (ContainerInterface $c) {
            return new RedisTransport(
                $c->get(CONTAINER_REDIS_STREAM_CONNECTION_SECRET),
                $c->get(CONTAINER_SERIALIZER))
            ;
        },
        CONTAINER_REDIS_TRANSPORT_LOG => function (ContainerInterface $c) {
            return new RedisTransport(
                $c->get(CONTAINER_REDIS_STREAM_CONNECTION_LOG),
                $c->get(CONTAINER_SERIALIZER))
            ;
        },
        CONTAINER_REDIS_STREAM_RECEIVER_SECRET => function (ContainerInterface $c) {
            return new RedisReceiver(
                $c->get(CONTAINER_REDIS_STREAM_CONNECTION_SECRET),
                $c->get(CONTAINER_SERIALIZER)
            );
        },
        CONTAINER_REDIS_STREAM_RECEIVER_LOG => function (ContainerInterface $c) {
            return new RedisReceiver(
                $c->get(CONTAINER_REDIS_STREAM_CONNECTION_LOG),
                $c->get(CONTAINER_SERIALIZER)
            );
        },
        CONTAINER_REDIS_STREAM_BUS => function (ContainerInterface $c) {
            $sendersLocator = new SendersLocator([
                AppMessagesSecretJsonMessages::class => [CONTAINER_REDIS_TRANSPORT_SECRET],
                AppMessagesDaemonLogMessage::class => [CONTAINER_REDIS_TRANSPORT_LOG],
            ], $c);
            $middleware[] = new SendMessageMiddleware($sendersLocator);

            return new MessageBus($middleware);
        },
        CONTAINER_REDIS_STREAM_CONNECTION_SECRET => function (ContainerInterface $c) {
            $host = 'bu-02-redis';
            $port = 6379;
            $dsn = "redis://$host:$port";
            $options = [
                'stream' => 'secret',
                'group' => 'default',
                'consumer' => 'default',
            ];

            return Connection::fromDsn($dsn, $options);
        },
        CONTAINER_REDIS_STREAM_CONNECTION_LOG => function (ContainerInterface $c) {
            $host = 'bu-02-redis';
            $port = 6379;
            $dsn = "redis://$host:$port";
            $options = [
                'stream' => 'log',
                'group' => 'default',
                'consumer' => 'default',
            ];

            return Connection::fromDsn($dsn, $options);
        },

An seo chì thu gu bheil sinn ann an SendersLocator gu bheil sinn air “còmhdhail” eadar-dhealaichte a shònrachadh airson dà theachdaireachd eadar-dhealaichte, agus tha a cheangal fhèin aig gach fear dhiubh ris na sruthan co-fhreagarrach.

Rinn mi pròiseact demo air leth a’ taisbeanadh cleachdadh de thrì daemonan a’ conaltradh ri chèile a’ cleachdadh a’ bhus a leanas: https://github.com/backend-university/products/tree/master/products/02-redis-streams-bus.

Ach seallaidh mi dhut mar as urrainn do neach-cleachdaidh a bhith air a structaradh:

use AppMessagesDaemonLogMessage;
use SymfonyComponentMessengerHandlerHandlerDescriptor;
use SymfonyComponentMessengerHandlerHandlersLocator;
use SymfonyComponentMessengerMessageBus;
use SymfonyComponentMessengerMiddlewareHandleMessageMiddleware;
use SymfonyComponentMessengerMiddlewareSendMessageMiddleware;
use SymfonyComponentMessengerTransportSenderSendersLocator;

require_once __DIR__ . '/../vendor/autoload.php';
/** @var PsrContainerContainerInterface $container */
$container = require_once('config/container.php');

$handlers = [
    DaemonLogMessage::class => [
        new HandlerDescriptor(
            function (DaemonLogMessage $m) {
                error_log('DaemonLogHandler: message handled: / ' . $m->getMessage());
            },
            ['from_transport' => CONTAINER_REDIS_TRANSPORT_LOG]
        )
    ],
];
$middleware = [];
$middleware[] = new HandleMessageMiddleware(new HandlersLocator($handlers));
$sendersLocator = new SendersLocator(['*' => [CONTAINER_REDIS_TRANSPORT_LOG]], $container);
$middleware[] = new SendMessageMiddleware($sendersLocator);

$bus = new MessageBus($middleware);
$receivers = [
    CONTAINER_REDIS_TRANSPORT_LOG => $container->get(CONTAINER_REDIS_STREAM_RECEIVER_LOG),
];
$w = new SymfonyComponentMessengerWorker($receivers, $bus, $container->get(CONTAINER_EVENT_DISPATCHER));
$w->run();

A’ cleachdadh a’ bhun-structair seo ann an tagradh

An dèidh dhomh am bus a chuir an gnìomh air mo chùl-raon, dhealaich mi ìrean fa-leth bhon t-seann àithne sioncronaich agus rinn mi làimhseachadh air leth, agus bidh gach fear dhiubh a’ dèanamh an rud fhèin.

Bha an loidhne-phìoban airson làrach ùr a chur ris an stòr-dàta a’ coimhead mar seo:

A’ gluasad backend PHP gu bus sruthan Redis agus a’ taghadh leabharlann neo-eisimeileach le frèam

Agus dìreach às deidh sin, dh’ fhàs e fada na b’ fhasa dhomh comas-gnìomh ùr a chuir ris, mar eisimpleir, a’ toirt a-mach agus a’ parsadh Rss. Air sgàth feumaidh am pròiseas seo cuideachd an t-susbaint tùsail, an uairsin bidh an inneal-làimhseachaidh ceangail RSS, leithid WebsiteIndexHistoryPersistor, a’ fo-sgrìobhadh don teachdaireachd “Content / HtmlContent”, ga phròiseasadh agus a’ dol seachad air an teachdaireachd a tha thu ag iarraidh air an loidhne-phìoban aige.

A’ gluasad backend PHP gu bus sruthan Redis agus a’ taghadh leabharlann neo-eisimeileach le frèam

Aig a 'cheann thall, chrìochnaich sinn le grunn dheamhan, agus tha gach aon dhiubh a' cumail suas ceanglaichean a-mhàin ris na goireasan riatanach. Mar eisimpleir deamhan crawlers anns a bheil a h-uile làimhseachadh a dh’ fheumas a dhol chun eadar-lìn airson susbaint, agus an deamhan leantuinn a’ cumail ceangal ris an stòr-dàta.

A-nis, an àite a bhith a’ taghadh bhon stòr-dàta, tha na h-ids a tha a dhìth às deidh an cuir a-steach leis an neach-leantainn dìreach air an cur tron ​​bhus gu gach neach-làimhseachaidh le ùidh.

Source: www.habr.com

Cuir beachd ann