PHP బ్యాకెండ్‌ని Redis స్ట్రీమ్స్ బస్సుకు బదిలీ చేయడం మరియు ఫ్రేమ్‌వర్క్-ఇండిపెండెంట్ లైబ్రరీని ఎంచుకోవడం

PHP బ్యాకెండ్‌ని Redis స్ట్రీమ్స్ బస్సుకు బదిలీ చేయడం మరియు ఫ్రేమ్‌వర్క్-ఇండిపెండెంట్ లైబ్రరీని ఎంచుకోవడం

ముందుమాట

నేను అభిరుచిగా నడుపుతున్న నా వెబ్‌సైట్ ఆసక్తికరమైన హోమ్ పేజీలు మరియు వ్యక్తిగత సైట్‌లను హోస్ట్ చేయడానికి రూపొందించబడింది. ఈ అంశం నా ప్రోగ్రామింగ్ ప్రయాణం ప్రారంభంలోనే నాకు ఆసక్తి కలిగించడం ప్రారంభించింది; ఆ సమయంలో నేను తమ గురించి, వారి అభిరుచులు మరియు ప్రాజెక్ట్‌ల గురించి వ్రాసే గొప్ప నిపుణులను కనుగొనడం ద్వారా ఆకర్షితుడయ్యాను. నా కోసం వాటిని కనుగొనే అలవాటు ఈనాటికీ ఉంది: దాదాపు ప్రతి వాణిజ్య మరియు చాలా వాణిజ్య సైట్‌లలో, రచయితలకు లింక్‌ల కోసం నేను ఫుటరులో చూస్తూనే ఉన్నాను.

ఆలోచన అమలు

మొదటి వెర్షన్ నా వ్యక్తిగత వెబ్‌సైట్‌లోని html పేజీ మాత్రమే, ఇక్కడ నేను సంతకాలతో లింక్‌లను ఉల్ జాబితాలో ఉంచాను. కొంత వ్యవధిలో 20 పేజీలను టైప్ చేసిన తర్వాత, ఇది చాలా ప్రభావవంతంగా లేదని నేను ఆలోచించడం ప్రారంభించాను మరియు ప్రక్రియను ఆటోమేట్ చేయడానికి ప్రయత్నించాలని నిర్ణయించుకున్నాను. స్టాక్‌ఓవర్‌ఫ్లో, చాలా మంది వ్యక్తులు తమ ప్రొఫైల్‌లలో సైట్‌లను సూచిస్తున్నట్లు నేను గమనించాను, కాబట్టి నేను phpలో ఒక పార్సర్‌ని వ్రాసాను, అది మొదటి దానితో ప్రారంభించి ప్రొఫైల్‌ల ద్వారా వెళ్ళింది (ఈ రోజు వరకు SOలోని చిరునామాలు ఇలా ఉన్నాయి: `/users/1` ), కావలసిన ట్యాగ్ నుండి లింక్‌లను సంగ్రహించి, దానిని SQLiteలో జోడించారు.

దీనిని రెండవ వెర్షన్ అని పిలవవచ్చు: SQLite పట్టికలో పదివేల URLల సేకరణ, ఇది htmlలో స్టాటిక్ జాబితాను భర్తీ చేసింది. నేను ఈ జాబితాలో ఒక సాధారణ శోధన చేసాను. ఎందుకంటే URLలు మాత్రమే ఉన్నాయి, అప్పుడు శోధన కేవలం వాటిపై ఆధారపడి ఉంటుంది.

ఈ దశలో నేను ప్రాజెక్ట్‌ను వదులుకున్నాను మరియు చాలా కాలం తర్వాత దానికి తిరిగి వచ్చాను. ఈ దశలో, నా పని అనుభవం ఇప్పటికే మూడు సంవత్సరాలకు పైగా ఉంది మరియు నేను మరింత తీవ్రంగా ఏదైనా చేయగలనని భావించాను. అదనంగా, సాపేక్షంగా కొత్త సాంకేతికతలను నేర్చుకోవాలనే గొప్ప కోరిక ఉంది.

