Интиқоли пуштибонии PHP ба автобуси ҷараёнҳои Redis ва интихоби китобхонаи аз чаҳорчӯба мустақил

Интиқоли пуштибонии PHP ба автобуси ҷараёнҳои Redis ва интихоби китобхонаи аз чаҳорчӯба мустақил

Пешгуфтор

Вебсайти ман, ки ман ҳамчун як маҳфил кор мекунам, барои ҷойгир кардани саҳифаҳои хонагӣ ва сайтҳои шахсӣ тарҳрезӣ шудааст. Ин мавзӯъ маро дар ибтидои сафари барномасозӣ ба худ ҷалб кард; дар он лаҳза ман аз пайдо кардани мутахассисони бузурге, ки дар бораи худ, маҳфилҳо ва лоиҳаҳои худ менависанд, маро ба ҳайрат овард. Одати кашфи онҳо барои худам то имрӯз боқӣ мондааст: қариб дар ҳар як сайти тиҷоратӣ ва на он қадар тиҷоратӣ ман дар ҷустуҷӯи истинод ба муаллифон дар поёни поён нигоҳ мекунам.

Татбиқи идея

Варианти аввал танҳо як саҳифаи html дар вебсайти шахсии ман буд, ки дар он ман истинодҳоро бо имзоҳо ба рӯйхати ul гузоштам. Пас аз чоп кардани 20 саҳифа дар тӯли як муддат, ман фикр кардам, ки ин чандон муассир нест ва тасмим гирифтам, ки ин равандро автоматӣ кунам. Ҳангоми stackoverflow, ман пайхас кардам, ки бисёр одамон сайтҳоро дар профилҳои худ нишон медиҳанд, бинобар ин ман дар php як таҳлилгар навиштам, ки он танҳо аз профилҳо сар карда аз аввал гузаштааст (суроғаҳо дар SO то имрӯз чунинанд: `/users/1` ), истинодҳоро аз теги дилхоҳ истихроҷ кард ва онро дар SQLite илова кард.

Инро метавон версияи дуюм номид: маҷмӯи даҳҳо ҳазор URL-ҳо дар ҷадвали SQLite, ки рӯйхати статикиро дар HTML иваз кард. Ман дар ин рӯйхат ҷустуҷӯи оддӣ кардам. Зеро танҳо URL-ҳо буданд, пас ҷустуҷӯ танҳо ба онҳо асос ёфтааст.

Дар ин марҳила ман лоиҳаро тарк кардам ва пас аз муддати тӯлонӣ ба он баргаштам. Дар ин марҳила таҷрибаи кории ман аллакай беш аз се сол буд ва ҳис мекардам, ки метавонам кори ҷиддитарро анҷом диҳам. Гайр аз ин, майлу хохиши азхуд кардани техникаи нисбатан нав пайдо шуд.

Версияи муосир

Лоиҳа Дар Docker ҷойгир карда шуд, базаи маълумот ба mongoDb интиқол дода шуд ва ба наздикӣ, шалғамча илова карда шуд, ки дар аввал танҳо барои кэш буд. Яке аз микрочаҳорчӯбҳои PHP ҳамчун асос истифода мешавад.

проблема

Сомонаҳои нав бо фармони консол илова карда мешаванд, ки ба таври синхронӣ амалҳои зеринро иҷро мекунанд:

  • Мундариҷаро аз рӯи URL зеркашӣ мекунад
  • Парчамеро муқаррар мекунад, ки дастрас будани HTTPS-ро нишон медиҳад
  • Моҳияти вебсайтро нигоҳ медорад
  • Сарчашмаи HTML ва сарлавҳаҳо дар таърихи "индексизатсия" захира карда мешаванд
  • Мундариҷаро таҳлил мекунад, унвон ва тавсифро иқтибос мекунад
  • Маълумотро ба коллексияи алоҳида захира мекунад

