ΠŸΡ€Π΅Π²ΠΎΠ΄ Π½Π° PHP Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° Redis streams ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€Ρ†ΠΈΡ‚Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

ΠŸΡ€Π΅Π²ΠΎΠ΄ Π½Π° PHP Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° Redis streams ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€Ρ†ΠΈΡ‚Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

ΠŸΡ€Π΅Π΄Π³ΠΎΠ²ΠΎΡ€

Моя страница, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ я ΡΠΌΠΎΡ‚Ρ€ΡŽ ΠΊΠ°ΠΊ Π½Π° Ρ…ΠΎΠ±Π±ΠΈ, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° Π·Π° ΡΡŠΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ интСрСсни домашни страници ΠΈ Π»ΠΈΡ‡Π½ΠΈ сайтовС. Π’Π°Π·ΠΈ Ρ‚Π΅ΠΌΠ° Π·Π°ΠΏΠΎΡ‡Π½Π° Π΄Π° ΠΌΠ΅ интСрСсува ΠΎΡ‰Π΅ Π² Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° ΠΌΠΎΠ΅Ρ‚ΠΎ ΠΏΡŠΡ‚ΡƒΠ²Π°Π½Π΅ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ, ΠΊΠΎΠ³Π°Ρ‚ΠΎ бях Π²ΠΏΠ΅Ρ‡Π°Ρ‚Π»Π΅Π½ ΠΎΡ‚ откритията Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈ профСсионалисти, ΠΊΠΎΠΈΡ‚ΠΎ ΠΏΠΈΡˆΠ°Ρ‚ Π·Π° сСбС си, своитС увлСчСния ΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈ. ΠΠ°Π²ΠΈΠΊΡŠΡ‚ Π΄Π° Π³ΠΈ ΠΎΡ‚ΠΊΡ€ΠΈΠ²Π°ΠΌ остава ΠΈ сСга: ΠΏΠΎΡ‡Ρ‚ΠΈ Π½Π° всСки Ρ‚ΡŠΡ€Π³ΠΎΠ²ΡΠΊΠΈ ΠΈ Π½Π΅ Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° сайт, ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠ°Π²Π°ΠΌ Π΄Π° ΠΏΠΎΠ³Π»Π΅ΠΆΠ΄Π°ΠΌ Π² Π΄ΠΎΠ»Π½Π°Ρ‚Π° част Π² Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅ Π½Π° Π²Ρ€ΡŠΠ·ΠΊΠΈ към Π°Π²Ρ‚ΠΎΡ€ΠΈΡ‚Π΅.

РСализация Π½Π° идСята

ΠŸΡŠΡ€Π²Π°Ρ‚Π° вСрсия бСшС просто html-страница Π½Π° моя пСрсоналСн сайт, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ ΡΡŠΠ±ΠΈΡ€Π°Ρ… Π»ΠΈΠ½ΠΊΠΎΠ²Π΅ с надписи Π² ul-списък. Π‘Π»Π΅Π΄ ΠΊΠ°Ρ‚ΠΎ написах ΠΎΠΊΠΎΠ»ΠΎ 20 страници, Π·Π°ΠΏΠΎΡ‡Π½Π°Ρ… Π΄Π° мисля, Ρ‡Π΅ Ρ‚ΠΎΠ²Π° Π½Π΅ Π΅ особСно Π΅Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎ ΠΈ Ρ€Π΅ΡˆΠΈΡ… Π΄Π° ΠΎΠΏΠΈΡ‚Π°ΠΌ Π΄Π° Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€Π°ΠΌ процСса. Π’ stackoverflow забСлязвах, Ρ‡Π΅ ΠΌΠ½ΠΎΠ³ΠΎ Ρ…ΠΎΡ€Π° посочват сайтовС Π² ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ‚Π΅ си, Π·Π°Ρ‚ΠΎΠ²Π° написах парсСр Π½Π° php, ΠΊΠΎΠΉΡ‚ΠΎ просто минавашС ΠΏΡ€Π΅Π· ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ‚Π΅, Π·Π°ΠΏΠΎΡ‡Π²Π°ΠΉΠΊΠΈ ΠΎΡ‚ ΠΏΡŠΡ€Π²ΠΈΡ (адрСситС Π½Π° SO ΠΈ Π΄ΠΎ днСс ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°Ρ‚ Ρ‚Π°ΠΊΠ°: `/users/1`), ΠΈΠ·Π²Π»ΠΈΡ‡Π°ΡˆΠ΅ Π»ΠΈΠ½ΠΊΠΎΠ²Π΅ ΠΎΡ‚ нСобходимия Ρ‚Π°Π³ ΠΈ Π³ΠΈ ΡΠΊΠ»Π°Π΄ΠΈΡ€Π°ΡˆΠ΅ Π² SQLite.