ఆధునిక వెర్షన్

ప్రాజెక్ట్ డాకర్‌లో అమలు చేయబడింది, డేటాబేస్ mongoDbకి బదిలీ చేయబడింది మరియు ఇటీవల, ముల్లంగి జోడించబడింది, ఇది మొదట కాషింగ్ కోసం మాత్రమే. PHP మైక్రోఫ్రేమ్‌వర్క్‌లలో ఒకటి ఆధారంగా ఉపయోగించబడుతుంది.

సమస్య

కింది వాటిని సమకాలీకరించే కన్సోల్ కమాండ్ ద్వారా కొత్త సైట్‌లు జోడించబడతాయి:

  • URL ద్వారా కంటెంట్‌ని డౌన్‌లోడ్ చేస్తుంది
  • HTTPS అందుబాటులో ఉందో లేదో సూచించే ఫ్లాగ్‌ను సెట్ చేస్తుంది
  • వెబ్‌సైట్ యొక్క సారాన్ని భద్రపరుస్తుంది
  • మూలం HTML మరియు హెడర్‌లు "ఇండెక్సింగ్" చరిత్రలో సేవ్ చేయబడతాయి
  • కంటెంట్‌ను అన్వయిస్తుంది, శీర్షిక మరియు వివరణను సంగ్రహిస్తుంది
  • డేటాను ప్రత్యేక సేకరణకు సేవ్ చేస్తుంది

ఇది కేవలం సైట్‌లను నిల్వ చేయడానికి మరియు వాటిని జాబితాలో ప్రదర్శించడానికి సరిపోతుంది:

PHP బ్యాకెండ్‌ని Redis స్ట్రీమ్స్ బస్సుకు బదిలీ చేయడం మరియు ఫ్రేమ్‌వర్క్-ఇండిపెండెంట్ లైబ్రరీని ఎంచుకోవడం

కానీ స్వయంచాలకంగా సూచిక చేయడం, వర్గీకరించడం మరియు ప్రతిదానిని ర్యాంక్ చేయడం, ప్రతిదీ తాజాగా ఉంచడం వంటి ఆలోచన ఈ నమూనాకు సరిగ్గా సరిపోలేదు. పేజీలను జోడించడానికి వెబ్ పద్ధతిని జోడించడం వల్ల కూడా కోడ్ డూప్లికేషన్ అవసరం మరియు సంభావ్య DDoSని నివారించడానికి బ్లాక్ చేయడం అవసరం.

సాధారణంగా, వాస్తవానికి, ప్రతిదీ సమకాలీకరించబడుతుంది మరియు వెబ్ పద్ధతిలో మీరు కేవలం URLని సేవ్ చేయవచ్చు, తద్వారా క్రూరమైన డెమోన్ జాబితా నుండి URLల కోసం అన్ని పనులను చేస్తుంది. కానీ ఇప్పటికీ, ఇక్కడ కూడా "క్యూ" అనే పదం స్వయంగా సూచిస్తుంది. మరియు క్యూ అమలు చేయబడితే, అప్పుడు అన్ని పనులు విభజించబడతాయి మరియు కనీసం అసమకాలికంగా నిర్వహించబడతాయి.

నిర్ణయం

క్యూలను అమలు చేయండి మరియు అన్ని టాస్క్‌లను ప్రాసెస్ చేయడానికి ఈవెంట్-ఆధారిత వ్యవస్థను రూపొందించండి. మరియు నేను చాలా కాలంగా Redis స్ట్రీమ్‌లను ప్రయత్నించాలనుకుంటున్నాను.

PHPలో Redis స్ట్రీమ్‌లను ఉపయోగించడం

