PHP பின்தளத்தை ரெடிஸ் ஸ்ட்ரீம்ஸ் பேருந்திற்கு மாற்றுதல் மற்றும் கட்டமைப்பின் சார்பற்ற நூலகத்தைத் தேர்ந்தெடுப்பது

PHP பின்தளத்தை ரெடிஸ் ஸ்ட்ரீம்ஸ் பேருந்திற்கு மாற்றுதல் மற்றும் கட்டமைப்பின் சார்பற்ற நூலகத்தைத் தேர்ந்தெடுப்பது

முன்னுரையில்

நான் பொழுதுபோக்காக நடத்தும் எனது இணையதளம், சுவாரஸ்யமான முகப்புப் பக்கங்களையும் தனிப்பட்ட தளங்களையும் ஹோஸ்ட் செய்யும் வகையில் வடிவமைக்கப்பட்டுள்ளது. எனது நிரலாக்க பயணத்தின் ஆரம்பத்திலேயே இந்த தலைப்பு எனக்கு ஆர்வமாக இருந்தது; அந்த நேரத்தில் தங்களைப் பற்றியும், அவர்களின் பொழுதுபோக்குகள் மற்றும் திட்டங்களைப் பற்றி எழுதும் சிறந்த நிபுணர்களைக் கண்டுபிடிப்பதில் நான் ஈர்க்கப்பட்டேன். நானே அவற்றைக் கண்டுபிடிக்கும் பழக்கம் இன்றுவரை உள்ளது: கிட்டத்தட்ட எல்லா வணிகத் தளங்களிலும் மற்றும் மிகவும் வணிகரீதியான தளங்களிலும், ஆசிரியர்களுக்கான இணைப்புகளைத் தேடி அடிக்குறிப்பைத் தொடர்ந்து பார்க்கிறேன்.

யோசனையை செயல்படுத்துதல்

முதல் பதிப்பு எனது தனிப்பட்ட இணையதளத்தில் ஒரு html பக்கமாக இருந்தது, அதில் கையொப்பங்களுடன் இணைப்புகளை உல் பட்டியலில் வைத்தேன். ஒரு குறிப்பிட்ட காலத்திற்குள் 20 பக்கங்களைத் தட்டச்சு செய்ததால், இது மிகவும் பயனுள்ளதாக இல்லை என்று நான் நினைக்க ஆரம்பித்தேன், மேலும் செயல்முறையை தானியக்கமாக்க முயற்சிக்க முடிவு செய்தேன். ஸ்டாக்ஓவர்ஃப்ளோவில், பலர் தங்கள் சுயவிவரங்களில் தளங்களைக் குறிப்பிடுவதை நான் கவனித்தேன், எனவே நான் php இல் ஒரு பாகுபடுத்தலை எழுதினேன், இது முதலில் தொடங்கி சுயவிவரங்கள் வழியாகச் சென்றது (இன்று வரை SO இல் உள்ள முகவரிகள் பின்வருமாறு: `/பயனர்கள்/1` ), விரும்பிய குறிச்சொல்லில் இருந்து இணைப்புகள் பிரித்தெடுக்கப்பட்டு SQLite இல் சேர்க்கப்பட்டது.

இதை இரண்டாவது பதிப்பு என்று அழைக்கலாம்: HTML இல் நிலையான பட்டியலை மாற்றிய SQLite அட்டவணையில் உள்ள பல்லாயிரக்கணக்கான URLகளின் தொகுப்பு. இந்த பட்டியலில் நான் ஒரு எளிய தேடலை செய்தேன். ஏனெனில் URLகள் மட்டுமே இருந்தன, பின்னர் தேடல் வெறுமனே அவற்றை அடிப்படையாகக் கொண்டது.

இந்த நிலையில் நான் திட்டத்தை கைவிட்டு நீண்ட நாட்களுக்குப் பிறகு திரும்பினேன். இந்த கட்டத்தில், எனது பணி அனுபவம் ஏற்கனவே மூன்று வருடங்களுக்கும் மேலாக இருந்தது, மேலும் தீவிரமாக ஏதாவது செய்ய முடியும் என்று உணர்ந்தேன். கூடுதலாக, ஒப்பீட்டளவில் புதிய தொழில்நுட்பங்களை மாஸ்டர் செய்ய ஒரு பெரிய ஆசை இருந்தது.

நவீன பதிப்பு

திட்டம் டோக்கரில் பயன்படுத்தப்பட்டது, தரவுத்தளம் மோங்கோடிபிக்கு மாற்றப்பட்டது, மேலும் சமீபத்தில், முள்ளங்கி சேர்க்கப்பட்டது, இது முதலில் தேக்ககத்திற்காக மட்டுமே இருந்தது. PHP மைக்ரோஃப்ரேம்வொர்க்குகளில் ஒன்று அடிப்படையாகப் பயன்படுத்தப்படுகிறது.

