Idziemy w asynchroniczność
Idziemy w asynchroniczność
Sprawdzenie, czy komentarz聂jest spamem, podczas obsługi wysyłania formularza może prowadzić做pewnych problemow。Akismet Jeśli interfejs API stanie siępowolny, nasza strona rownieżbędzie powolna国防后勤局użytkownikow。公司gorsza jeżeli przekroczymy限制czasu滑Akismet API jest niedostępne、możemy stracićkomentarze。
Idealnie byłoby, gdybyśmy przechowywali przesłane戴恩鹿角的第二叉我publikowania我natychmiast zwracali odpowiedź。Sprawdzenie、马nie czy spamu może zostaćwykonane poza głownym wątkiem。
Oznaczanie komentarzy
Musimy wprowadzićatrybut状态
określający斯坦·komentarzy przyjmujący trzy wartości:提交
国防后勤局komentarzy wysłanych,发表
国防后勤局opublikowanych oraz垃圾邮件
国防后勤局odrzuconych jako spamowe。
Dodaj atrybut状态
做klasy评论
:
1
美元ob娱乐下载symfony控制台:实体发表评论
Powinniśmy także upewnićsię,że domyślna wartośćatrybutu状态
jest ustawiona na提交
:
1 2 3 4 5 6 7 8 9 10 11 12 13
- - - / src /实体/ Comment.php+ + + b / src /实体/ Comment.php@@ -38 38 8 + 8 @@类评论# [ORM \列(类型:字符串,长度:255年,可以为空:true)]私人photoFilename美元;- # [ORM \列(类型:字符串,长度:255)]美元——私人状态;+ # [ORM \列(类型:字符串,长度:255年,选择:(“默认”= >“提交”)))美元+私人状态=“提交”;公共函数__toString():字符串{
Utworz migracjębazy danych:
1
美元ob娱乐下载symfony控制台:迁移
Zmodyfikuj migrację达克,zaktualizowała地位wszystkich istniejących komentarzy na发表
:
1 2 3 4 5 6 7 8 9 10
- - - /迁移/ Version00000000000000.php+ + + b /迁移/ Version00000000000000.php@@ -21、6 + 21日7 @@最终类Version00000000000000延伸AbstractMigration{/ /这个()迁移是自动生成的,请根据自己的需求修改$ this - > addSql (“ALTER TABLE注释添加状态VARCHAR(255)默认\ ' \“NOT NULL”)提交;+ $ this - > addSql(“更新评论设置状态=发表”);}公共函数(模式美元):空白
Uruchom migracjębazy danych:
1
美元ob娱乐下载symfony控制台学说:迁移:迁移
Zaktualizuj reguły wyświetlania,赎uniknąćpojawienia sięnieopublikowanych komentarzy na stronie:
1 2 3 4 5 6 7 8 9 10 11 12
- - - / src /仓库/ CommentRepository.php+ + + b / src /仓库/ CommentRepository.php@@ -27 7 + 27 9 @@类CommentRepository延伸ServiceEntityRepository {$ query = $ this - > createQueryBuilder (“c”) - >引入(c。=会议:会议”)+ - >引入(c。=:状态”)- > setParameter(“会议”,会议美元)+ - > setParameter(“状态”,“发表”)- > orderBy (c。createdAt, DESC) - > setMaxResults (self:: PAGINATOR_PER_PAGE) - > setFirstResult(抵消美元)
Zaktualizuj konfiguracjęEasyAdmin达克,商务部zobaczyć斯坦komentarza:
1 2 3 4 5 6 7 8 9 10
- - - / src /控制器/ Admin / CommentCrudController.php+ + + b / src /控制器/ Admin / CommentCrudController.php@@ -51 51 6 + 7 @@类CommentCrudController延伸AbstractCrudController - > setLabel(照片)- > onlyOnIndex ();+收益率TextField::新(状态);$ createdAt = DateTimeField::新(createdAt) - > setFormTypeOptions ([“html5”= >真的,
聂zapomnij rownieżzaktualizowaćtestow poprzez ustawienie atrybutu状态
w danych testowych (ang。设备):
1 2 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延伸夹具$ comment1 - > setAuthor(“法”);$ comment1 - > setEmail (fabien@example.com);$ comment1 - > setText(“这是一个伟大的会议。”);+ $ comment1 - >设置状态(“发表”);(管理器- >坚持美元comment1);+ $ comment2 =新的评论();+ $ comment2 - > setConference阿姆斯特丹($);+ $ comment2 - > setAuthor(卢卡斯);+ $ comment2 - > setEmail (lucas@example.com);+ $ comment2 - > setText(我认为这是要节制。”);+ $经理- >保存($ comment2);+管理美元= new admin ();$管理- > setRoles ([' ROLE_ADMIN ']);$管理- > setUsername(管理);
W przypadku testow kontrolera należy przeprowadzićsymulacjęwalidacji:
1 2 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;使用Syob娱乐下载mfony \包\ FrameworkBundle \ \ WebTestCase测试;类ConferenceControllerTest延伸WebTestCase @@ -22年10 + 24日16 @@类ConferenceControllerTest延伸WebTestCase $客户- > submitForm(‘提交’,‘comment_form(作者)”= >“法”,“comment_form[文本]= >从自动化功能测试的一些反馈,——“comment_form(电子邮件)”= >“me@automat.ed”,(电子邮件)+ ' comment_form ' = > $邮件=“me@automat.ed”,comment_form[图片]' = >目录名(__DIR__, 2)。' /公共/图片/在建。gif”);$ this - > assertResponseRedirects ();++ / /模拟验证发表评论+ $ =自我评论::getContainer() - >获得(CommentRepository::类)- > findOneByEmail(电子邮件);+ $评论- >设置状态(“发表”);+ self:: getContainer () - > (EntityManagerInterface::类)- >冲洗();+客户端- > followRedirect美元();$ this - > assertSelectorExists (“div:包含(有两个评论)');}
Z poziomu testu PHPUnit) można uzyskaćdowolnąusługęZ kontenera咱pośrednictwem自我::getContainer () - > ()
;daje, rownieżdostęp做usług niepublicznych。
Zrozumienie komponentu信使
Zarządzanie kodem asynchronicznym w ob娱乐下载Symfony jest zadaniem komponentu使者:
1
美元ob娱乐下载symfony作曲家点播doctrine-messenger
Gdy jakieśdziałania powinny byćwykonywane asynchronicznie wyślijwiadomość(ang。消息)magistrali komunikacyjnej(ang。信使号公共汽车)。Magistrala dodaje wiadomość做kolejki(ang。队列)我natychmiast zwraca wynik,赎umożliwićwykonywanie od新法提案kolejnych operacji。
Konsument(ang。消费者)pracuje陈旧w框架,czytając nowe wiadomości w kolejce我wykonuje związane z nimi schematy działań。Konsument może działaćna tym samym serwerze公司aplikacja internetowa滑osobnym。
Jest bardzo podobne做sposobu obsługiżądańHTTP、z wyjątkiem迪高,że聂mamy odpowiedzi。
Kodowanie obsługi wiadomości (ang。消息处理程序)
Wiadomośćjest klasąobiektu danych z ktorą聂sązwiązaneżadne reguły działania。Będzie ona zserializowana赎byćprzechowywana w kolejce więc przechowuj tylko proste戴恩,ktore można serializować。
Stworz klasęCommentMessage
:
Wświecie Messengera聂mamy kontrolerow, lecz obiekty obsługi wiadomości (ang。消息处理程序)。
Utworz klasęCommentMessageHandler
w nowej przestrzeni nazw应用MessageHandler \
ktora体育运动,木菠萝obsługiwaćwiadomościCommentMessage
:
MessageHandlerInterface
jest interfejsemznacznikowym(ang。标记接口)。在Symfony Pob娱乐下载omaga tylko w automatycznej rejestracji我konfiguracji klasy做obsługi wiadomości。Zgodnie z konwencjąreguły obsługi znajdująsięw metodzie__invoke ()
。PodpowiedźtypuCommentMessage
做jednego z argumentow tej metody mowi Messengerowi, ktorąklasębędzie obsługiwać。
Zaktualizuj kontroler,赎korzystaćz nowego systemu:
1 2 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 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 57 58 59 60 61 62 63 64
- - - / src /控制器/ ConferenceController.php+ + + b / src /控制器/ ConferenceController.php@@ 5,14 + 5,15 @@名称空间应用\控制器;使用App \实体\评论;使用App \实体\会议;使用App \ \ CommentFormType形式;+使用App \ \ CommentMessage消息;使用App \ Repository \ CommentRepository;使用App \ Repository \ ConferenceRepository;用程序\ SpamChecker;使用原则\ ORM \ EntityManagerInterface;控制器使ob娱乐下载用Symfony \包\ FrameworkBundle \ \ AbstractController;组件使用ob娱乐下载Symfony \ \ HttpFoundation \文件\ \ FileException异常;使用Syob娱乐下载mfony \ HttpFoundation \ \组件请求;组件使用ob娱乐下载Symfony \ \ HttpFoundation \反应;+使用Syob娱乐下载mfony \组件\ \ MessageBusInterface使者;使用Syob娱乐下载mfony \组件\路由\注释\路线;用树枝\环境;@@ -20年11 + 21日13 @@类ConferenceController延伸AbstractController{私人美元树枝;私人entityManager美元;美元+私人公交;——公共职能__construct(环境树枝美元,EntityManagerInterface entityManager美元)+公共职能__construct(环境树枝美元,EntityManagerInterface entityManager美元,美元MessageBusInterface总线){$ this - >枝= $树枝;$ this - > entityManager = $ entityManager;+ $ this - >总线= $总线;}#(路线(' / ',名字:“主页”)]@@ -36年7 + 39岁7 @@类ConferenceController延伸AbstractController} #(路线(“/会议/{蛞蝓}”,名字:“会议”))公共函数显示(请求美元请求、会议会议上,美元CommentRepository CommentRepository美元,SpamChecker SpamChecker美元,字符串photoDir美元):反应+公共函数显示(请求美元请求、会议会议上,美元CommentRepository CommentRepository美元,字符串photoDir美元):反应{$评论=新的评论();$ = $ this - > createForm形式(CommentFormType::类,评论美元);@@ -54 6 + 57 7 @@类ConferenceController延伸AbstractController} $ this - > entityManager - >保存($评论);+ $ this - > entityManager - >冲洗();$上下文= [' user_ip ' = > $请求- > getClientIp(), @@ -61年11 + 65,8 @@类ConferenceController延伸AbstractController“推荐人”= >请求- >标题- >获取美元(“推荐人”)、“永久链接”= > $请求- > getUri ());——如果(2 = = = $ spamChecker - > getSpamScore(评论,上下文美元)){——把新\ RuntimeException(“明目张胆的垃圾邮件,走开!”);- - - - - -}- $ this - > entityManager - >冲洗();+ $ this - >总线- >调度(新CommentMessage (- > getId()发表评论,美元上下文));返回$ this - > redirectToRoute(“会议”,(“鼻涕虫”= > $会议- > getSlug ()));}
Zamiast polegaćna kontrolerze spamu, wysyłamy teraz wiadomośćmagistrali。Następnie obiekt obsługi decyduje公司z niązrobić。
Osiągnęliśmy cośnieoczekiwanego。Odłączyliśmy nasz kontroler od kontrolera spamu我przenieśliśmy schemat działania做nowej klasy - obsługi (ang。处理程序)。Jest idealne zastosowanie国防后勤局magistrali。Przetestuj kod: działa。Wszystko jest纳达尔wykonywane synchronicznie,啤酒kod jest jużprawdopodobnie“lepszy”。
Idziemy w prawdziwąasynchroniczność
Domyślnie, obsługa wywoływana jest synchronicznie。偿przejść做trybu asynchronicznego, należy skonfigurować,ktorej kolejki użyć国防后勤局każdego obiektu obsługującego wiadomości (ang。处理程序)w pliku konfiguracyjnym配置/包/ messenger.yaml
:
1 2 3 4 5 6 7 8
- - - / config /包/ messenger.yaml+ + + b / config /包/ messenger.yaml@@ -21年,21岁的4 + 4 @@框架:Symfonob娱乐下载y \组件\消息通知\ \ SmsMessage:异步#你的消息路由到传输- #“App \消息\信件内容”:异步+应用程序消息\ \ CommentMessage:异步
Konfiguracja każe magistrali wysyłaćinstancje应用\ \ CommentMessage消息
做kolejki异步
,ktora jest zdefiniowana przez DSN (MESSENGER_TRANSPORT_DSN
),przechowywany w pliku zmiennychśrodowiskowych.env
。Krotko mowiąc, używamy PostgreSQL jako kolejki国防后勤局naszych wiadomości。
Skonfiguruj tabele我wyzwalacze w PostgreSQL:
1
美元ob娱乐下载symfony控制台:迁移
我zmigruj bazędanych:
1
美元ob娱乐下载symfony控制台学说:迁移:迁移
提示
咱kulisami Syob娱乐下载mfony używa wbudowanego PostgreSQL、wydajnego skalowalnego我transakcyjnego systemu pub / sub (听
/通知
)。Możesz także przeczytaćrozdziało RabbitMQ jeśli chcesz去używaćzamiast PostgreSQL jako brokera wiadomości。
Przetwarzanie wiadomości
Jeśli sprobujesz przesłaćnowy komentarz, kontroler spamu聂będzie jużwywoływany。Dodaj wywołanieerror_log ()
w metodziegetSpamScore ()
偿potwierdzić。Zamiast迪高,wiadomośćczeka w kolejce, gotowa skonsumowania przez jakiś过程。
木菠萝możesz siędomyślić,Symob娱乐下载fony posiada polecenie przetwarzania wiadomości。Uruchom我teraz:
1
美元ob娱乐下载symfony控制台信使:异步vv消费
Powinno小野natychmiast przetworzyćwiadomośćwysłanąw związku z przesłanymi komentarzami:
1 2 3 4 5 6 7 8 9 10 11
[好]消费信息传输“异步”。/ /工人将自动退出一旦收到了停止信号通过信使:stop-workers命令。/ /退出control - c的工人。11:30:20信息(信使)收到的消息应用\ \ CommentMessage消息(消息“消息”= >应用\ \ CommentMessage ^{…},“阶级”= >“应用程序消息\ \ CommentMessage”] 11:30:20信息[http_client]请求:“https://80cea32be1f6.rest.akismet.com/1.1/comment-check”11:30:20信息(http_client)回应:“200 https://80cea32be1f6.rest.akismet.com/1.1/comment-check”11:30:20信息(信使)消息应用\ \ CommentMessage消息由应用MessageHandler \ \ CommentMessageHandler:: __invoke(“消息”= >应用程序消息\ \ CommentMessage ^{…},“阶级”= >“应用\ \ CommentMessage消息”,“处理”= >“MessageHandler应用\ \ CommentMessageHandler: __invoke”] 11:30:20信息(信使)应用\ \ CommentMessage消息处理成功(承认运输)。["消息" = >应用程序消息\ \ CommentMessage ^{…},“阶级”= >“应用\ \ CommentMessage消息”)
Aktywnośćkonsumentow jest zapisywana w logach,啤酒możesz otrzymaćnatychmiastowąinformacjęzwrotnąna konsoli, przekazując flagęvv
。Możesz dostrzec nawet połączenie Akismet API。
偿zatrzymaćkonsumenta naciśnijCtrl + C
。
Robotnicy (ang。工人)działający w框架
Zamiast uruchamiaćkonsumenta咱każdym razem, gdy zamieszczamy komentarz,我zatrzymywaćnatychmiast阿宝tym, chcemy uruchomić去w sposob ciągły,鹿角的第二叉otwierania zbyt wielu okien滑zakładek terminala。
ob娱乐下载Symfony CLI może zarządzaćtakimi poleceniami w框架(robotnikami) używając flagi demona (- d
)na poleceniu运行
。
Uruchom ponownie konsumenta wiadomości,啤酒umieśćw框架:
1
美元ob娱乐下载src, symfony运行- d——看=配置模板,供应商symfony控制台信使:异步vv消费
Opcja——看
mowi ob娱乐下载Symfony,że polecenie musi zostaćzrestartowane咱każdym razem, gdy dochodzi做zmiany plikow w katalogach配置/
,src /
,模板/
、滑供应商/
。
请注意
聂używajvv
,ponieważotrzymasz zduplikowane wiadomości w服务器:日志
(wiadomości zarowno w logach我w konsoli)。
Jeśli konsument przestanie pracowaćz jakiegośpowodu(限制pamięci błąd, itp),到zostanie automatycznie uruchomiony ponownie。啤酒jeśli konsument przestanie pracowaćnatychmiast阿宝uruchomieniu——Symfonob娱乐下载y CLI podda się。
罗技sąprzesyłane strumieniowo przezob娱乐下载symfony服务器:日志
wraz z wszystkimi innymi logami pochodzącymi z PHP, serwera WWW我aplikacji:
1
美元ob娱乐下载symfony服务器:日志
Użyj polecenia服务器:状态
框架,赎wyświetlićlistęwszystkich robotnikow pracujących w w bieżącym projekcie:
1 2 3 4
美元ob娱乐下载symfony服务器:https://127.0.0.1:8000 Web服务器监听状态命令symfony控制台信使:使用异步运行与PID 15774(看配置/ src /模板/)
偿zatrzymaćrobotnika, zatrzymaj serwer WWW滑zabij PID podany przez polecenie服务器:状态
:
1
美元杀了15774年
Ponawianie dostarczenia niedostarczonych wiadomości
有限公司,jeśli API Akismet聂działa podczas przetwarzania wiadomości吗?马Tworca komentarza聂o tym pojęcia,啤酒wiadomośćzostaje utracona我komentarz ktorego dotyczyła,聂zostaje sprawdzony pod kątem bycia spamem。
信使posiada mechanizm ponawiania przetwarzania wiadomości w przypadku wystąpienia wyjątku podczas jej obsługi:
Jeśli pojawi się问题podczas obsługi wiadomości, konsument sprobuje ponownie trzy razy przed rezygnacją。一个potem zamiast odrzucićwiadomość,umieści jąw trwałej kolejce nieudanych przetworzeń(ang。失败的
),ktora wykorzystuje innątabelęw bazie danych。
Przejrzyj nieudane wiadomości, następnie ponow przetwarzanie咱pomocąnastępujących poleceń:
1 2 3
美元ob娱乐下载symfony控制台信使:失败:节目美元ob娱乐下载symfony控制台信使:失败:重试
Uruchamianie robotnikow na Platform.sh
偿przetwarzaćwiadomości od PostgreSQL, musimy bezustannie uruchamiaćpolecenie信使:消费
。Na平台。sh开玩笑,劳拉robotnika(ang。工人):
Podobnie木菠萝Syob娱乐下载mfony CLI,平台。sh zarządza restartami我logami。
偿odczytać罗技robotnika użyj:
1
美元ob娱乐下载syob直播appmfony云:日志——工人=所有的消息
Idąc dalej
- Samouczek ob娱乐下载SymfonyCasts信使;
- “Korporacyjna magistrala usług <https://pl.wikipedia.org/wiki/Enterprise_Service_Bus> ' _ (ang。企业服务总线)orazwzorzec CQRS;
- Dokumentacja ob娱乐下载Symfony信使;