ఎందుకంటే Symfony, Laravel, Yii అనే మూడు దిగ్గజాలలో నా ఫ్రేమ్‌వర్క్ ఒకటి కానందున, నేను స్వతంత్ర లైబ్రరీని కనుగొనాలనుకుంటున్నాను. కానీ, అది ముగిసిన (మొదటి పరీక్షలో), వ్యక్తిగత తీవ్రమైన లైబ్రరీలను కనుగొనడం అసాధ్యం. క్యూలకు సంబంధించిన ప్రతిదీ ఐదు సంవత్సరాల క్రితం 3 కమిట్‌ల నుండి వచ్చిన ప్రాజెక్ట్ లేదా ఫ్రేమ్‌వర్క్‌తో ముడిపడి ఉంటుంది.

వ్యక్తిగత ఉపయోగకరమైన భాగాల సరఫరాదారుగా నేను Symfony గురించి చాలా విన్నాను మరియు నేను ఇప్పటికే వాటిలో కొన్నింటిని ఉపయోగిస్తున్నాను. మరియు లారావెల్ నుండి కొన్ని వస్తువులను కూడా ఉపయోగించవచ్చు, ఉదాహరణకు వాటి ORM, ఫ్రేమ్‌వర్క్ లేకుండానే.

symfony/messenger

మొదటి అభ్యర్థి వెంటనే ఆదర్శంగా అనిపించింది మరియు ఎటువంటి సందేహం లేకుండా నేను దానిని ఇన్‌స్టాల్ చేసాను. కానీ Symfony వెలుపల ఉపయోగించే Google ఉదాహరణలను ఉపయోగించడం చాలా కష్టంగా మారింది. సార్వత్రికమైన, అర్థరహితమైన పేర్లతో, సందేశాలను పంపడానికి బస్సు మరియు Redisలో కూడా తరగతుల సమూహం నుండి ఎలా సమీకరించాలి?

PHP బ్యాకెండ్‌ని Redis స్ట్రీమ్స్ బస్సుకు బదిలీ చేయడం మరియు ఫ్రేమ్‌వర్క్-ఇండిపెండెంట్ లైబ్రరీని ఎంచుకోవడం

అధికారిక సైట్‌లోని డాక్యుమెంటేషన్ చాలా వివరంగా ఉంది, కానీ సింఫోనిస్ట్ కానివారి కోసం వారి ఇష్టమైన YML మరియు ఇతర మ్యాజిక్ పద్ధతులను ఉపయోగించి ప్రారంభించడం మాత్రమే Symfony కోసం వివరించబడింది. ఇన్‌స్టాలేషన్ ప్రాసెస్‌పై నాకు ఆసక్తి లేదు, ముఖ్యంగా న్యూ ఇయర్ సెలవుల్లో. కానీ అనుకోకుండా చాలా కాలం ఇలా చేయాల్సి వచ్చింది.

Symfony మూలాధారాలను ఉపయోగించి సిస్టమ్‌ను ఎలా ఇన్‌స్టాంటియేట్ చేయాలో గుర్తించడానికి ప్రయత్నించడం కూడా కఠినమైన గడువు కోసం చాలా చిన్న పని కాదు:

PHP బ్యాకెండ్‌ని Redis స్ట్రీమ్స్ బస్సుకు బదిలీ చేయడం మరియు ఫ్రేమ్‌వర్క్-ఇండిపెండెంట్ లైబ్రరీని ఎంచుకోవడం

వీటన్నింటిని లోతుగా పరిశోధించి, నా చేతులతో ఏదో చేయాలని ప్రయత్నించిన తరువాత, నేను ఒక రకమైన క్రచెస్ చేస్తున్నానని నిర్ధారణకు వచ్చాను మరియు ఇంకేదైనా ప్రయత్నించాలని నిర్ణయించుకున్నాను.

ప్రకాశించే/క్యూ