பிரச்சனை

ஒரு கன்சோல் கட்டளை மூலம் புதிய தளங்கள் சேர்க்கப்படுகின்றன, அது பின்வருவனவற்றை ஒத்திசைவாகச் செய்கிறது:

  • URL மூலம் உள்ளடக்கத்தைப் பதிவிறக்குகிறது
  • HTTPS கிடைக்குமா என்பதைக் குறிக்கும் கொடியை அமைக்கிறது
  • இணையதளத்தின் சாரத்தை பாதுகாக்கிறது
  • மூல HTML மற்றும் தலைப்புகள் "இண்டெக்சிங்" வரலாற்றில் சேமிக்கப்படும்
  • உள்ளடக்கத்தை பாகுபடுத்துகிறது, தலைப்பு மற்றும் விளக்கத்தை பிரித்தெடுக்கிறது
  • ஒரு தனி சேகரிப்பில் தரவைச் சேமிக்கிறது

தளங்களைச் சேமித்து அவற்றை பட்டியலில் காட்ட இது போதுமானது:

PHP பின்தளத்தை ரெடிஸ் ஸ்ட்ரீம்ஸ் பேருந்திற்கு மாற்றுதல் மற்றும் கட்டமைப்பின் சார்பற்ற நூலகத்தைத் தேர்ந்தெடுப்பது

ஆனால் எல்லாவற்றையும் தானாக அட்டவணைப்படுத்துதல், வகைப்படுத்துதல் மற்றும் தரவரிசைப்படுத்துதல், அனைத்தையும் புதுப்பித்த நிலையில் வைத்திருப்பது போன்ற யோசனை இந்த முன்னுதாரணத்திற்கு சரியாக பொருந்தவில்லை. பக்கங்களைச் சேர்க்க ஒரு வலை முறையைச் சேர்ப்பது கூட, சாத்தியமான DDoS ஐத் தவிர்க்க, குறியீடு நகல் மற்றும் தடுப்பதைத் தேவைப்படுகிறது.

பொதுவாக, நிச்சயமாக, எல்லாவற்றையும் ஒத்திசைவாக செய்ய முடியும், மேலும் இணைய முறையில் நீங்கள் URL ஐ வெறுமனே சேமிக்க முடியும், இதனால் பட்டியலிலிருந்து URLகளுக்கான அனைத்து பணிகளையும் கொடூரமான டீமான் செய்கிறது. ஆனால் இன்னும், இங்கே கூட "வரிசை" என்ற வார்த்தை தன்னைக் குறிக்கிறது. ஒரு வரிசை செயல்படுத்தப்பட்டால், அனைத்து பணிகளும் பிரிக்கப்பட்டு குறைந்தபட்சம் ஒத்திசைவற்ற முறையில் செய்யப்படலாம்.

முடிவு

வரிசைகளை செயல்படுத்தவும் மற்றும் அனைத்து பணிகளையும் செயலாக்க ஒரு நிகழ்வு-உந்துதல் அமைப்பை உருவாக்கவும். நான் ரெடிஸ் ஸ்ட்ரீம்களை நீண்ட காலமாக முயற்சிக்க விரும்பினேன்.

PHP இல் ரெடிஸ் ஸ்ட்ரீம்களைப் பயன்படுத்துதல்

ஏனெனில் எனது கட்டமைப்பு சிம்ஃபோனி, லாராவெல், யி ஆகிய மூன்று மாபெரும் நிறுவனங்களில் ஒன்றல்ல என்பதால், நான் ஒரு சுதந்திர நூலகத்தைக் கண்டுபிடிக்க விரும்புகிறேன். ஆனால், அது மாறியது போல் (முதல் தேர்வில்), தனிப்பட்ட தீவிர நூலகங்களைக் கண்டுபிடிப்பது சாத்தியமில்லை. வரிசைகள் தொடர்பான அனைத்தும் ஐந்து ஆண்டுகளுக்கு முன்பு 3 கமிட்களில் இருந்து ஒரு திட்டமாகும், அல்லது கட்டமைப்போடு இணைக்கப்பட்டுள்ளது.

தனிப்பட்ட பயனுள்ள கூறுகளின் சப்ளையராக சிம்ஃபோனியைப் பற்றி நான் நிறைய கேள்விப்பட்டிருக்கிறேன், அவற்றில் சிலவற்றை நான் ஏற்கனவே பயன்படுத்துகிறேன். மேலும் Laravel இலிருந்து சில விஷயங்களையும் பயன்படுத்தலாம், எடுத்துக்காட்டாக, அவற்றின் ORM, கட்டமைப்பின் முன்னிலையில் இல்லாமல்.