Π’ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°Ρ€Π΅Ρ‡Π΅ Π²Ρ‚ΠΎΡ€Π°Ρ‚Π° вСрсия: колСкция ΠΎΡ‚ дСсСтки хиляди ΡƒΡ€Π»Π° Π² SQLite Ρ‚Π°Π±Π»ΠΈΡ†Π°, която Π·Π°ΠΌΠ΅Π½ΠΈ статичния списък Π² html. По Ρ‚ΠΎΠ·ΠΈ списък Π½Π°ΠΏΡ€Π°Π²ΠΈΡ… прост Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅. Въй ΠΊΠ°Ρ‚ΠΎ имашС само ΡƒΡ€Π»ΠΈ, Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅Ρ‚ΠΎ бСшС просто ΠΏΠΎ тях.

На Ρ‚ΠΎΠ·ΠΈ Π΅Ρ‚Π°ΠΏ оставих ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈ сС Π²ΡŠΡ€Π½Π°Ρ… към Π½Π΅Π³ΠΎ слСд дълго Π²Ρ€Π΅ΠΌΠ΅. На Ρ‚ΠΎΠ·ΠΈ Π΅Ρ‚Π°ΠΏ ΠΎΠΏΠΈΡ‚ΡŠΡ‚ ΠΌΠΈ бСшС Π²Π΅Ρ‡Π΅ Π½Π°Π΄ Ρ‚Ρ€ΠΈ Π³ΠΎΠ΄ΠΈΠ½ΠΈ ΠΈ чувствах, Ρ‡Π΅ ΠΌΠΎΠ³Π° Π΄Π° направя Π½Π΅Ρ‰ΠΎ ΠΏΠΎ-сСриозно. ОсвСн Ρ‚ΠΎΠ²Π° имашС голямо ΠΆΠ΅Π»Π°Π½ΠΈΠ΅ Π΄Π° усвоявам Π·Π° ΠΌΠ΅Π½ относитСлно Π½ΠΎΠ²ΠΈ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ.

Π‘ΡŠΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Π° вСрсия

ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ Ρ€Π°Π·Π²ΠΈΡ‚Π° Π² docker, Π±Π°Π·Π°Ρ‚Π° Π΅ прСмСстСна Π½Π° mongoDb, Π° сравнитСлно ΠΎΡ‚ скоро Π΅ Π΄ΠΎΠ±Π°Π²Π΅Π½ redis, ΠΊΠΎΠΉΡ‚ΠΎ ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎ бСшС просто Π·Π° ΠΊΠ΅ΡˆΠΈΡ€Π°Π½Π΅. ΠšΠ°Ρ‚ΠΎ основа сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π΅Π΄ΠΈΠ½ ΠΎΡ‚ ΠΌΠΈΠΊΡ€ΠΎ-Ρ„Ρ€Π΅ΠΉΠΌΡƒΡŠΡ€Ρ†ΠΈΡ‚Π΅ Π½Π° PHP.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°