ఈ లైబ్రరీ లారావెల్ ఇన్‌ఫ్రాస్ట్రక్చర్ మరియు ఇతర డిపెండెన్సీల సమూహంతో గట్టిగా ముడిపడి ఉందని తేలింది, కాబట్టి నేను దానిపై ఎక్కువ సమయం వెచ్చించలేదు: నేను దానిని ఇన్‌స్టాల్ చేసాను, చూశాను, డిపెండెన్సీలను చూసాను మరియు తొలగించాను.

yiisoft/yii2-క్యూ

బాగా, ఇక్కడ అది వెంటనే పేరు నుండి ఊహించబడింది, మళ్ళీ, Yii2కి ఖచ్చితమైన కనెక్షన్. నేను ఈ లైబ్రరీని ఉపయోగించాల్సి వచ్చింది మరియు అది చెడ్డది కాదు, కానీ ఇది పూర్తిగా Yii2పై ఆధారపడి ఉంటుంది అనే వాస్తవం గురించి నేను ఆలోచించలేదు.

మిగిలినవి

GitHubలో నేను కనుగొన్న మిగతావన్నీ నక్షత్రాలు, ఫోర్కులు మరియు పెద్ద సంఖ్యలో కమిట్‌లు లేని విశ్వసనీయత లేనివి, కాలం చెల్లినవి మరియు వదలివేయబడిన ప్రాజెక్ట్‌లు.

సింఫోనీ/మెసెంజర్, సాంకేతిక వివరాలకు తిరిగి వెళ్ళు

నేను ఈ లైబ్రరీని గుర్తించవలసి వచ్చింది మరియు మరికొంత సమయం గడిపిన తర్వాత, నేను చేయగలిగాను. ప్రతిదీ చాలా సంక్షిప్తంగా మరియు సరళంగా ఉందని తేలింది. బస్సును తక్షణం చేయడానికి, నేను ఒక చిన్న ఫ్యాక్టరీని చేసాను, ఎందుకంటే... నేను అనేక టైర్లు మరియు విభిన్న హ్యాండ్లర్‌లను కలిగి ఉండవలసి ఉంది.

PHP బ్యాకెండ్‌ని Redis స్ట్రీమ్స్ బస్సుకు బదిలీ చేయడం మరియు ఫ్రేమ్‌వర్క్-ఇండిపెండెంట్ లైబ్రరీని ఎంచుకోవడం

కేవలం కొన్ని దశలు:

  • మేము మెసేజ్ హ్యాండ్లర్‌లను సృష్టిస్తాము, అవి కేవలం కాల్ చేయగలవు
  • మేము వాటిని హ్యాండ్లర్‌డిస్క్రిప్టర్‌లో చుట్టాము (లైబ్రరీ నుండి తరగతి)
  • మేము ఈ “డిస్క్రిప్టర్‌లను” హ్యాండ్లర్స్‌లోకేటర్ ఉదాహరణలో చుట్టాము
  • MessageBus ఉదాహరణకి HandlersLocatorని జోడిస్తోంది
  • మేము SendersLocatorకి `SenderInterface` సెట్‌ను పంపుతాము, నా విషయంలో `RedisTransport` తరగతులకు స్పష్టమైన మార్గంలో కాన్ఫిగర్ చేయబడింది
  • MessageBus ఉదాహరణకి SendersLocatorని జోడిస్తోంది

MessageBus ఒక `->డిస్పాచ్()` పద్ధతిని కలిగి ఉంది, ఇది HandlersLocatorలో తగిన హ్యాండ్లర్‌లను చూసి వారికి సందేశాన్ని పంపుతుంది, సంబంధిత `SenderInterface`ని ఉపయోగించి బస్సు (Redis స్ట్రీమ్‌లు) ద్వారా పంపుతుంది.

కంటైనర్ కాన్ఫిగరేషన్‌లో (ఈ సందర్భంలో php-di), ఈ మొత్తం బండిల్‌ను ఇలా కాన్ఫిగర్ చేయవచ్చు:

        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);
        },