Ин барои нигоҳ доштани сайтҳо ва намоиши онҳо дар рӯйхат кофӣ буд:

Интиқоли пуштибонии PHP ба автобуси ҷараёнҳои Redis ва интихоби китобхонаи аз чаҳорчӯба мустақил

Аммо идеяи ба таври худкор индексатсия кардан, гурӯҳбандӣ кардан ва гурӯҳбандӣ кардани ҳама чиз, навсозӣ кардани ҳама чиз ба ин парадигма чандон мувофиқ набуд. Ҳатто танҳо илова кардани як усули веб барои илова кардани саҳифаҳо такрори код ва блокро талаб мекард, то DDoS-и эҳтимолиро пешгирӣ кунад.

Умуман, албатта, ҳама чизро метавон ба таври синхронӣ анҷом дод ва дар усули веб шумо метавонед танҳо URL-ро захира кунед, то демони даҳшатовар ҳама вазифаҳоро барои URL-ҳои рӯйхат иҷро кунад. Аммо ба ҳар ҳол, ҳатто дар ин ҷо калимаи "навбат" худашро пешниҳод мекунад. Ва агар навбат амалӣ карда шавад, пас ҳама вазифаҳоро метавон тақсим кард ва ҳадди аққал асинхронӣ иҷро кард.

ҳалли

Навбатҳоро амалӣ кунед ва системаи ба рӯйдодҳо асосёфтаро барои коркарди ҳама вазифаҳо эҷод кунед. Ва ман муддати тӯлонӣ мехостам Redis Streams -ро санҷам.

Истифодаи ҷараёнҳои Redis дар PHP

Зеро Азбаски чаҳорчӯбаи ман яке аз се бузургии Symfony, Laravel, Yii нест, ман мехоҳам як китобхонаи мустақил пайдо кунам. Аммо, чунон ки маълум шуд (дар муоинаи аввал) китобхонахои алохидаи чиддиро ёфтан мумкин нест. Ҳама чизе, ки ба навбат алоқаманд аст, ё лоиҳаи 3 супориши панҷ сол пеш аст, ё ба чаҳорчӯба вобаста аст.

Ман дар бораи Symfony ҳамчун таъминкунандаи ҷузъҳои муфиди инфиродӣ бисёр шунидаам ва аллакай баъзеи онҳоро истифода мебарам. Ва инчунин баъзе чизҳо аз Laravel низ метавонанд истифода шаванд, масалан, ORM-и онҳо, бидуни ҳузури худи чаҳорчӯба.

symfony/messenger

Номзади аввал дарҳол беҳтарин ба назар мерасид ва ман онро насб кардам. Аммо маълум шуд, ки Google мисолҳои истифода берун аз Symfony душвортар буд. Чӣ тавр аз як гурӯҳи синфҳо бо номҳои универсалӣ, бемаънӣ, автобус барои интиқоли паёмҳо ва ҳатто дар Redis ҷамъ овардан мумкин аст?

Интиқоли пуштибонии PHP ба автобуси ҷараёнҳои Redis ва интихоби китобхонаи аз чаҳорчӯба мустақил

Ҳуҷҷатҳо дар сайти расмӣ хеле муфассал буд, аммо оғозсозӣ танҳо барои Symfony бо истифода аз YML дӯстдоштаи худ ва дигар усулҳои ҷодугарӣ барои ғайрисимфонист тасвир шудааст. Ман ба худи раванди насб, махсусан дар рӯзҳои ҷашни Соли нав таваҷҷӯҳ надоштам. Аммо ба ман лозим омад, ки муддати тӯлонӣ ғайричашмдошт ин корро кунам.

Кӯшиши фаҳмидани чӣ гуна сохтани система бо истифода аз манбаъҳои Symfony низ кори ночизтарин барои мӯҳлати маҳдуд нест:

Интиқоли пуштибонии PHP ба автобуси ҷараёнҳои Redis ва интихоби китобхонаи аз чаҳорчӯба мустақил