symfony/messenger

முதல் வேட்பாளர் உடனடியாக சிறந்தவராகத் தோன்றினார், எந்த சந்தேகமும் இல்லாமல் நான் அதை நிறுவினேன். ஆனால் சிம்ஃபோனிக்கு வெளியே பயன்படுத்துவதற்கான எடுத்துக்காட்டுகளை கூகிள் செய்வது மிகவும் கடினமாக இருந்தது. உலகளாவிய, அர்த்தமற்ற பெயர்கள், செய்திகளை அனுப்புவதற்கான பேருந்து மற்றும் ரெடிஸ்ஸில் கூட வகுப்புகளின் தொகுப்பிலிருந்து எவ்வாறு ஒன்று சேர்வது?

PHP பின்தளத்தை ரெடிஸ் ஸ்ட்ரீம்ஸ் பேருந்திற்கு மாற்றுதல் மற்றும் கட்டமைப்பின் சார்பற்ற நூலகத்தைத் தேர்ந்தெடுப்பது

அதிகாரப்பூர்வ தளத்தில் உள்ள ஆவணங்கள் மிகவும் விரிவாக இருந்தன, ஆனால் சிம்ஃபோனிக்கு அவர்களுக்குப் பிடித்த YML மற்றும் சிம்போனிஸ்டு அல்லாதவர்களுக்கான மற்ற மேஜிக் முறைகளைப் பயன்படுத்தி மட்டுமே துவக்கம் விவரிக்கப்பட்டது. குறிப்பாக புத்தாண்டு விடுமுறை நாட்களில் நிறுவல் செயல்பாட்டில் எனக்கு ஆர்வம் இல்லை. ஆனால் நான் எதிர்பாராத விதமாக நீண்ட நேரம் இதைச் செய்ய வேண்டியிருந்தது.

சிம்ஃபோனி ஆதாரங்களைப் பயன்படுத்தி ஒரு கணினியை எவ்வாறு உடனடியாக உருவாக்குவது என்பதைக் கண்டுபிடிக்க முயற்சிப்பது இறுக்கமான காலக்கெடுவிற்கு மிகவும் அற்பமான பணி அல்ல:

PHP பின்தளத்தை ரெடிஸ் ஸ்ட்ரீம்ஸ் பேருந்திற்கு மாற்றுதல் மற்றும் கட்டமைப்பின் சார்பற்ற நூலகத்தைத் தேர்ந்தெடுப்பது

இதையெல்லாம் அலசி ஆராய்ந்து, கைகளால் எதையாவது செய்ய முற்பட்ட பிறகு, நான் ஏதோ ஊன்றுகோல் செய்கிறேன் என்ற முடிவுக்கு வந்து, வேறு ஏதாவது முயற்சி செய்ய முடிவு செய்தேன்.

ஒளிரும்/வரிசை

இந்த நூலகம் லாராவெல் உள்கட்டமைப்பு மற்றும் பிற சார்புகளுடன் இறுக்கமாக இணைக்கப்பட்டுள்ளது, எனவே நான் அதில் அதிக நேரம் செலவிடவில்லை: நான் அதை நிறுவி, அதைப் பார்த்தேன், சார்புகளைப் பார்த்து நீக்கினேன்.

yiisoft/yii2-வரிசை

சரி, இங்கே அது உடனடியாக பெயரிலிருந்து கருதப்பட்டது, மீண்டும், Yii2 க்கு ஒரு கண்டிப்பான இணைப்பு. நான் இந்த நூலகத்தைப் பயன்படுத்த வேண்டியிருந்தது, அது மோசமாக இல்லை, ஆனால் அது முற்றிலும் Yii2 ஐப் பொறுத்தது என்ற உண்மையைப் பற்றி நான் நினைக்கவில்லை.

மீதமுள்ளவை

கிட்ஹப்பில் நான் கண்டறிந்த மற்ற அனைத்தும் நம்பகத்தன்மையற்றவை, காலாவதியான மற்றும் நட்சத்திரங்கள், ஃபோர்க்குகள் மற்றும் அதிக எண்ணிக்கையிலான கமிட்கள் இல்லாத திட்டங்கள்.

சிம்ஃபோனி/மெசஞ்சர், தொழில்நுட்ப விவரங்களுக்குத் திரும்பு