НовитС сайтовС сС добавят с ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° Π² ΠΊΠΎΠ½Π·ΠΎΠ»Π°Ρ‚Π°, която синхронно ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° слСдното:

  • Π‘Π²Π°Π»ΠΈ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅Ρ‚ΠΎ ΠΏΠΎ URL
  • ΠŸΠΎΡΡ‚Π°Π²Ρ Ρ„Π»Π°Π³, Π΄Π°Π»ΠΈ Π΅ Π±ΠΈΠ» Π΄ΠΎΡΡ‚ΡŠΠΏΠ΅Π½ HTTPS
  • Π‘ΡŠΡ…Ρ€Π°Π½ΡΠ²Π° ΡΡŠΡ‰Π΅ΡΡ‚Π²ΠΎΡ‚ΠΎ Π½Π° ΡƒΠ΅Π±-сайта
  • Π—Π°ΠΏΠ°Π·Π²Π° оригиналния HTML ΠΈ Π·Π°Π³Π»Π°Π²ΠΊΠΈΡ‚Π΅ Π² историята Π½Π° "индСксиранСто"
  • ΠŸΠ°Ρ€ΡΠΈΡ€Π° ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅Ρ‚ΠΎ, ΠΈΠ·Π²Π»ΠΈΡ‡Π° Title ΠΈ Description
  • Π”Π°Π½Π½ΠΈΡ‚Π΅ сС ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Ρ‚ Π² ΠΎΡ‚Π΄Π΅Π»Π½Π° колСкция

Π’ΠΎΠ²Π° бСшС Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ, Π·Π° Π΄Π° ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°ΠΌ сайтовС ΠΈ Π΄Π° Π³ΠΈ ΠΏΠΎΠΊΠ°Π·Π²Π°ΠΌ Π² списък:

ΠŸΡ€Π΅Π²ΠΎΠ΄ Π½Π° PHP Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° Redis streams ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€Ρ†ΠΈΡ‚Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

Но идСята Π΄Π° индСксирамС всичко Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎ, Π΄Π° Π³ΠΎ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠ·ΠΈΡ€Π°ΠΌΠ΅ ΠΈ Π΄Π° Π³ΠΎ класирамС, ΠΊΠ°Ρ‚ΠΎ ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°ΠΌΠ΅ всичко Π°ΠΊΡ‚ΡƒΠ°Π»Π½ΠΎ, Π½Π΅ сС вписва Π² Ρ‚Π°Π·ΠΈ ΠΏΠ°Ρ€Π°Π΄ΠΈΠ³ΠΌΠ°. Π”ΠΎΡ€ΠΈ простото добавянС Π½Π° ΡƒΠ΅Π± ΠΌΠ΅Ρ‚ΠΎΠ΄ Π·Π° добавянС Π½Π° страници изисквашС Π΄ΡƒΠ±Π»ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΊΠΎΠ΄ ΠΈ Π·Π°ΠΊΠ»ΡŽΡ‡Π²Π°Π½ΠΈΡ, Π·Π° Π΄Π° сС ΠΈΠ·Π±Π΅Π³Π½Π΅ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»Π΅Π½ DDoS.

Π Π°Π·Π±ΠΈΡ€Π° сС, всичко ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΏΡ€Π°Π²ΠΈ ΠΈ синхронно, Π° Π² ΡƒΠ΅Π± ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π΄Π° сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠΈ просто Π·Π°ΠΏΠ°Π·Π²Π°Π½Π΅ Π½Π° URL, Π·Π° Π΄Π° ΠΌΠΎΠΆΠ΅ монструозният Π΄Π΅ΠΌΠΎΠ½ Π΄Π° изпълнява всички Π·Π°Π΄Π°Ρ‡ΠΈ Π·Π° URL ΠΎΡ‚ списъка. Но всС ΠΏΠ°ΠΊ Ρ‚ΡƒΠΊ сС Π½Π°Π±ΠΈΠ²Π° Π½Π° ΡƒΠΌ Π΄ΡƒΠΌΠ°Ρ‚Π° β€žΠΎΠΏΠ°ΡˆΠΊΠ°β€œ. А Π°ΠΊΠΎ Π²Π½Π΅Π΄Ρ€ΠΈΠΌ опашка, ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Ρ€Π°Π·Π΄Π΅Π»ΠΈΠΌ всички Π·Π°Π΄Π°Ρ‡ΠΈ ΠΈ Π΄Π° Π³ΠΈ изпълнявамС ΠΏΠΎΠ½Π΅ асинхронно.

