ืคึฐึผืชึดืืึท
ืืืชืจ ืฉืื, ืืืชื ืื ื ืื ืื ืืชืืืื, ืืืืขื ืืืจื ืืคื ืืืช ืืืชืจืื ืืืฉืืื ืืขื ืืื ืื. ืื ืืฉื ืืื ืืชืืื ืืขื ืืื ืืืชื ืืืฉ ืืชืืืืช ืืกืข ืืชืื ืืช ืฉืื; ืืืืชื ืจืืข ืืืงืกืืชื ืืืืฆืื ืื ืฉื ืืงืฆืืข ืืขืืืื ืฉืืืชืืื ืขื ืขืฆืื, ืขื ืืชืืืืืื ืืืคืจืืืงืืื ืฉืืื. ืืืจืื ืืืืืช ืืืชื ืืขืฆืื ื ืฉืืจ ืขื ืืืื: ืืืขื ืืื ืืชืจ ืืกืืจื ืืื ืืืื ืืกืืจื, ืื ื ืืืฉืื ืืืคืฉ ืืืืชืจืช ืืชืืชืื ื ืืืืคืืฉ ืืืจ ืงืืฉืืจืื ืืืืชืืื.
ืืืฉืื ืืจืขืืื
ืืืจืกื ืืจืืฉืื ื ืืืืชื ืจืง ืืฃ HTML ืืืชืจ ืืืืฉื ืฉืื, ืฉืื ืืื ืกืชื ืงืืฉืืจืื ืขื ืืชืืืืช ืืจืฉืืืช ul. ืืืืจ ืฉืืงืืืชื 20 ืขืืืืื ืขื ืคื ื ืชืงืืคื, ืืชืืืชื ืืืฉืื ืฉืื ืื ืืขืื ืืืืืื ืืืืืืชื ืื ืกืืช ืืืคืื ืืช ืืชืืืื ืืืืืืืื. ื-stackoverflow, ืฉืืชื ืื ืฉืื ืฉืื ืจืืื ืืฆืืื ืื ืืชืจืื ืืคืจืืคืืืื ืฉืืื, ืื ืืชืืชื ืื ืชื ื-php, ืฉืคืฉืื ืขืืจ ืขื ืืคืจืืคืืืื, ืืื ืืืจืืฉืื (ืืืชืืืืช ื-SO ืขื ืืืื ืื ืื: `/users/1` ), ืืืืฅ ืงืืฉืืจืื ืืืชื ืืจืฆืื ืืืืกืืฃ ืืืชื ื-SQLite.
ืืคืฉืจ ืืงืจืื ืืื ืืืจืกื ืืฉื ืืื: ืืืกืฃ ืฉื ืขืฉืจืืช ืืืคื ืืชืืืืช URL ืืืืืช SQLite, ืฉืืืืืคื ืืช ืืจืฉืืื ืืกืืืืช ื-html. ืขืฉืืชื ืืืคืืฉ ืคืฉืื ืืจืฉืืื ืืื. ืื ืืื ืจืง ืืชืืืืช URL, ืืื ืืืืคืืฉ ืคืฉืื ืืชืืกืก ืขืืืื.
ืืฉืื ืื ื ืืฉืชื ืืช ืืคืจืืืงื ืืืืจืชื ืืืื ืืืืจ ืืื ืจื. ืืฉืื ืืื ืื ืืกืืื ืืขืืืื ืฉืื ืืื ืืืจ ืืืชืจ ืืฉืืืฉ ืฉื ืื ืืืจืืฉืชื ืฉืื ื ืืืื ืืขืฉืืช ืืฉืื ืืืชืจ ืจืฆืื ื. ืื ืืกืฃ, ืืื ืจืฆืื ืืืื ืืฉืืื ืืืื ืืืืืืืช ืืืฉืืช ืืืกืืช.
ืืจืกื ืืืืจื ืืช
ืืขืื
ืืชืจืื ืืืฉืื ืืชืืืกืคืื ืขื ืืื ืคืงืืืช ืืกืืฃ ืฉืขืืฉื ืืืืคื ืกืื ืืจืื ื ืืช ืืคืขืืืืช ืืืืืช:
- ืืืจืื ืชืืื ืืคื ืืชืืืช URL
- ืืืืืจ ืืื ืืืฆืืื ืื HTTPS ืืื ืืืื
- ืฉืืืจ ืขื ืืืืช ืืืชืจ
- HTML ืืืงืืจ ืืืืืชืจืืช ื ืฉืืจืืช ืืืืกืืืจืืืช ื"ืืื ืืงืก".
- ืื ืชื ืชืืื, ืืืืฅ ืืืชืจืช ืืชืืืืจ
- ืฉืืืจ ื ืชืื ืื ืืืืกืฃ ื ืคืจื
ืื ืืกืคืืง ืืื ืคืฉืื ืืืืกื ืืชืจืื ืืืืฆืื ืืืชื ืืจืฉืืื:
ืืื ืืจืขืืื ืฉื ืืื ืืงืก, ืกืืืื ืืืืจืื ืืืืืืื ืฉื ืืื, ืฉืืืจื ืขื ืืื ืืขืืืื, ืื ืืฉืชืื ืืืื ืืคืจืืืืื ืืื. ืืคืืื ืืืกืคืช ืฉืืืช ืืื ืืจื ื ืืืืกืคืช ืืคืื ืืจืฉื ืฉืืคืื ืืืกืืื ืฉื ืงืื ืืื ืืื ืืข DDoS ืคืืื ืฆืืืื.
ืืืืคื ืืืื, ืืืืื, ืืื ืืืื ืืืืขืฉืืช ืืืืคื ืกืื ืืจืื ื, ืืืฉืืืช ืืืื ืืจื ื ืืคืฉืจ ืคืฉืื ืืฉืืืจ ืืช ื-URL ืื ืฉืืืืื ืืืคืืฆืชื ืืืฆืข ืืช ืื ืืืฉืืืืช ืขืืืจ ื-URL ืืืจืฉืืื. ืืื ืขืืืื, ืื ืืื ืืืืื "ืชืืจ" ืืฆืืขื ืืช ืขืฆืื. ืืื ืืืืฉื ืชืืจ, ืื ื ืืชื ืืืืง ืืืืฆืข ืืช ืื ืืืฉืืืืช ืืคืืืช ืืืืคื ืืกืื ืืจืื ื.
ืืืืื
ืืืืขืช ืชืืจืื ืืืฆืืจืช ืืขืจืืช ืืื ืขืช ืืืจืืขืื ืืขืืืื ืื ืืืฉืืืืช. ืืื ื ืืืจ ืืจืื ืืื ืจืืฆื ืื ืกืืช ืืช Redis Streams.
ืฉืืืืฉ ืืืจืื Redis ื-PHP
ืื ืืืืืื ืฉืืืกืืจืช ืฉืื ืืื ืื ืืืช ืืฉืืืฉืช ืืขื ืงืื Symfony, Laravel, Yii, ืืืืชื ืจืืฆื ืืืฆืื ืกืคืจืืื ืขืฆืืืืช. ืืื, ืืคื ืฉืืชืืจืจ (ืืืืืงื ืจืืฉืื ื), ืื ืืคืฉืจ ืืืฆืื ืกืคืจืืืช ืจืฆืื ืืืช ืืืืืืช. ืื ืื ืฉืงืฉืืจ ืืชืืจืื ืืื ืื ืคืจืืืงื ื-3 ืืชืืืืืื ืืคื ื ืืืฉ ืฉื ืื, ืื ืงืฉืืจ ืืืกืืจืช.
ืฉืืขืชื ืืจืื ืขื Symfony ืืกืคืงืืช ืฉื ืจืืืืื ืฉืืืืฉืืื ืืืืืื, ืืืืจ ืื ื ืืฉืชืืฉ ืืืืงื. ืืื ืืื ืืืจืื ื-Laravel ืืืืืื ืืฉืืฉ, ืืืฉื ื-ORM ืฉืืื, ืืื ื ืืืืืช ืืืกืืจืช ืขืฆืื.
ืกืืืคืื ืื/ืืกื ื'ืจ
ืืืืขืื ืืจืืฉืื ื ืจืื ืืื ืืืืืืื ืืืื ืื ืกืคืง ืืชืงื ืชื ืืืชื. ืืื ืืชืืจืจ ืฉืงืฉื ืืืชืจ ืืืคืฉ ืืืืื ืืืืืืืช ืืฉืืืืฉ ืืืืฅ ืืกืืืคืื ื. ืืื ืืืจืืื ืืืืืจื ืฉื ืืืชืืช ืขื ืฉืืืช ืืื ืืืจืกืืืื ืืืกืจื ืืฉืืขืืช, ืืืืืืืก ืืืขืืจืช ืืืืขืืช ืืืคืืื ืขื Redis?
ืืชืืขืื ืืืชืจ ืืจืฉืื ืืื ืืคืืจื ืืืื, ืืื ืืืชืืื ืชืืืจ ืจืง ืขืืืจ ืกืืืคืื ืื ืืืืฆืขืืช YML ืืืืืืื ืขืืืื ืืฉืืืืช ืงืกื ืืืจืืช ืขืืืจ ืืื-ืกืืืคืื ืืกื. ืื ืืื ืื ืขื ืืื ืืชืืืื ืืืชืงื ื ืขืฆืื, ืืืืืื ืืืืคืฉืืช ืจืืฉ ืืฉื ื. ืืื ืืืืชื ืฆืจืื ืืขืฉืืช ืืช ืื ืืืฉื ืืื ืจื ืืืืคื ืืืชื ืฆืคืื.
ืื ืืกืืื ืืืืื ืืืฆื ืืืคืขืื ืืขืจืืช ืืืืฆืขืืช ืืงืืจืืช ืกืืืคืื ืื ืืื ืื ืื ืืืฉืืื ืืืจืืืืืืืืช ืืืืชืจ ืขืืืจ ืืืืืื ืงืฆืจ:
ืืืจื ืฉืืชืขืืงืชื ืืื ืื ืื ืืกืืชื ืืขืฉืืช ืืฉืื ืขื ืืืืืื, ืืืขืชื ืืืกืงื ื ืฉืื ื ืขืืฉื ืกืื ืฉื ืงืืืื ืืืืืืชื ืื ืกืืช ืืฉืื ืืืจ.
ืืืืจ/ืชืืจ
ืืชืืจืจ ืฉืืกืคืจืืื ืืื ืืืืชื ืงืฉืืจื ืืืืคื ืืืืง ืืชืฉืชืืช Laravel ืืืขืื ืืืื ืชืืืช, ืื ืื ืืฉืงืขืชื ืื ืืจืื ืืื: ืืชืงื ืชื ืืืชื, ืืกืชืืืชื ืขืืื, ืจืืืชื ืืช ืืชืืืช ืืืืงืชื ืืืชื.
yiisoft/yii2-queue
ืืืื, ืืื ืืื ื ืืื ืืืฉื, ืฉืื, ืงืฉืจ ืงืคืื ื ื-Yii2. ืืืืชื ืฆืจืื ืืืฉืชืืฉ ืืกืคืจืืื ืืื ืืื ืื ืืื ืจืข, ืืื ืื ืืฉืืชื ืขื ืื ืฉืื ืืืืจื ืชืืื ื-Yii2.
ืืฉืืจ
ืื ืืฉืืจ ืฉืืฆืืชื ื-GitHub ืืื ืคืจืืืงืืื ืื ืืืื ืื, ืืืืฉื ืื ืื ืืืฉืื ืืื ืืืืืื, ืืืืืืช ืืืกืคืจ ืจื ืฉื ืืืืืืืช.
ืืืจื ืืกืืืคืื ืื/ืืกื ื'ืจ, ืคืจืืื ืืื ืืื
ืืืืชื ืฆืจืื ืืืืื ืืช ืืกืคืจืืื ืืื, ืืืืจื ืฉืืืืืชื ืขืื ืืื, ืืฆืืืชื. ืืชืืจืจ ืฉืืื ืืื ืื ืชืืฆืืชื ืืคืฉืื. ืืื ืืืฆืืจ ืืช ืืืืืืืืก, ืืฆืจืชื ืืคืขื ืงืื, ืื... ืืื ืืืืจืื ืืืืืช ืื ืืื ืฆืืืืื ืืขื ืืืคืืื ืฉืื ืื.
ืจืง ืืื ืฆืขืืื:
- ืื ื ืืืฆืจืื ืืืคืื ืืืืขืืช ืฉืคืฉืื ืฆืจืืืื ืืืืืช ื ืืชื ืื ืืืชืงืฉืจืืช
- ืื ื ืขืืืคืื ืืืชื ื- HandlerDescriptor (ืืืชื ืืืกืคืจืืื)
- ืื ื ืขืืืคืื ืืช ื"ืชืืืืจืื" ืืืื ืืืืคืข HandlersLocator
- ืืืกืคืช HandlersLocator ืืืืคืข MessageBus
- ืื ื ืืขืืืจืื ืงืืืฆื ืฉื 'SenderInterface' ื-SendersLocator, ืืืงืจื ืฉืื ืืงืจืื ืฉื ืืืืงืืช 'RedisTransport', ืืืืืืจืืช ืืฆืืจื ืืจืืจื
- ืืืกืคืช SendersLocator ืืืืคืข MessageBus
ื-MessageBus ืืฉ ืฉืืื ืฉื โโ`->dispatch()` ืฉืืืคืฉืช ืืช ืืืืคืืื ืืืชืืืืื ื- HandlersLocator ืืืขืืืจื ืืื ืืช ืืืืืขื, ืชืื ืฉืืืืฉ ื-`SenderInterface` ืืืงืืื ืืฉืืืื ืืจื ืืืืืืืืก (Redis streams).
ืืชืฆืืจืช ืืืืืื (ืืืงืจื ืื 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 ืืงืฆืื ื "ืืจื ืกืคืืจืืื" ืฉืื ืื ืืฉืชื ืืืืขืืช ืฉืื ืืช, ืฉืืื ืืืช ืืื ืืฉ ืืืืืจ ืืฉืื ืืืจืืื ืืืชืืืืื.
ืขืฉืืชื ืคืจืืืงื ืืืืื ื ืคืจื ืืืืืื ืืืฉืื ืฉื ืฉืืืฉื ืืืื ืื ืืืชืงืฉืจืื ืื ืขื ืื ืืืืฆืขืืช ืืืืืืืืก ืืื:
ืืื ืื ื ืืจืื ืื ืืื ืืคืฉืจ ืืื ืืช ืฆืจืื:
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();
ืฉืืืืฉ ืืชืฉืชืืช ืื ืืืคืืืงืฆืื
ืืืืจ ืฉืืืืขืชื ืืช ืืืืืืืืก ื-backend ืฉืื, ืืคืจืืชื ืฉืืืื ืืืืืื ืืืคืงืืื ืืกืื ืืจืื ืืช ืืืฉื ื ืืืื ืชื ืืืคืืื ื ืคืจืืื, ืฉืื ืืื ืืื ืขืืฉื ืืช ืฉืื.
ืืฆืื ืืจ ืืืืกืคืช ืืชืจ ืืืฉ ืืืกื ืื ืชืื ืื ื ืจืื ืื:
ืืืื ืืืืจ ืืื, ืืื ืื ืืจืื ืืืชืจ ืงื ืืืืกืืฃ ืคืื ืงืฆืืื ืืืืช ืืืฉื, ืืืฉื, ืืืืืฅ ืื ืืชืื Rss. ืื ืชืืืื ืื ืืืจืฉ ืื ืืช ืืชืืื ืืืงืืจื, ืืื ืืืืคื ืืืืืืฅ ืงืืฉืืจื RSS, ืืื WebsiteIndexHistoryPersistor, ื ืจืฉื ืืืืืขืช "Content/HtmlContent", ืืขืื ืืืชื ืืืขืืืจ ืืช ืืืืืขื ืืจืฆืืื ืืืืจื ืืฆืื ืืจ ืฉืื.
ืืกืืคื ืฉื ืืืจ, ืืืขื ื ืืืื ืืืื ืื, ืฉืื ืืื ืืื ืฉืืืจ ืขื ืงืฉืจืื ืจืง ืืืฉืืืื ืืืจืืฉืื. ืืืฉื ืฉื ืกืืจืงืื ืืืื ืืช ืื ืืืืคืืื ืฉืืืจืฉืื ืื ืืกื ืืืื ืืจื ื ืืชืืื, ืืืช ืืืืื ืืืชืืื ืืืืืง ืืืืืืจ ืืืกื ืื ืชืื ืื.
ืืขืช, ืืืงืื ืืืืืจ ืืชืื ืืกื ืื ืชืื ืื, ืืืืืื ืื ืืจืฉืื ืืืืจ ืืืกืคื ืขื ืืื ืืืชืืื ืืืขืืจืื ืคืฉืื ืืจื ืืืืืืืืก ืืื ืืืืคืืื ืืืขืื ืืื ืื ืืื.
ืืงืืจ: www.habr.com