åºæ
趣å³ã§éå¶ããŠããç§ã® Web ãµã€ãã¯ãèå³æ·±ãããŒã ããŒãžãå人ãµã€ãããã¹ãããããã«èšèšãããŠããŸãã ãã®ãããã¯ã«èå³ãæã¡å§ããã®ã¯ãããã°ã©ãã³ã°ã®æ
ãå§ããã°ããã®é ã§ããããã®ç¬éãç§ã¯èªåèªèº«ã趣å³ããããžã§ã¯ãã«ã€ããŠæžããŠããåªããå°é家ãèŠã€ããããšã«é
äºãããŸããã èªåã§ããããèŠã€ããç¿æ
£ã¯ä»ã§ãæ®ã£ãŠããŸããã»ãšãã©ãã¹ãŠã®åçšãµã€ãã§ããããŸãåçšã§ãªããµã€ãã§ããèè
ãžã®ãªã³ã¯ãæ¢ããŠããã¿ãŒã調ã¹ç¶ããŠããŸãã
ã¢ã€ãã¢ã®å®çŸ
æåã®ããŒãžã§ã³ã¯ç§ã®å人ç㪠Web ãµã€ãäžã® HTML ããŒãžã§ã眲åä»ãã®ãªã³ã¯ã UL ãªã¹ãã«è¿œå ããŸããã äžå®æéã«ããã£ãŠ 20 ããŒãžãå ¥åããåŸãããã§ã¯ããŸãå¹æçã§ã¯ãªããšèãå§ããããã»ã¹ãèªååããŠã¿ãããšã«ããŸããã stackoverflow ã§ãå€ãã®äººãèªåã®ãããã¡ã€ã«ã§ãµã€ãã瀺ããŠããããšã«æ°ã¥ããŸããããã®ãããæåã®ãããã¡ã€ã«ããå§ããŠãããã¡ã€ã«ãåçŽã«åŠçããããŒãµãŒã php ã§äœæããŸãã (ä»æ¥ãŸã§ã® SO ã®ã¢ãã¬ã¹ã¯æ¬¡ã®ãšããã§ã: `/users/1`) )ãç®çã®ã¿ã°ãããªã³ã¯ãæœåºããSQLite ã«è¿œå ããŸããã
ãã㯠XNUMX çªç®ã®ããŒãžã§ã³ãšåŒã¶ããšãã§ããŸããSQLite ããŒãã«å ã®æ°äžã® URL ã®ã³ã¬ã¯ã·ã§ã³ã§ãããHTML ã®éçãªã¹ãã眮ãæãããã®ã§ãã ãã®ãªã¹ãããç°¡åãªæ€çŽ¢ãããŠã¿ãŸããã ãªããªãURL ã®ã¿ããããæ€çŽ¢ã¯åã« URL ã«åºã¥ããŠããŸããã
ãã®æ®µéã§ãããžã§ã¯ããæŸæ£ããä¹ ãã¶ãã«ãããžã§ã¯ãã«æ»ããŸããã ãã®æ®µéã§ãç§ã®è·æŽã¯ãã§ã« XNUMX 幎以äžã«ãªã£ãŠããããã£ãšæ¬æ Œçãªããšãã§ããã®ã§ã¯ãªãããšæããŠããŸããã ããã«ãæ¯èŒçæ°ãããã¯ãããžãŒãç¿åŸããããšãã匷ãé¡æããããŸããã
çŸä»£ç
åé¡
æ°ãããµã€ãã¯ã次ã®ããšãåæçã«å®è¡ããã³ã³ãœãŒã« ã³ãã³ãã«ãã£ãŠè¿œå ãããŸãã
- URLããšã«ã³ã³ãã³ããããŠã³ããŒãããŸã
- HTTPS ãå©çšå¯èœãã©ããã瀺ããã©ã°ãèšå®ããŸã
- ãŠã§ããµã€ãã®æ¬è³ªãç¶æãã
- ãœãŒã¹HTMLãšããããŒã¯ãã€ã³ããã¯ã¹äœæãå±¥æŽã«ä¿åãããŸã
- ã³ã³ãã³ãã解æããã¿ã€ãã«ãšèª¬æãæœåºããŸã
- ããŒã¿ãå¥ã®ã³ã¬ã¯ã·ã§ã³ã«ä¿åããŸã
åçŽã«ãµã€ããä¿åããŠãªã¹ãã«è¡šç€ºããã«ã¯ãããã§ååã§ããã
ãããããã¹ãŠãèªåçã«ã€ã³ããã¯ã¹ä»ããåé¡ãã©ã³ã¯ä»ããããã¹ãŠãææ°ã®ç¶æ
ã«ä¿ã€ãšããã¢ã€ãã¢ã¯ããã®ãã©ãã€ã ã«ã¯ããŸãé©åããŸããã§ããã ããŒãžãè¿œå ãã Web ã¡ãœãããè¿œå ããã ãã§ããæœåšç㪠DDoS ãåé¿ããããã«ã³ãŒãã®è€è£œãšãããã¯ãå¿
èŠã§ããã
ãã¡ãããäžè¬çã«ã¯ãã¹ãŠãåæçã«è¡ãããšãã§ããWeb ã¡ãœããã§ã¯ URL ãä¿åããã ãã§ã巚倧ãªããŒã¢ã³ããªã¹ãã® URL ã«å¯Ÿãããã¹ãŠã®ã¿ã¹ã¯ãå®è¡ã§ããŸãã ããããããã§ããããã§ããè¡åããšããèšèèªäœãæ瀺ãããŠããŸãã ãŸãããã¥ãŒãå®è£ ãããŠããå Žåããã¹ãŠã®ã¿ã¹ã¯ãåå²ããŠãå°ãªããšãéåæã«å®è¡ã§ããŸãã
ãœãªã¥ãŒã·ã§ã³
ãã¥ãŒãå®è£ ãããã¹ãŠã®ã¿ã¹ã¯ãåŠçããããã®ã€ãã³ãé§ååã·ã¹ãã ãäœæããŸãã ãããŠãç§ã¯é·ãé Redis Streams ãè©ŠããŠã¿ãããšæã£ãŠããŸããã
PHP ã§ã® Redis ã¹ããªãŒã ã®äœ¿çš
ãªããªãç§ã®ãã¬ãŒã ã¯ãŒã¯ã¯ SymfonyãLaravelãYii ã® 3 ã€ã®å·šäººã®ã©ãã§ããªãã®ã§ãç¬ç«ããã©ã€ãã©ãªãæ¢ããããšæã£ãŠããŸãã ããããïŒæåã®èª¿æ»ã§ïŒå€æããããã«ãåå¥ã®æ¬æ Œçãªã©ã€ãã©ãªãèŠã€ããããšã¯äžå¯èœã§ãã ãã¥ãŒã«é¢é£ãããã®ã¯ãã¹ãŠãXNUMX 幎åã® XNUMX ã€ã®ã³ãããããã®ãããžã§ã¯ãã§ãããããã¬ãŒã ã¯ãŒã¯ã«é¢é£ä»ããããŠããŸãã
Symfony ã«ã€ããŠã¯ãåå¥ã®äŸ¿å©ãªã³ã³ããŒãã³ãã®ãµãã©ã€ã€ãŒãšããŠããè³ã«ããŠããããã§ã«ããã€ãã䜿çšããŠããŸãã ãŸããLaravel ã®äžéšã®ãã® (ORM ãªã©) ãããã¬ãŒã ã¯ãŒã¯èªäœãååšããªããŠã䜿çšã§ããŸãã
symfony/ã¡ãã»ã³ãžã£ãŒ
æåã®åè£ãããã«çæ³çã ãšæããäœã®çãããªããããã€ã³ã¹ããŒã«ããŸããã ããããSymfony 以å€ã§ã®äœ¿çšäŸã Google ã§æ€çŽ¢ããã®ã¯ããã«é£ããããšãå€æããŸããã æ®éçã§æå³ã®ãªãååãã¡ãã»ãŒãžãæž¡ãããã®ãã¹ãããã«ã¯ Redis äžã§ãããæã€å€æ°ã®ã¯ã©ã¹ããçµã¿ç«ãŠãã«ã¯ã©ãããã°ããã§ãããã?
å
¬åŒãµã€ãã®ããã¥ã¡ã³ãã¯éåžžã«è©³çŽ°ã§ããããSymfony ã®ãæ°ã«å
¥ãã® YML ãéã·ã³ãã©ãã¹ãåãã®ãã®ä»ã®éæ³ã®ã¡ãœããã䜿çšãã Symfony ã®åæåã«ã€ããŠã®ã¿èª¬æãããŠããŸããã ç¹ã«å¹Žæ«å¹Žå§ã¯ãã€ã³ã¹ããŒã«ã®ããã»ã¹èªäœã«èå³ããããŸããã§ããã ããããäºæ³å€ã«é·ãéãããè¡ãå¿
èŠããããŸããã
Symfony ãœãŒã¹ã䜿çšããŠã·ã¹ãã ãã€ã³ã¹ã¿ã³ã¹åããæ¹æ³ãèŠã€ãåºãããšããå³ããç· ãåãã®äžã§ã®æãç°¡åãªäœæ¥ã§ã¯ãããŸããã
ããããã¹ãŠãæãäžããŠãèªåã®æã§äœããããããšããåŸãç§ã¯ããçš®ã®æŸèæã䜿ã£ãŠãããšããçµè«ã«éããå¥ã®ããšãè©ŠããŠã¿ãããšã«ããŸããã
ã©ã€ãã¢ãã/ãã¥ãŒ
ãã®ã©ã€ãã©ãªã¯ Laravel ã€ã³ãã©ã¹ãã©ã¯ãã£ããã®ä»ã®å€æ°ã®äŸåé¢ä¿ã«å¯æ¥ã«é¢é£ä»ããããŠããããšãå€æãããããç§ã¯ããã«ããŸãæéãè²»ãããŸããã§ãããã€ã³ã¹ããŒã«ããŠç¢ºèªããäŸåé¢ä¿ã確èªããŠåé€ããŸããã
yiisoft/yii2-queue
ããŠãããã§ãååããããã«ãYii2 ãšã®å³å¯ãªé¢ä¿ãæšæž¬ãããŸããã ãã®ã©ã€ãã©ãªã䜿çšããå¿ èŠããããããã¯æªããããŸããã§ããããå®å šã« Yii2 ã«äŸåããŠãããšããäºå®ã«ã€ããŠã¯èããŠããŸããã§ããã
æ®ã
GitHub ã§èŠã€ããä»ã®ãã®ã¯ãã¹ãŠãã¹ã¿ãŒããã©ãŒã¯ãå€æ°ã®ã³ãããã®ãªããä¿¡é Œæ§ãäœããæ代é ãã§ãæŸæ£ããããããžã§ã¯ãã§ããã
symfony/ã¡ãã»ã³ãžã£ãŒãæè¡çãªè©³çŽ°ã«æ»ã
ãã®ã©ã€ãã©ãªãç解ããå¿ èŠããããããã«æéãè²»ãããåŸãç解ããããšãã§ããŸããã ãã¹ãŠãéåžžã«ç°¡æœã§ã·ã³ãã«ã§ããããšãããããŸããã ãã¹ãã€ã³ã¹ã¿ã³ã¹åããããã«ãç§ã¯å°ããªå·¥å ŽãäœããŸããã è€æ°ã®ã¿ã€ã€ãšç°ãªããã³ãã©ãŒã䜿çšããããšã«ãªã£ãŠããŸããã
ã»ãã®æ°ã¹ããã:
- åçŽã«åŒã³åºãããšãã§ããã¡ãã»ãŒãž ãã³ãã©ãŒãäœæããŸãã
- ãããã HandlerDescriptor (ã©ã€ãã©ãªã®ã¯ã©ã¹) ã§ã©ããããŸãã
- ãããã®ãèšè¿°åãã HandlersLocator ã€ã³ã¹ã¿ã³ã¹ã§ã©ããããŸãã
- HandlersLocator ã MessageBus ã€ã³ã¹ã¿ã³ã¹ã«è¿œå ãã
- `SenderInterface` ã®ã»ããã SendersLocator ã«æž¡ããŸããç§ã®å Žåã¯ãæãããªæ¹æ³ã§æ§æããã `RedisTransport` ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã§ãã
- SendersLocator ã MessageBus ã€ã³ã¹ã¿ã³ã¹ã«è¿œå ãã
MessageBus ã«ã¯ãHandlersLocator ã§é©åãªãã³ãã©ãŒãæ€çŽ¢ãã察å¿ãã `SenderInterface` ã䜿çšããŠãã¹ (Redis ã¹ããªãŒã ) çµç±ã§éä¿¡ããã¡ãã»ãŒãžããã³ãã©ãŒã«æž¡ã `->dispatch()` ã¡ãœããããããŸãã
ã³ã³ãããŒæ§æ (ãã®å Žå㯠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 㧠XNUMX ã€ã®ç°ãªãã¡ãã»ãŒãžã«ç°ãªãããã©ã³ã¹ããŒãããå²ãåœãŠãããããã察å¿ããã¹ããªãŒã ãžã®ç¬èªã®æ¥ç¶ãæã£ãŠããããšãããããŸãã
次ã®ãã¹ã䜿çšããŠçžäºã«éä¿¡ãã XNUMX ã€ã®ããŒã¢ã³ã®ã¢ããªã±ãŒã·ã§ã³ããã¢ã³ã¹ãã¬ãŒã·ã§ã³ããå¥ã®ã㢠ãããžã§ã¯ããäœæããŸããã
ãã ããæ¶è²»è ãã©ã®ããã«æ§æã§ãããã瀺ããŸãã
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();
ã¢ããªã±ãŒã·ã§ã³ã§ãã®ã€ã³ãã©ã¹ãã©ã¯ãã£ã䜿çšãã
ããã¯ãšã³ãã«ãã¹ãå®è£ ããåŸãå€ãåæã³ãã³ãããåã ã®ã¹ããŒãžãåé¢ãããããããç¬èªã®åŠçãå®è¡ããåå¥ã®ãã³ãã©ãŒãäœæããŸããã
æ°ãããµã€ããããŒã¿ããŒã¹ã«è¿œå ãããã€ãã©ã€ã³ã¯æ¬¡ã®ããã«ãªããŸãã
ãããŠãã®çŽåŸãããRss ã®æœåºã解æãªã©ã®æ°ããæ©èœãè¿œå ããããšãã¯ããã«ç°¡åã«ãªããŸããã ãªããªããã®ããã»ã¹ã«ã¯å
ã®ã³ã³ãã³ããå¿
èŠã§ãããã®åŸãWebsiteIndexHistoryPersistor ãªã©ã® RSS ãªã³ã¯æœåºãã³ãã©ãŒããContent/HtmlContentãã¡ãã»ãŒãžããµãã¹ã¯ã©ã€ããããããåŠçããŠãå¿
èŠãªã¡ãã»ãŒãžããã€ãã©ã€ã³ã«æ²¿ã£ãŠæž¡ããŸãã
æçµçã«ã¯ããããããå¿
èŠãªãªãœãŒã¹ãžã®æ¥ç¶ã®ã¿ãç¶æããè€æ°ã®ããŒã¢ã³ãäœæããããšã«ãªããŸããã ããšãã°æªé ã¯ããŒã© ã³ã³ãã³ããååŸããããã«ã€ã³ã¿ãŒãããã«ã¢ã¯ã»ã¹ããå¿
èŠããããã¹ãŠã®ãã³ãã©ãŒãšããŒã¢ã³ãå«ãŸããŠããŸãã æç¶æ§ ããŒã¿ããŒã¹ãžã®æ¥ç¶ãä¿æããŸãã
çŸåšã¯ãããŒã¿ããŒã¹ããéžæãã代ããã«ãããŒã·ã¹ã¿ãŒã«ããæ¿å
¥åŸã®å¿
èŠãª ID ãããã¹ãä»ããŠé¢ä¿ãããã¹ãŠã®ãã³ãã©ãŒã«éä¿¡ãããã ãã§ãã
åºæïŒ habr.com