РСшСниС

Π”Π° Π²Π½Π΅Π΄Ρ€ΠΈΠΌ опашки ΠΈ Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ систСма Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° всички Π·Π°Π΄Π°Ρ‡ΠΈ, управлявана ΠΎΡ‚ ΡΡŠΠ±ΠΈΡ‚ΠΈΡ. И ΠΎΡ‚Π΄Π°Π²Π½Π° искам Π΄Π° ΠΎΠΏΠΈΡ‚Π°ΠΌ Redis Streams.

ИзползванС на Redis streams в PHP

Въй ΠΊΠ°Ρ‚ΠΎ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΡŠΡ‚ ΠΌΠΈ Π½Π΅ Π΅ ΠΎΡ‚ Ρ‚Ρ€ΠΈΡ‚Π΅ Π³ΠΎΠ»Π΅ΠΌΠΈ, Symfony, Laravel, Yii, исках Π΄Π° намСря нСзависима Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°. Но, ΠΊΠ°ΠΊΡ‚ΠΎ сС ΠΎΠΊΠ°Π·Π° (ΠΏΡ€ΠΈ ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎΡ‚ΠΎ Ρ€Π°Π·Π³Π»Π΅ΠΆΠ΄Π°Π½Π΅), нСвъзмоТно Π΅ Π΄Π° сС намСрят сСриозни ΠΎΡ‚Π΄Π΅Π»Π½ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ. Всичко, ΡΠ²ΡŠΡ€Π·Π°Π½ΠΎ с ΠΎΠΏΠ°ΡˆΠΊΠΈΡ‚Π΅, ΠΈΠ»ΠΈ Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΎΡ‚ Ρ‚Ρ€ΠΈ ΠΊΠΎΠΌΠΈΡ‚Π°, Π½Π°ΠΏΡ€Π°Π²Π΅Π½ ΠΏΡ€Π΅Π΄ΠΈ ΠΏΠ΅Ρ‚ Π³ΠΎΠ΄ΠΈΠ½ΠΈ, ΠΈΠ»ΠΈ Π΅ ΡΠ²ΡŠΡ€Π·Π°Π½ΠΎ с Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°.

Π§ΡƒΡ… ΠΌΠ½ΠΎΠ³ΠΎ Π·Π° Symfony ΠΊΠ°Ρ‚ΠΎ доставчик Π½Π° ΠΏΠΎΠ»Π΅Π·Π½ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΈ, Π° ΠΈ някои ΠΎΡ‚ тях Π²Π΅Ρ‡Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ. ОсвСн Ρ‚ΠΎΠ²Π° ΠΎΡ‚ Laravel ΡΡŠΡ‰ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π½Π΅Ρ‰ΠΎ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ тяхната ORM, Π±Π΅Π· ΠΏΡ€ΠΈΡΡŠΡΡ‚Π²ΠΈΠ΅Ρ‚ΠΎ Π½Π° самия Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ.

symfony/messenger

ΠŸΡŠΡ€Π²ΠΈΡΡ‚ ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ Π²Π΅Π΄Π½Π°Π³Π° ΠΌΠΈ сС стори ΠΈΠ΄Π΅Π°Π»Π΅Π½ ΠΈ Π³ΠΎ инсталирах Π±Π΅Π· ΠΊΠΎΠ»Π΅Π±Π°Π½ΠΈΠ΅. Но Π½Π°ΠΌΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° ΡƒΠΏΠΎΡ‚Ρ€Π΅Π±Π° извън Symfony сС ΠΎΠΊΠ°Π·Π° ΠΏΠΎ-Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ. Как Π΄Π° сглобя ΠΎΡ‚ ΠΊΡƒΠΏ класовС с унивСрсални, Π½ΠΈΡ‰ΠΎ Π½Π΅ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°Ρ‰ΠΈ ΠΈΠΌΠ΅Π½Π°, шина Π·Π° ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ, ΠΈ Ρ‚ΠΎ с Redis?