SendersLocatorలో మేము రెండు వేర్వేరు సందేశాల కోసం వేర్వేరు “రవాణా”లను కేటాయించినట్లు ఇక్కడ మీరు చూడవచ్చు, వీటిలో ప్రతి ఒక్కటి సంబంధిత స్ట్రీమ్‌లకు దాని స్వంత కనెక్షన్‌ను కలిగి ఉంటాయి.

నేను ఈ క్రింది బస్సును ఉపయోగించి ఒకదానితో ఒకటి కమ్యూనికేట్ చేసుకునే మూడు డెమోన్‌ల అప్లికేషన్‌ను ప్రదర్శించే ప్రత్యేక డెమో ప్రాజెక్ట్‌ను రూపొందించాను: https://github.com/backend-university/products/tree/master/products/02-redis-streams-bus.

కానీ వినియోగదారుని ఎలా నిర్మించాలో నేను మీకు చూపిస్తాను:

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

అప్లికేషన్‌లో ఈ మౌలిక సదుపాయాలను ఉపయోగించడం

నా బ్యాకెండ్‌లో బస్సును అమలు చేసిన తర్వాత, నేను పాత సింక్రోనస్ కమాండ్ నుండి వ్యక్తిగత దశలను వేరు చేసాను మరియు ప్రత్యేక హ్యాండ్లర్‌లను తయారు చేసాను, ప్రతి ఒక్కరూ వారి స్వంత పనిని చేస్తారు.

డేటాబేస్‌కు కొత్త సైట్‌ని జోడించే పైప్‌లైన్ ఇలా ఉంది:

PHP బ్యాకెండ్‌ని Redis స్ట్రీమ్స్ బస్సుకు బదిలీ చేయడం మరియు ఫ్రేమ్‌వర్క్-ఇండిపెండెంట్ లైబ్రరీని ఎంచుకోవడం

మరియు ఆ వెంటనే, నాకు కొత్త ఫంక్షనాలిటీని జోడించడం చాలా సులభం అయింది, ఉదాహరణకు, Rssని సంగ్రహించడం మరియు అన్వయించడం. ఎందుకంటే ఈ ప్రక్రియకు అసలు కంటెంట్ కూడా అవసరం, ఆపై వెబ్‌సైట్‌ఇండెక్స్‌హిస్టరీ పెర్సిస్టర్ వంటి RSS లింక్ ఎక్స్‌ట్రాక్టర్ హ్యాండ్లర్ “కంటెంట్/HtmlContent” సందేశానికి సబ్‌స్క్రైబ్ చేసి, దానిని ప్రాసెస్ చేస్తుంది మరియు దాని పైప్‌లైన్‌లో కావలసిన సందేశాన్ని మరింత ముందుకు పంపుతుంది.

PHP బ్యాకెండ్‌ని Redis స్ట్రీమ్స్ బస్సుకు బదిలీ చేయడం మరియు ఫ్రేమ్‌వర్క్-ఇండిపెండెంట్ లైబ్రరీని ఎంచుకోవడం

చివరికి, మేము అనేక డెమోన్‌లతో ముగించాము, వీటిలో ప్రతి ఒక్కటి అవసరమైన వనరులకు మాత్రమే కనెక్షన్‌లను నిర్వహిస్తుంది. ఉదాహరణకు ఒక రాక్షసుడు క్రాలర్ కంటెంట్ కోసం ఇంటర్నెట్‌కి వెళ్లాల్సిన అన్ని హ్యాండ్లర్‌లు మరియు డెమోన్‌ని కలిగి ఉంటుంది అంటిపెట్టుకుని ఉంటారు డేటాబేస్కు కనెక్షన్ కలిగి ఉంది.

ఇప్పుడు, డేటాబేస్ నుండి ఎంచుకోవడానికి బదులుగా, పెర్‌సిస్టర్ చొప్పించిన తర్వాత అవసరమైన ఐడిలు ఆసక్తిగల హ్యాండ్లర్‌లందరికీ బస్సు ద్వారా ప్రసారం చేయబడతాయి.

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి