Перехід до асинхронності
Перехід до асинхронності
Перевірканаспам,підчасобробкивідправленоїформи,можепризвестидопевнихпроблем。AkismetЯкщоAPIпрацюватимеповільно,нашвеб——сайттакожуповільнитьсядлякористувачів。Але,щощегірше,якщоминатрапимонатайма,ут,абоAPI Akismetбуденедоступний,миможемовтратитикоментарі。
Відеалі,мимаємозберігативідправленіданінепублікуючиїх,відразуповертаючивідповідь。Перевірканаспамможебутивиконанавіншомупотоці。
Позначеннякоментарів
Нам потрібно вв в с с ст т (状态
) дл коментарів:提交
(надіслано),垃圾邮件
(спам),та发表
(опубліковано)。
Додайтевластивість状态
уклас评论
:
1
$欧宝娱乐app下载地址symfony控制台make:实体注释
Митакожмаємопереконатися,щозазамовчуваннямдлявластивості状态
встановленозначення提交
:
12 3 4 5 6 7 8 9 10 11 12 13
——/ src /实体/ Comment.php+ + + b / src /实体/ Comment.php@@ -39,8 +39,8 @@ class注释#[ORM\列(长度:255,nullable: true)] private ?string $photoFilename = null;#[ORM\列(长度:255)]$state = null;+ #[ORM\列(长度:255,选项:['default' => 'submitted'])]$state = '已提交';公共函数__toString():字符串{
Створіть міграцію баз з дани и:
1
$欧宝娱乐app下载地址Symfony控制台make:迁移
Модифікуйтеміграцію,щобоновитивсінаявнікоментарі、дляякихбудевстановленостан发表
зазамовчуванням:
1 2 3 4 5 6 7 8 9 10
——/迁移/ Version00000000000000.php+ + + b /迁移/ Version00000000000000.php@@ -21,6 +21,7 @@ final class Version00000000000000 extends AbstractMigration {// this up()迁移是自动生成的,请根据您的需要修改$this->addSql('ALTER TABLE comment ADD state VARCHAR(255) DEFAULT \'submitted\' NOT NULL');+ $this->addSql("UPDATE comment SET state='published'");}公共函数关闭(Schema $ Schema):无效
Виконайте міграцію баз з дани и:
1
$欧宝娱乐app下载地址Symfony控制台原则:迁移:迁移
Оновітьлогікувідображення,щобуникнутипоявинеопублікованихкоментарівнавеб——сайті:
12 3 4 5 6 7 8 9 10 11 12
——/ src /仓库/ CommentRepository.php+ + + b / src /仓库/ CommentRepository.php@@ -29,7 +29,9 @@ class CommentRepository extends ServiceEntityRepository {$query = $this->createQueryBuilder('c') ->andWhere('c. 1 ')Conference =: Conference ')+ - >引入(c。State =: State ')- > setParameter(“会议”,会议美元)+ ->setParameter('state', 'published')- > orderBy (c。->setMaxResults(self::PAGINATOR_PER_PAGE) ->setFirstResult($offset)
ОновітьконфігураціюEasyAdmin,щобматиможливістьбачитистанкоментарів:
1 2 3 4 5 6 7 8 9 10
——/ src /控制器/ Admin / CommentCrudController.php+ + + b / src /控制器/ Admin / CommentCrudController.php@@类CommentCrudController extends AbstractCrudController ->setLabel('照片')->onlyOnIndex();+ yield TextField::new('state');$createdAt = DateTimeField::new('createdAt')->setFormTypeOptions(['html5' => true,
Незабудьтетакожоновититести,встановившипараметр状态
уфікстурах:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
——/ src / DataFixtures / AppFixtures.php+ + + b / src / DataFixtures / AppFixtures.php@@ -37,8 +37,16 @@类AppFixtures扩展Fixture $comment1->setAuthor('Fabien');comment1 - > setEmail (fabien@example.com);$comment1->setText('This was a great conference.');+ $ comment1 - >设置状态(“发表”);经理- >保存($ comment1);+ $comment2 = new Comment();+ $ comment2 - > setConference阿姆斯特丹($);+ $ comment2 - > setAuthor(卢卡斯);+ $ comment2 - > setEmail (lucas@example.com);+ $comment2->setText('我认为这个将被缓和。');+ $经理- >保存($ comment2);+$admin = new admin ();管理- > setRoles ([' ROLE_ADMIN ']);管理- > setUsername(管理);
Для тестів контролера змодел т т т перевірку:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
——/ /控制器/ ConferenceControllerTest.php测试+ + + b /测试/控制器/ ConferenceControllerTest.php@@ -2,6 +2,8 @@名称空间应用\ \测试控制器;+使用App \ Repository \ CommentRepository;+使用原则\ ORM \ EntityManagerInterface;使用Sy欧宝娱乐app下载地址mfony \包\ FrameworkBundle \ \ WebTestCase测试;class ConferenceControllerTest extends WebTestCase $client->submitForm('Submit', ['comment_form[author]' => 'Fabien', 'comment_form[text]' => '自动功能测试的一些反馈',- 'comment_form[email]' => 'me@automat.ed',+ 'comment_form[email]' => $email = 'me@automat.ed','comment_form[photo]' => dirname(__DIR__, 2).'/public/images/under-construction.gif',]);$ this - > assertResponseRedirects ();++ //模拟注释验证+ $comment = self::getContainer()->get(CommentRepository::class)->findOneByEmail($email);+ $评论- >设置状态(“发表”);+ self:: getContainer () - > (EntityManagerInterface::类)——>冲洗();+客户端- > followRedirect ();$this->assertSelectorExists('div:contains("有2个注释")');}
ЗтестуPHPUnit)виможетеотриматибудь——якийсервісізконтейнеразадопомогою自我::$容器- > get ()
;він також надає доступ до непублічних сервісів。
Опанування信使
КеруванняасинхроннимкодомуSymf欧宝娱乐app下载地址ony——цезавданнякомпонента使者:
1
$欧宝娱乐app下载地址交响乐作曲家要求教义使者
Колипевналогікамаєвиконуватисяасинхронно,відправтеповідомленняушинуповідомлень.Шина зберігає повідомлення Шина зберігає повідомленнячерзітанегайноповертаєвідповідь,щобпотікопераційвідновивсяякомогашвидше。
Споживачпрацюєбезперервно,уфоновомурежимі、читаючиновіповідомленнявчерзітавиконуючивідповіднулогіку。Споживачможепрацюватинатомужсервері、щойвеб——застосунок,абонаокремомусервері。
Цедужесхоженате,якобробляютьсяHTTP -запити,завиняткомтого,щоунаснемаєвідповідей。
Створення об обника повідомлень
Повідомлення——цекласоб的єктуданих,якийнеповиненміститижодноїлогіки。Вінбудесеріалізованийдлязбереженняучерзі,томузберігайтелишеп”рості”дані、щоможутьбутисеріалізованими。
СтворітькласCommentMessage
:
Усвіті信使,унаснеконтролери,аобробникиповідомлень。
СтворітькласCommentMessageHandler
у о о о о о о о о о імен应用MessageHandler \
, ки и з знатиме як об обл т т повідомленняCommentMessage
:
AsMessageHandler
допомагаєS欧宝娱乐app下载地址ymfonyавтоматичнозареєструватитаналаштуватикласуякостіобробника信使。Задомовленістю,логікаобробниказнаходитьсяуметодізназвою__invoke ()
.ПідказкатипуCommentMessage
,вєдиномуаргументіцьогометоду,повідомляє信使проте,якийсамекласвінбудеобробляти。
Оновітьконтролер,щобвикористовуватиновусистему:
12 34 56 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
——/ src /控制器/ ConferenceController.php+ + + b / src /控制器/ ConferenceController.php@@ -5,21 +5,23 @@命名空间应用\控制器;使用App \实体\评论;使用App \实体\会议;使用App \ \ CommentFormType形式;+使用App \ \ CommentMessage消息;使用App \ Repository \ CommentRepository;使用App \ Repository \ ConferenceRepository;用程序\ SpamChecker;使用原则\ ORM \ EntityManagerInterface;控制器使欧宝娱乐app下载地址用Symfony \包\ FrameworkBundle \ \ AbstractController;使用Sy欧宝娱乐app下载地址mfony \ DependencyInjection \属性\ \组件自动装配;组件使用欧宝娱乐app下载地址Symfony \ \ HttpFoundation \文件\ \ FileException异常;使用Sy欧宝娱乐app下载地址mfony \ HttpFoundation \ \组件请求;组件使用欧宝娱乐app下载地址Symfony \ \ HttpFoundation \反应;+使用Sy欧宝娱乐app下载地址mfony \组件\ \ MessageBusInterface使者;使用Sy欧宝娱乐app下载地址mfony \组件\路由\注释\路线;类ConferenceController扩展AbstractController{公共函数__construct(private EntityManagerInterface $entityManager,+ private MessageBusInterface{} @@ -36,7 +38,6 @@类ConferenceController扩展AbstractController请求$请求,会议$会议,CommentRepository $ CommentRepository- SpamChecker $ SpamChecker,#[autoire ('%photo_dir%')] string $photoDir,): Response {$comment = new comment ();@@ -55,6 +56,7 @@ class ConferenceController extends AbstractController} $this->entityManager->persist($comment);+ $ this - > entityManager - >冲洗();$context = ['user_ip' => $request->getClientIp(), @@ -62,11 +64,7 @@ class ConferenceController extends AbstractController 'referrer' => $request->headers->get('referer'), 'permalink' => $request->getUri(),];- if (2 === $spamChecker->getSpamScore($comment, $context)) {- throw new \RuntimeException('公然的垃圾邮件,走开!');- - - - - -}-- $ this - > entityManager - >冲洗();+ $this->bus->dispatch(new CommentMessage($comment->getId(), $context));return $this->redirectToRoute('conference', ['slug' => $conference->getSlug()]);}
Замістьтогощобзалежативідзасобуперевіркинаспам,тепермивідправляємоповідомленнядошини。Потім обробник вирішує, що з ним робит。
Ми дос л ос несподіваного。Мивідокремилинашконтролервідзасобуперевіркинаспаміперенеслилогікувновийкласобробник。Цеідеальнийсценарійвикористанняшиниповідомлень。Перевірте код, він працює。Всеякіранішевиконуєтьсясинхронно,алекод,напевно,вжестав“краще”。
Перехід до и еал но и асинхронності
Зазамовчуваннямобробникивикликаютьсясинхронно。Щобперейтидоасинхронності、необхідноявноналаштувати,якучергувикористовуватидлякожногообробникауфайліконфігурації配置/包/ messenger.yaml
:
1 2 3 4 5 6 7 8
——/ config /包/ messenger.yaml+ + + b / config /包/ messenger.yaml@@ -21,4 +21,4 @@框架:Symfony\C欧宝娱乐app下载地址omponent\Notifier\Message\SmsMessage: async#路由你的消息到传输# App\Message\YourMessage: async+ App\Message\CommentMessage: async
Конфігураціяповідомляєшиніпроте,щоекземпляри应用\ \ CommentMessage消息
слід відправляти в炼钢厂异步
, ка а и из зна а опомо о о о о о в DSN (MESSENGER_TRANSPORT_DSN
), що вказує а а主义,як а а а а а а то а а а а.env
.Якщоговоритипростоюмовою,мивикористовуємоPostgreSQLуякостічергидлянашихповідомлень。
提示
ЗалаштункамиSy欧宝娱乐app下载地址mfonyвикористовуєвбудованувPostgreSQLпродуктивн,умасштабовануітранзакційнусистемуpub / sub (听
/通知
).ВитакожможетепрочитатирозділпроRabbitMQ,якщохочетевикористовуватийогозамістьPostgreSQLуякостіброкераповідомлень。
Опрацюванняповідомлень
Якщовиспробуєтевідправитиновийкоментар,засібперевіркинаспамбільшеневикликатиметься。Додайтевикликerror_log ()
уметодgetSpamScore ()
, щоб перек конатис у л ом。Натомістьповідомленняочікуватимевчерзі,вготовностідоопрацюванняпевнимипроцесами。
Яквиможетеуявити,Symf欧宝娱乐app下载地址onyпоставляєтьсяізкомандоюспоживача。Виконайтеїї:
1
$欧宝娱乐app下载地址Symfony控制台messenger:consume async -vv
Цемаєнегайноопрацюватиповідомлення,відправленедлянадісланогокоментаря:
1 2 3 4 5 6 7 8 9 10 11
[OK]从传输“异步”中消费消息。//一旦通过messenger:stop-workers命令接收到停止信号,worker将自动退出。//使用CONTROL-C退出worker11:30:20 INFO [messenger]已接收消息App\ message \CommentMessage ["message" => App\ message \CommentMessage^{…},"class" => "App\ message \CommentMessage"] 11:30:20 INFO [http_client]请求:"POST https://80cea32be1f6.rest.akismet.com/1.1/comment-check" 11:30:20 INFO [http_client]响应:"200 https://80cea32be1f6.rest.akismet.com/1.1/comment-check" 11:30:20 INFO [messenger] Message App\Message\CommentMessage handling by App\MessageHandler\CommentMessageHandler::__invoke [" Message" => App\Message\CommentMessage^{…},"class" => "App\Message\CommentMessage","handler" => "App\MessageHandler\CommentMessageHandler::__invoke"] 11:30:20 INFO [messenger] App\Message\CommentMessage was handled successfully (acknowledgement to transport)。["message" => App\ message \CommentMessage^{…},"class" => "App\ message \CommentMessage"]
Активністьспоживачаповідомленьзаписуєтьсявжурнал,алевиотримаєтемиттєвіповідомленнявконсолі、передавшипрапорецьvv
.Ви навіть зможете помітити виклик API Akismet。
Щоб з з пинит т споживача, натиснітьCtrl + C
.
Запуск воркерів у фо оно ому режимі
Замістьтогощобзапускатиспоживачакожногоразу、колимипублікуємокоментар,іодразужзупинятийого,михочемощобвінпрацювавбезперервно,немаючизанадтобагатовідкритихвіконабовкладоктермінала。
欧宝娱乐app下载地址Symfony CLIможекеруватитакимифоновимикомандамиабоворкерами,використовуючипрапорецьдемона(- d
),команди运行
.
Запустітьспоживачаповідомленьщераз,алевідправтейогоуфоновийрежим:
1
$欧宝娱乐app下载地址Symfony run -d——watch=config,src,templates,vendor Symfony控制台messenger:consume async -vv
Параметр——看
вказуєS欧宝娱乐app下载地址ymfony,щокомандамаєбутиперезапущенащоразу、коливідбуваєтьсязмінафайловоїсистемивкаталогах配置/
,src /
,模板/
чи供应商/
.
请注意
Невикористовуйтеvv
том м му у, що ви м м м т а атим ме повідомлення у服务器:日志
(повідомленняужурналійконсольніповідомлення)。
Якщоспоживачзякоїсьпричиниперестаєпрацювати(обмеженняпам”яті、помилка,…),вінбудеперезапущенийавтоматично。Алеякщоспоживачперестаєпрацюватизанадтошвидко,Symfony欧宝娱乐app下载地址 CLIнезможейогозапустити。
Журнали можна пере е л нут т за допомо о в欧宝娱乐app下载地址symfony服务器:日志
,разомзусімаіншимижурналами,щонадходятьізPHP,веб——сервератазастосунку:
1
$欧宝娱乐app下载地址symfony服务器:日志
Використовуйтекоманду服务器:状态
,щобвивестисписоквсіхворкерів,щопрацюютьуфоновомурежимі、керованихдляпоточногопроекту:
1 2 3 4
$欧宝娱乐app下载地址命令symfony控制台messenger:使用PID 15774 (watching config/, src/, templates/)来运行async。
Щобзупинитиворкер,зупинітьвеб——серверабозавершітьпроцесзаPID,щонаданийкомандою服务器:状态
:
1
$杀了15774
Повторна відправка повідомлень у а аз с помилки
,ЩоробитиякщAkismetонепрацюєпідчасопрацюванняповідомлення吗?Ценевпливаєнакористувачів,яківідправляютькоментарі、алеповідомленнявтрачаєтьсяіперевірканаспамнепроходить。
信使маємеханізмдляповторноївідправкиуразівиникненнявиняткупідчасобробкиповідомлення:
Якщопідчасобробкиповідомленнявиникаєпроблема,споживачповторитьспроб3урази,першніжзупинитися。Алезамістьтогощобвідкинутиповідомлення,вінперманентнозбережейогоучерзі失败的
, ка використовує іншу таб бли и и。
Перевіртеповідомленнязпомилкамийповторітьспробузадопомогоюнаступнихкоманд:
1 2 3
$欧宝娱乐app下载地址Symfony控制台信使:失败:显示$欧宝娱乐app下载地址Symfony控制台messenger:failed:重试
Запуск воркерів у у у Platform.sh
ЩобопрацьовуватиповідомленнязPostgreSQL,нампотрібнопостійновиконуватикоманду信使:消费
.У Platform.sh外公外公外公外公外公外公外公外公外公外公外公воркер:
ЯкіSy欧宝娱乐app下载地址mfony CLI, Platform.shкеруєперезавантаженнямийжурналами。
Щоб от ти м мат т журнали о о к ке а, вико исто о о ист то о у у т т т:
1
$欧宝娱乐app下欧宝体育应用最新版app下载载地址Symfony云:logs——worker=messages all