ΠŸΡ€Π΅Π²ΠΎΠ΄ Π½Π° PHP Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° Redis streams ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€Ρ†ΠΈΡ‚Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

ДокумСнтацията Π½Π° официалния сайт бСшС доста ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π°, Π½ΠΎ инициализацията бСшС описана само Π·Π° Symfony с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° тяхната любима YML ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ магичСски ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π·Π° нСсимфонисти. НямашС интСрСс Π² самия процСс Π½Π° инсталиранС, особСно ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° Π½ΠΎΠ²ΠΎΠ³ΠΎΠ΄ΠΈΡˆΠ½ΠΈΡ‚Π΅ ΠΏΡ€Π°Π·Π½ΠΈΡ†ΠΈ. Но сС Π½Π°Π»ΠΎΠΆΠΈ Π΄Π° сС Π·Π°Π½ΠΈΠΌΠ°Π²Π°ΠΌ с Ρ‚ΠΎΠ²Π° ΠΈ Π½Π΅ΠΎΡ‡Π°ΠΊΠ²Π°Π½ΠΎ дълго.

ΠžΠΏΠΈΡ‚ΡŠΡ‚ Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π° ΠΊΠ°ΠΊ Π΄Π° инстанцирам систСмата ΠΏΠΎ изходния ΠΊΠΎΠ΄ Π½Π° Symfony ΡΡŠΡ‰ΠΎ Π½Π΅ Π΅ Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»Π½Π° Π·Π°Π΄Π°Ρ‡Π° Π·Π° ΠΊΡ€Π°Ρ‚ΠΊΠΈ сроковС:

ΠŸΡ€Π΅Π²ΠΎΠ΄ Π½Π° PHP Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° Redis streams ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€Ρ†ΠΈΡ‚Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

Π‘Π»Π΅Π΄ ΠΊΠ°Ρ‚ΠΎ сС ΠΏΠΎΡ€Π°Π·Ρ€ΠΎΠ²ΠΈΡ… Π² Ρ‚ΠΎΠ²Π° ΠΈ сС ΠΎΠΏΠΈΡ‚Π°Ρ… Π΄Π° направя Π½Π΅Ρ‰ΠΎ Π½Π° Ρ€ΡŠΠΊΠ°, стигнах Π΄ΠΎ ΠΈΠ·Π²ΠΎΠ΄Π°, Ρ‡Π΅ сС Π·Π°Π½ΠΈΠΌΠ°Π²Π°ΠΌ с някакви скСлСти ΠΈ Ρ€Π΅ΡˆΠΈΡ… Π΄Π° ΠΎΠΏΠΈΡ‚Π°ΠΌ Π½Π΅Ρ‰ΠΎ Π΄Ρ€ΡƒΠ³ΠΎ.

illuminate/queue

Оказа сС, Ρ‡Π΅ Ρ‚Π°Π·ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π΅ дълбоко ΡΠ²ΡŠΡ€Π·Π°Π½Π° с инфраструктурата Π½Π° Laravel ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ Π΄Ρ€ΡƒΠ³ΠΈ зависимости, Π·Π°Ρ‚ΠΎΠ²Π° Π½Π΅ ΠΎΡ‚Π΄Π΅Π»ΠΈΡ… ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π·Π° нСя: инсталирах я, ΠΏΠΎΠ³Π»Π΅Π΄Π½Π°Ρ…, видях зависимоститС ΠΈ я ΠΏΡ€Π΅ΠΌΠ°Ρ…Π½Π°Ρ….

yiisoft/yii2-queue