Пас аз он ки ҳамаи инҳоро фаҳмидам ва кӯшиш кардам, ки бо дастонам коре анҷом диҳам, ман ба хулосае омадам, ки ман ягон намуди асобаро иҷро карда истодаам ва тасмим гирифтам, ки чизи дигарро санҷам.

мунаввар/навбат

Маълум шуд, ки ин китобхона бо инфрасохтори Laravel ва як қатор вобастагии дигар зич алоқаманд аст, бинобар ин ман вақти зиёд сарф накардам: ман онро насб кардам, ба он нигоҳ кардам, вобастагиҳоро дидам ва нест кардам.

yiisoft/yii2-навбат

Хуб, дар ин ҷо он дарҳол аз ном тахмин карда шуд, боз, пайвасти қатъӣ ба Yii2. Ман маҷбур будам, ки ин китобхонаро истифода барам ва ин бад набуд, аммо ман дар бораи он фикр накардаам, ки он комилан аз Yii2 вобаста аст.

Дигар

Ҳама чизи дигаре, ки ман дар GitHub ёфтам, лоиҳаҳои беэътимод, кӯҳна ва партофташуда бе ситораҳо, форкҳо ва шумораи зиёди ӯҳдадориҳо буданд.

Бозгашт ба symfony/messenger, тафсилоти техникӣ

Ман маҷбур будам, ки ин китобхонаро фаҳмам ва пас аз чанд вақти дигар, ман тавонистам. Маълум шуд, ки ҳама чиз хеле мухтасар ва оддӣ буд. Барои ба вуҷуд овардани автобус ман як корхонаи хурд сохтам, зеро... Ман бояд якчанд шина ва бо коркардкунандагони гуногун дошта бошам.

Интиқоли пуштибонии PHP ба автобуси ҷараёнҳои Redis ва интихоби китобхонаи аз чаҳорчӯба мустақил

Танҳо чанд қадам:

  • Мо коркардкунандагони паёмҳоро эҷод мекунем, ки бояд ба таври оддӣ даъват карда шаванд
  • Мо онҳоро дар HandlerDescriptor мепӯшем (синф аз китобхона)
  • Мо ин "Тасвиркунандагон" -ро дар мисоли HandlersLocator мепӯшем
  • Илова кардани HandlersLocator ба мисоли MessageBus
  • Мо маҷмӯи `SenderInterface`-ро ба SendersLocator мерасонем, дар ҳолати ман, синфҳои `RedisTransport`, ки ба таври равшан танзим карда шудаанд
  • Илова кардани SendersLocator ба мисоли MessageBus

MessageBus дорои усули `->dispatch()` мебошад, ки коркардкунандагони мувофиқро дар 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, ба монанди WebsiteIndexHistoryPersistor, ба паёми "Content/HtmlContent" обуна шуда, онро коркард мекунад ва паёми дилхоҳро дар хати лӯлаи худ интиқол медиҳад.

Интиқоли пуштибонии PHP ба автобуси ҷараёнҳои Redis ва интихоби китобхонаи аз чаҳорчӯба мустақил

Дар ниҳоят, мо бо якчанд демонҳо ба охир расидем, ки ҳар яки онҳо танҳо ба захираҳои зарурӣ пайваст мешаванд. Масалан шайтон ҳунармандон дорои ҳамаи коркардкунандагонест, ки барои мундариҷа ва демон рафтан ба Интернетро талаб мекунанд истодагарӣ кардан ба базаи маълумот пайваст дорад.

Ҳоло, ба ҷои интихоб аз пойгоҳи додаҳо, идентификаторҳои зарурӣ, пас аз ворид кардани персистер, танҳо тавассути автобус ба ҳама коркардкунандагони манфиатдор интиқол дода мешаванд.

Манбаъ: will.com

Илова Эзоҳ