இந்த நூலகத்தை நான் கண்டுபிடிக்க வேண்டியிருந்தது, மேலும் சிறிது நேரம் செலவழித்த பிறகு, என்னால் முடிந்தது. எல்லாம் மிகவும் சுருக்கமாகவும் எளிமையாகவும் இருந்தது என்று மாறியது. பஸ்ஸை உடனடியாக இயக்க, நான் ஒரு சிறிய தொழிற்சாலையை உருவாக்கினேன், ஏனென்றால்... என்னிடம் பல டயர்கள் மற்றும் வெவ்வேறு கையாளுபவர்கள் இருக்க வேண்டும்.

PHP பின்தளத்தை ரெடிஸ் ஸ்ட்ரீம்ஸ் பேருந்திற்கு மாற்றுதல் மற்றும் கட்டமைப்பின் சார்பற்ற நூலகத்தைத் தேர்ந்தெடுப்பது

ஒரு சில படிகள்:

  • வெறுமனே அழைக்கக்கூடிய செய்தி கையாளுபவர்களை நாங்கள் உருவாக்குகிறோம்
  • நாங்கள் அவற்றை HandlerDescriptor இல் (நூலகத்திலிருந்து வகுப்பு) மூடுகிறோம்
  • இந்த "விளக்கங்களை" ஒரு HandlersLocator நிகழ்வில் மூடுகிறோம்
  • MessageBus நிகழ்வில் HandlersLocator ஐச் சேர்த்தல்
  • SendersLocator க்கு `SenderInterface`ன் தொகுப்பை அனுப்புகிறோம், என்னுடைய விஷயத்தில் `RedisTransport` வகுப்புகள் வெளிப்படையான முறையில் கட்டமைக்கப்பட்டுள்ளன.
  • MessageBus நிகழ்வில் SendersLocator ஐச் சேர்த்தல்

MessageBus ஒரு `->dispatch()` முறையைக் கொண்டுள்ளது, இது HandlersLocator இல் பொருத்தமான ஹேண்ட்லர்களைப் பார்த்து, அவர்களுக்குச் செய்தியை அனுப்பும், தொடர்புடைய `SenderInterface`ஐப் பயன்படுத்தி பஸ் (ரெடிஸ் ஸ்ட்ரீம்கள்) வழியாக அனுப்புகிறது.

கொள்கலன் உள்ளமைவில் (இந்த வழக்கில் 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 பின்தளத்தை ரெடிஸ் ஸ்ட்ரீம்ஸ் பேருந்திற்கு மாற்றுதல் மற்றும் கட்டமைப்பின் சார்பற்ற நூலகத்தைத் தேர்ந்தெடுப்பது

அதன் பிறகு, புதிய செயல்பாட்டைச் சேர்ப்பது எனக்கு மிகவும் எளிதாகிவிட்டது, எடுத்துக்காட்டாக, Rss ஐ பிரித்தெடுத்தல் மற்றும் பாகுபடுத்துதல். ஏனெனில் இந்த செயல்முறைக்கு அசல் உள்ளடக்கம் தேவைப்படுகிறது, பின்னர் RSS இணைப்பு பிரித்தெடுத்தல் கையாளுபவர், WebsiteIndexHistoryPersistor போன்றது, "உள்ளடக்கம்/HtmlContent" செய்திக்கு குழுசேர்ந்து, அதை செயலாக்குகிறது மற்றும் விரும்பிய செய்தியை அதன் பைப்லைனில் மேலும் அனுப்புகிறது.

PHP பின்தளத்தை ரெடிஸ் ஸ்ட்ரீம்ஸ் பேருந்திற்கு மாற்றுதல் மற்றும் கட்டமைப்பின் சார்பற்ற நூலகத்தைத் தேர்ந்தெடுப்பது

முடிவில், நாங்கள் பல டெமான்களுடன் முடித்தோம், அவை ஒவ்வொன்றும் தேவையான ஆதாரங்களுடன் மட்டுமே இணைப்புகளை பராமரிக்கின்றன. உதாரணமாக ஒரு பேய் கிராலர்கள் உள்ளடக்கத்திற்காக இணையத்திற்குச் செல்ல வேண்டிய அனைத்து ஹேண்ட்லர்கள் மற்றும் டீமான் ஆகியவற்றைக் கொண்டுள்ளது நிலைத்திருக்கும் தரவுத்தளத்துடன் ஒரு இணைப்பை வைத்திருக்கிறது.

இப்போது, ​​தரவுத்தளத்திலிருந்து தேர்ந்தெடுப்பதற்குப் பதிலாக, பெர்சிஸ்டரால் செருகப்பட்ட பிறகு தேவையான ஐடிகள், ஆர்வமுள்ள அனைத்து கையாளுபவர்களுக்கும் பேருந்து வழியாக அனுப்பப்படும்.

ஆதாரம்: www.habr.com

கருத்தைச் சேர்