Π’ΡƒΠΊ Π²Π΅Π΄Π½Π°Π³Π° сС ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°ΡˆΠ΅ ΠΎΡ‚ ΠΈΠΌΠ΅Ρ‚ΠΎ, Ρ‡Π΅ ΠΈΠΌΠ° строг Π°Π½Π³Π°ΠΆΠΈΠΌΠ΅Π½Ρ‚ към Yii2. ΠŸΠΎΡ‚Ρ€Π΅Π±ΡΠ²Π°Π» съм Ρ‚Π°Π·ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΈ бСшС Π΄ΠΎΠ±Ρ€Π°, Π½ΠΎ Π½Π΅ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Ρ…, Ρ‡Π΅ тя Π΅ напълно зависима ΠΎΡ‚ Yii2.

ΠžΡΡ‚Π°Π½Π°Π»ΠΈΡ‚Π΅

Всичко Π΄Ρ€ΡƒΠ³ΠΎ, ΠΊΠΎΠ΅Ρ‚ΠΎ Π½Π°ΠΌΠ΅Ρ€ΠΈΡ… Π² GitHub, бяха Π½Π΅Π½Π°Π΄Π΅ΠΆΠ΄Π½ΠΈ, остарСли ΠΈ изоставСни ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈ Π±Π΅Π· Π·Π²Π΅Π·Π΄ΠΈ, фоксовС ΠΈ мноТСство ΠΊΠΎΠΌΠΈΡ‚ΠΈ.

Π’Ρ€ΡŠΡ‰Π°Π½Π΅ към symfony/messenger, тСхничСски подробности

Π’Ρ€ΡΠ±Π²Π°ΡˆΠ΅ Π΄Π° сС запозная с Ρ‚Π°Π·ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΈ, слСд ΠΊΠ°Ρ‚ΠΎ ΠΎΡ‚Π΄Π΅Π»ΠΈΡ… ΠΎΡ‰Π΅ извСстно Π²Ρ€Π΅ΠΌΠ΅, успях. Оказа сС, Ρ‡Π΅ всичко Π΅ относитСлно Π»Π°ΠΊΠΎΠ½ΠΈΡ‡Π½ΠΎ ΠΈ просто. Π—Π° инстанциранС Π½Π° ΡˆΠΈΠ½Π°Ρ‚Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΡ… ΠΌΠ°Π»ΠΊΠ° Ρ„Π°Π±Ρ€ΠΈΠΊΠ°, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΠΌ, Ρ‡Π΅ Ρ‰Π΅ ΠΈΠΌΠ°ΠΌ няколко шини с Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈ.

ΠŸΡ€Π΅Π²ΠΎΠ΄ Π½Π° PHP Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° Redis streams ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€Ρ†ΠΈΡ‚Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

Π‘Π°ΠΌΠΎ няколко ΡΡ‚ΡŠΠΏΠΊΠΈ:

  • БъздавамС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈ Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ, ΠΊΠΎΠΈΡ‚ΠΎ трябва Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ просто callable
  • ΠžΠ±Π³Ρ€ΡŠΡ‰Π°ΠΌΠ΅ Π³ΠΈ Π² HandlerDescriptor (клас ΠΎΡ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π°)
  • Π’Π΅Π·ΠΈ "ДСскриптори" ΠΎΠ±Π³Ρ€ΡŠΡ‰Π°ΠΌΠ΅ Π² инстанция Π½Π° HandlersLocator
  • ДобавямС HandlersLocator Π² инстанция Π½Π° MessageBus
  • ΠŸΡ€Π΅Π΄Π°Π²Π°ΠΌΠ΅ Π½Π° SendersLocator Π½Π°Π±ΠΎΡ€ `SenderInterface`, Π² моя случай инстанции Π½Π° класовС `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 Π·Π° Π΄Π²Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ смС Π·Π°Π΄Π°Π²Π°Π»ΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π΅Π½ β€žΡ‚Ρ€Π°Π½ΡΠΏΠΎΡ€Ρ‚β€œ, всСки ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ ΠΈΠΌΠ° своСто ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅ към ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΈΡ‚Π΅ стриймовС.

Π‘ΡŠΠ·Π΄Π°Π΄ΠΎΡ… ΠΎΡ‚Π΄Π΅Π»Π΅Π½ дСмонстрационСн ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, дСмонстриращ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΎΡ‚ Ρ‚Ρ€ΠΈ Π΄Π΅ΠΌΠΎΠ½Π°, ΠΊΠΎΠΈΡ‚ΠΎ ΠΊΠΎΠΌΡƒΠ½ΠΈΠΊΠΈΡ€Π°Ρ‚ ΠΏΠΎΠΌΠ΅ΠΆΠ΄Ρƒ си Ρ‡Ρ€Π΅Π· Ρ‚Π°ΠΊΠ°Π²Π° шина: https://github.com/backend-university/products/tree/master/products/02-redis-streams-bus.

Но Ρ‰Π΅ ΠΏΠΎΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС устроСн консумСр:

ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡ‚Π΅ AppMessagesDaemonLogMessage;
ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡ‚Π΅ SymfonyComponentMessengerHandlerHandlerDescriptor;
ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡ‚Π΅ SymfonyComponentMessengerHandlerHandlersLocator;
ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡ‚Π΅ SymfonyComponentMessengerMessageBus;
ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡ‚Π΅ SymfonyComponentMessengerMiddlewareHandleMessageMiddleware;
ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡ‚Π΅ SymfonyComponentMessengerMiddlewareSendMessageMiddleware;
ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΡ‚Π΅ 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 Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° Redis streams ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€Ρ†ΠΈΡ‚Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

И Ρ‚ΠΎΡ‡Π½ΠΎ слСд Ρ‚ΠΎΠ²Π° стана ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-лСсно Π΄Π° добавям Π½ΠΎΠ²ΠΈ функционалности, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ·Π²Π»ΠΈΡ‡Π°Π½Π΅ ΠΈ парсинг Π½Π° RSS. Въй ΠΊΠ°Ρ‚ΠΎ Ρ‚ΠΎΠ·ΠΈ процСс ΡΡŠΡ‰ΠΎ изисква ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½ΠΎ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅, Ρ…Π΅Π½Π΄Π»Π΅Ρ€ΡŠΡ‚, ΠΈΠ·Π²Π»ΠΈΡ‡Π°Ρ‰ Π»ΠΈΠ½ΠΊΠΎΠ²Π΅ към rss, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ WebsiteIndexHistoryPersistor, сС Π°Π±ΠΎΠ½ΠΈΡ€Π° Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Β«Content/HtmlContentΒ», ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π²Π° Π³ΠΎ ΠΈ ΠΏΡ€Π΅Π΄Π°Π²Π° Π½ΡƒΠΆΠ½ΠΎΡ‚ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΏΠΎ своя ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½ Π½Π°ΠΏΡ€Π΅Π΄.

ΠŸΡ€Π΅Π²ΠΎΠ΄ Π½Π° PHP Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° Redis streams ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€Ρ†ΠΈΡ‚Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

Π’ ΠΊΡ€Π°ΠΉΠ½Π° смСтка сС ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ…Π° няколко Π΄Π΅ΠΌΠΎΠ½Π°, всСки ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° Π²Ρ€ΡŠΠ·ΠΊΠΈ само към Π½ΡƒΠΆΠ½ΠΈΡ‚Π΅ рСсурси. НапримСр Π΄Π΅ΠΌΠΎΠ½ crawlers ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° всички ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ изискват Π΄ΠΎΡΡ‚ΡŠΠΏ Π΄ΠΎ ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Π·Π° ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅, Π° Π΄Π΅ΠΌΠΎΠ½ persister ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° Π²Ρ€ΡŠΠ·ΠΊΠ° с Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ.

Π‘Π΅Π³Π° вмСсто сСлСкти ΠΎΡ‚ Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ Π½ΡƒΠΆΠ½ΠΈΡ‚Π΅ id слСд Π²ΠΌΡŠΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ просто сС ΠΏΡ€Π΅Π΄Π°Π²Π°Ρ‚ ΠΏΡ€Π΅Π· ΡˆΠΈΠ½Π°Ρ‚Π° Π½Π° всички заинтСрСсовани ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈ.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster