ΠΡΠ΅Π΄ΠΈΡΠ»ΠΎΠ²ΠΈΠ΅
ΠΠΎΠΉ ΡΠ°ΠΉΡ, ΠΊΠΎΡΠΎΡΡΠΌ Ρ Π·Π°Π½ΠΈΠΌΠ°ΡΡΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Ρ
ΠΎΠ±Π±ΠΈ, ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ Π΄Π»Ρ Ρ
ΡΠ°Π½Π΅Π½ΠΈΡ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΡΡ
Π΄ΠΎΠΌΠ°ΡΠ½ΠΈΡ
ΡΡΡΠ°Π½ΠΈΡ ΠΈ ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΡΠ½ΡΡ
ΡΠ°ΠΉΡΠΎΠ². ΠΡΠ° ΡΠ΅ΠΌΠ° ΡΡΠ°Π»Π° ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠΎΠ²Π°ΡΡ ΠΌΠ΅Π½Ρ Π² ΡΠ°ΠΌΠΎΠΌ Π½Π°ΡΠ°Π»Π΅ ΠΌΠΎΠ΅Π³ΠΎ ΠΏΡΡΠΈ Π² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ, Π² ΡΠΎΡ ΠΌΠΎΠΌΠ΅Π½Ρ ΠΌΠ΅Π½Ρ Π²ΠΎΡΡ
ΠΈΡΠ°Π»ΠΎ Π½Π°Ρ
ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π±ΠΎΠ»ΡΡΠΈΡ
ΠΏΡΠΎΡΠ΅ΡΡΠΈΠΎΠ½Π°Π»ΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠΈΡΡΡ ΠΎ ΡΠ΅Π±Π΅, ΡΠ²ΠΎΠΈΡ
ΡΠ²Π»Π΅ΡΠ΅Π½ΠΈΡΡ
ΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠ°Ρ
. ΠΡΠΈΠ²ΡΡΠΊΠ° ΠΎΡΠΊΡΡΠ²Π°ΡΡ ΠΈΡ
Π΄Π»Ρ ΡΠ΅Π±Ρ ΠΎΡΡΠ°Π»Π°ΡΡ ΠΈ ΡΠ΅ΠΉΡΠ°Ρ: ΠΏΠΎΡΡΠΈ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΊΠΎΠΌΠΌΠ΅ΡΡΠ΅ΡΠΊΠΎΠΌ ΠΈ Π½Π΅ ΠΎΡΠ΅Π½Ρ ΡΠ°ΠΉΡΠ΅ Ρ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°Ρ Π·Π°Π³Π»ΡΠ΄ΡΠ²Π°ΡΡ Π² ΡΡΡΠ΅Ρ Π² ΠΏΠΎΠΈΡΠΊΠ°Ρ
ΡΡΡΠ»ΠΎΠΊ Π½Π° Π°Π²ΡΠΎΡΠΎΠ².
Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΈΠ΄Π΅ΠΈ
ΠΠ΅ΡΠ²Π°Ρ Π²Π΅ΡΡΠΈΡ Π±ΡΠ»Π° ΠΏΡΠΎΡΡΠΎ html-ΡΡΡΠ°Π½ΠΈΡΠ΅ΠΉ Π½Π° ΠΌΠΎΡΠΌ ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΡΠ½ΠΎΠΌ ΡΠ°ΠΉΡΠ΅, Π³Π΄Π΅ Ρ ΡΠΊΠ»Π°Π΄ΡΠ²Π°Π» ΡΡΡΠ»ΠΊΠΈ Ρ ΠΏΠΎΠ΄ΠΏΠΈΡΡΠΌΠΈ Π² ul-ΡΠΏΠΈΡΠΎΠΊ. ΠΠ°Π±ΡΠ°Π² Π·Π° ΠΊΠ°ΠΊΠΎΠ΅-ΡΠΎ Π²ΡΠ΅ΠΌΡ ΡΡΡΠ°Π½ΠΈΡ 20, Ρ Π½Π°ΡΠ°Π» Π΄ΡΠΌΠ°ΡΡ, ΡΡΠΎ ΡΡΠΎ Π½Π΅ ΠΎΡΠ΅Π½Ρ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎ ΠΈ ΡΠ΅ΡΠΈΠ» ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°ΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΏΡΠΎΡΠ΅ΡΡ. ΠΠ° stackoverflow Ρ Π·Π°ΠΌΠ΅ΡΠ°Π», ΡΡΠΎ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ ΡΠ°ΠΉΡΡ Π² ΡΠ²ΠΎΠΈΡ ΠΏΡΠΎΡΠΈΠ»ΡΡ , ΠΏΠΎΡΡΠΎΠΌΡ Ρ Π½Π°ΠΏΠΈΡΠ°Π» ΠΏΠ°ΡΡΠ΅Ρ Π½Π° php, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΎΡΡΠΎ ΡΠ΅Π» ΠΏΠΎ ΠΏΡΠΎΡΠΈΠ»ΡΠΌ, Π½Π°ΡΠΈΠ½Π°Ρ Ρ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ (Π°Π΄ΡΠ΅ΡΠ° Π½Π° SO ΠΈ ΠΏΠΎ ΡΠ΅ΠΉ Π΄Π΅Π½Ρ ΡΠ°ΠΊΠΎΠ³ΠΎ Π²ΠΈΠ΄Π°: `/users/1`), ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π» ΡΡΡΠ»ΠΊΠΈ ΠΈΠ· Π½ΡΠΆΠ½ΠΎΠ³ΠΎ ΡΠ΅Π³Π° ΠΈ ΡΠΊΠ»Π°Π΄ΡΠ²Π°Π» Π² SQLite.
ΠΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°Π·Π²Π°ΡΡ Π²ΡΠΎΡΠΎΠΉ Π²Π΅ΡΡΠΈΠ΅ΠΉ: ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΡ ΠΈΠ· Π΄Π΅ΡΡΡΠΊΠ° ΡΡΡΡΡ ΡΡΠ»ΠΎΠ² Π² SQLite ΡΠ°Π±Π»ΠΈΡΠΊΠ΅, ΠΊΠΎΡΠΎΡΠ°Ρ Π·Π°ΠΌΠ΅Π½ΠΈΠ»Π° ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΠΏΠΈΡΠΎΠΊ Π² html. ΠΠΎ ΡΡΠΎΠΌΡ ΡΠΏΠΈΡΠΊΡ Ρ ΡΠ΄Π΅Π»Π°Π» ΠΏΡΠΎΡΡΠΎΠΉ ΠΏΠΎΠΈΡΠΊ. Π’.ΠΊ. Π±ΡΠ»ΠΈ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΠ»Ρ, ΡΠΎ ΠΈ ΠΏΠΎΠΈΡΠΊ Π±ΡΠ» ΠΏΡΠΎΡΡΠΎ ΠΏΠΎ Π½ΠΈΠΌ.
ΠΠ° ΡΡΠΎΠΌ ΡΡΠ°ΠΏΠ΅ Ρ Π·Π°Π±ΡΠΎΡΠΈΠ» ΠΏΡΠΎΠ΅ΠΊΡ ΠΈ Π²Π΅ΡΠ½ΡΠ»ΡΡ ΠΊ Π½Π΅ΠΌΡ, ΡΠΏΡΡΡΡ Π΄ΠΎΠ»Π³ΠΎΠ΅ Π²ΡΠ΅ΠΌΡ. ΠΠ° ΡΡΠΎΠΌ ΡΡΠ°ΠΏΠ΅ ΠΎΠΏΡΡ ΠΌΠΎΠ΅ΠΉ ΡΠ°Π±ΠΎΡΡ ΡΠΎΡΡΠ°Π²Π»ΡΠ» ΡΠΆΠ΅ Π±ΠΎΠ»ΡΡΠ΅ ΡΡΡΡ Π»Π΅Ρ ΠΈ Ρ ΡΡΠ²ΡΡΠ²ΠΎΠ²Π°Π», ΡΡΠΎ ΠΌΠΎΠ³Ρ ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠΎ-ΡΠΎ ΠΏΠΎΡΠ΅ΡΡΡΠ·Π½Π΅Π΅. Π ΡΠΎΠΌΡ ΠΆΠ΅ Π±ΡΠ»ΠΎ Π±ΠΎΠ»ΡΡΠΎΠ΅ ΠΆΠ΅Π»Π°Π½ΠΈΠ΅ ΠΎΡΠ²Π°ΠΈΠ²Π°ΡΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π½ΠΎΠ²ΡΠ΅ Π΄Π»Ρ ΡΠ΅Π±Ρ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ.
Π‘ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π²Π΅ΡΡΠΈΡ
ΠΡΠΎΠ±Π»Π΅ΠΌΠ°
ΠΠΎΠ²ΡΠ΅ ΡΠ°ΠΉΡΡ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡΡΡ ΠΊΠΎΠ½ΡΠΎΠ»ΡΠ½ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΠΎ Π΄Π΅Π»Π°Π΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅:
- Π‘ΠΊΠ°ΡΠΈΠ²Π°Π΅Ρ ΠΊΠΎΠ½ΡΠ΅Π½Ρ ΠΏΠΎ URL
- ΠΡΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠ»Π°Π³ ΠΎ ΡΠΎΠΌ, Π΄ΠΎΡΡΡΠΏΠ΅Π½ Π»ΠΈ Π±ΡΠ» HTTPS
- Π‘ΠΎΡ ΡΠ°Π½ΡΠ΅Ρ ΡΡΡΠ½ΠΎΡΡΡ Π²Π΅Π±-ΡΠ°ΠΉΡΠ°
- ΠΡΡ ΠΎΠ΄Π½ΡΠΉ HTML ΠΈ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ΡΠΎΡ ΡΠ°Π½ΡΠ΅Ρ Π² ΠΈΡΡΠΎΡΠΈΡ Β«ΠΈΠ½Π΄Π΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡΒ»
- ΠΠ°ΡΡΠΈΡ ΠΊΠΎΠ½ΡΠ΅Π½Ρ, ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ Title ΠΈ Description
- ΠΠ°Π½Π½ΡΠ΅ ΡΠΎΡ ΡΠ°Π½ΡΠ΅Ρ Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΡ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΡ
ΠΡΠΎΠ³ΠΎ Π±ΡΠ»ΠΎ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ, ΡΡΠΎΠ±Ρ ΠΏΡΠΎΡΡΠΎ Ρ ΡΠ°Π½ΠΈΡΡ ΡΠ°ΠΉΡΡ ΠΈ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡ ΠΈΡ Π² ΡΠΏΠΈΡΠΊΠ΅:
ΠΠΎ ΠΈΠ΄Π΅Ρ Π²ΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΈΠ½Π΄Π΅ΠΊΡΠΈΡΠΎΠ²Π°ΡΡ, ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΈ ΡΠ°Π½ΠΆΠΈΡΠΎΠ²Π°ΡΡ, Π΄Π΅ΡΠΆΠ° Π²ΡΡ Π² Π°ΠΊΡΡΠ°Π»ΡΠ½ΠΎΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΈ Π² ΡΡΡ ΠΏΠ°ΡΠ°Π΄ΠΈΠ³ΠΌΡ ΡΠΊΠ»Π°Π΄ΡΠ²Π°Π»Π°ΡΡ ΡΠ»Π°Π±ΠΎ. ΠΠ°ΠΆΠ΅ ΠΏΡΠΎΡΡΠΎΠ΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ web-ΠΌΠ΅ΡΠΎΠ΄Π° Π΄Π»Ρ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΡ ΡΡΡΠ°Π½ΠΈΡ ΠΏΠΎΡΡΠ΅Π±ΠΎΠ²Π°Π»ΠΎ Π΄ΡΠ±Π»ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΊΠΎΠ΄Π° ΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΎΠΊ Π΄Π»Ρ ΠΈΠ·Π±Π΅ΠΆΠ°Π½ΠΈΡ ΠΏΠΎΡΠ΅Π½ΡΠΈΠ°Π»ΡΠ½ΠΎΠ³ΠΎ DDoS.
ΠΠΎΠΎΠ±ΡΠ΅, ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ, Π²ΡΡ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π΅Π»Π°ΡΡ ΠΈ ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΠΎ, Π° Π² web-ΠΌΠ΅ΡΠΎΠ΄Π΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΡ ΠΏΡΠΎΡΡΠΎ ΡΠΎΡ ΡΠ°Π½Π΅Π½ΠΈΠ΅ Π£Π ΠΠ° Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΌΠΎΠ½ΡΡΡΡΠΎΠ·Π½ΡΠΉ Π΄Π΅ΠΌΠΎΠ½ Π²ΡΠΏΠΎΠ»Π½ΡΠ» Π²ΡΠ΅ Π·Π°Π΄Π°ΡΠΈ Π΄Π»Ρ Π£Π ΠΠΎΠ² ΠΈΠ· ΡΠΏΠΈΡΠΊΠ°. ΠΠΎ Π²ΡΡ ΡΠ°Π²Π½ΠΎ Π΄Π°ΠΆΠ΅ ΡΡΡ Π½Π°ΠΏΡΠ°ΡΠΈΠ²Π°Π΅ΡΡΡ ΡΠ»ΠΎΠ²ΠΎ Β«ΠΎΡΠ΅ΡΠ΅Π΄ΡΒ». Π Π΅ΡΠ»ΠΈ ΠΎΡΠ΅ΡΠ΅Π΄Ρ Π²Π½Π΅Π΄ΡΠΈΡΡ, ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠ΅ Π·Π°Π΄Π°ΡΠΈ ΡΠ°Π·Π΄Π΅Π»ΠΈΡΡ ΠΈ Π²ΡΠΏΠΎΠ»Π½ΡΡΡ ΠΏΠΎ ΠΊΡΠ°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅ΡΠ΅ Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΠΎ.
Π Π΅ΡΠ΅Π½ΠΈΠ΅
ΠΠ½Π΅Π΄ΡΠΈΡΡ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ ΠΈ ΡΠ΄Π΅Π»Π°ΡΡ event-driven ΡΠΈΡΡΠ΅ΠΌΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π²ΡΠ΅Ρ Π·Π°Π΄Π°Ρ. Π ΠΊΠ°ΠΊ ΡΠ°Π· Π΄Π°Π²Π½ΠΎ Ρ ΠΎΡΠ΅Π»ΠΎΡΡ ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°ΡΡ Redis Streams.
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Redis streams Π² PHP
Π’.ΠΊ. ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊ Ρ ΠΌΠ΅Π½Ρ Π½Π΅ ΠΈΠ· ΡΡΠΎΠΉΠΊΠΈ Π³ΠΈΠ³Π°Π½ΡΠΎΠ² Symfony, Laravel, Yii, ΡΠΎ ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ Ρ ΠΎΡΠ΅Π»ΠΎΡΡ Π±Ρ Π½Π°ΠΉΡΠΈ Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΡΡ. ΠΠΎ, ΠΊΠ°ΠΊ ΠΎΠΊΠ°Π·Π°Π»ΠΎΡΡ (ΠΏΡΠΈ ΠΏΠ΅ΡΠ²ΠΎΠΌ ΡΠ°ΡΡΠΌΠΎΡΡΠ΅Π½ΠΈΠΈ) β ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΡ ΡΠ΅ΡΡΡΠ·Π½ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ Π½Π°ΠΉΡΠΈ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. ΠΡΡ, ΡΡΠΎ ΡΠ²ΡΠ·Π°Π½ΠΎ Ρ ΠΎΡΠ΅ΡΠ΅Π΄ΡΠΌΠΈ, Π»ΠΈΠ±ΠΎ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΡΠΎΠ΅ΠΊΡΠΈΠΊΠΎΠΌ ΠΈΠ· 3 ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ² ΠΏΡΡΠΈΠ»Π΅ΡΠ½Π΅ΠΉ Π΄Π°Π²Π½ΠΎΡΡΠΈ, Π»ΠΈΠ±ΠΎ ΠΏΡΠΈΠ²ΡΠ·Π°Π½ΠΎ ΠΊ ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊΡ.
Π― Π½Π°ΡΠ»ΡΡΠ°Π½ ΠΎ Symfony, ΠΊΠ°ΠΊ ΠΎ ΠΏΠΎΡΡΠ°Π²ΡΠΈΠΊΠ΅ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΡ ΠΏΠΎΠ»Π΅Π·Π½ΡΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ², ΠΊ ΡΠΎΠΌΡ ΠΆΠ΅ Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ Ρ ΡΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ. Π ΡΠ°ΠΊΠΆΠ΅ ΠΎΡ Laravel ΠΊΠΎΠ΅-ΡΡΠΎ ΡΠΎΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΠΈΡ ORM, Π±Π΅Π· ΠΏΡΠΈΡΡΡΡΡΠ²ΠΈΡ ΡΠ°ΠΌΠΎΠ³ΠΎ ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊΠ°.
symfony/messenger
ΠΠ΅ΡΠ²ΡΠΉ ΠΆΠ΅ ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ ΡΡΠ°Π·Ρ ΠΆΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Π»ΡΡ ΠΈΠ΄Π΅Π°Π»ΡΠ½ΡΠΌ ΠΈ Π±Π΅Π·ΠΎ Π²ΡΡΠΊΠΈΡ ΡΠΎΠΌΠ½Π΅Π½ΠΈΠΉ Ρ Π΅Π³ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΠ». ΠΠΎ Π½Π°Π³ΡΠ³Π»ΠΈΡΡ ΠΏΡΠΈΠΌΠ΅ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ Π²Π½Π΅ Symfony ΠΎΠΊΠ°Π·Π°Π»ΠΎΡΡ ΡΠ»ΠΎΠΆΠ½Π΅Π΅. ΠΠ°ΠΊ ΡΠΎΠ±ΡΠ°ΡΡ ΠΈΠ· ΠΊΡΡΠΈ ΠΊΠ»Π°ΡΡΠΎΠ² Ρ ΡΠ½ΠΈΠ²Π΅ΡΡΠ°Π»ΡΠ½ΡΠΌΠΈ, Π½ΠΈ ΠΎ ΡΡΠΌ Π½Π΅ Π³ΠΎΠ²ΠΎΡΡΡΠΈΠΌΠΈ Π½Π°Π·Π²Π°Π½ΠΈΡΠΌΠΈ, ΡΠΈΠ½Ρ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ, Π΄Π° Π΅ΡΠ΅ ΠΈ Π½Π° Redis?
ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ Π½Π° ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΌ ΡΠ°ΠΉΡΠ΅ Π±ΡΠ»Π° Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΠΉ, Π½ΠΎ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ Π±ΡΠ»Π° ΠΎΠΏΠΈΡΠ°Π½Π° ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ Symfony Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΈΡ
Π»ΡΠ±ΠΈΠΌΠΎΠ³ΠΎ YML ΠΈ Π΄ΡΡΠ³ΠΈΡ
ΠΌΠ°Π³ΠΈΡΠ΅ΡΠΊΠΈΡ
ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² Π΄Π»Ρ Π½Π΅ ΡΠΈΠΌΡΠΎΠ½ΠΈΡΡΠ°. ΠΠ½ΡΠ΅ΡΠ΅ΡΠ° Π² ΡΠ°ΠΌΠΎΠΌ ΠΏΡΠΎΡΠ΅ΡΡΠ΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ Ρ ΠΌΠ΅Π½Ρ Π½Π΅ Π±ΡΠ»ΠΎ, ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ Π² Π½ΠΎΠ²ΠΎΠ³ΠΎΠ΄Π½ΠΈΠ΅ ΠΊΠ°Π½ΠΈΠΊΡΠ»Ρ. ΠΠΎ ΠΏΡΠΈΡΠ»ΠΎΡΡ Π·Π°Π½ΠΈΠΌΠ°ΡΡΡΡ ΡΡΠΈΠΌ ΠΈ Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½ΠΎ Π΄ΠΎΠ»Π³ΠΎ.
ΠΠΎΠΏΡΡΠΊΠ° ΡΠ°Π·ΠΎΠ±ΡΠ°ΡΡΡΡ Ρ ΠΈΠ½ΡΡΠ°Π½ΡΠΈΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΠΈΡΡΠ΅ΠΌΡ ΠΏΠΎ ΠΈΡΡ ΠΎΠ΄Π½ΠΈΠΊΠ°ΠΌ Symfony Π·Π°Π΄Π°ΡΠ° ΡΠΎΠΆΠ΅ Π½Π΅ ΡΠ°ΠΌΠ°Ρ ΡΡΠΈΠ²ΠΈΠ°Π»ΡΠ½Π°Ρ Π΄Π»Ρ ΡΠΆΠ°ΡΡΡ ΡΡΠΎΠΊΠΎΠ²:
ΠΠΎΠΊΠΎΠ²ΡΡΡΠ²ΡΠΈΡΡ Π² ΡΡΠΎΠΌ Π²ΡΡΠΌ ΠΈ ΠΏΠΎΠΏΡΡΠ°Π²ΡΠΈΡΡ ΡΡΠΎ-ΡΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠΊΠ°ΠΌΠΈ, Ρ ΠΏΡΠΈΡΠ΅Π» ΠΊ Π²ΡΠ²ΠΎΠ΄Ρ, ΡΡΠΎ Π·Π°Π½ΠΈΠΌΠ°ΡΡΡ ΠΊΠ°ΠΊΠΈΠΌΠΈ-ΡΠΎ ΠΊΠΎΡΡΡΠ»ΡΠΌΠΈ ΠΈ ΡΠ΅ΡΠΈΠ» ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°ΡΡ ΡΡΠΎ-Π½ΠΈΠ±ΡΠ΄Ρ Π΅ΡΠ΅.
illuminate/queue
ΠΠΊΠ°Π·Π°Π»ΠΎΡΡ, ΡΡΠΎ ΡΡΠ° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π½Π°ΠΌΠ΅ΡΡΠ²ΠΎ ΠΏΡΠΈΠ²ΡΠ·Π°Π½Π° ΠΊ ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΠ΅ Laravel ΠΈ ΠΊΡΡΠ΅ Π΄ΡΡΠ³ΠΈΡ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠ΅ΠΉ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Ρ Π½Π° Π½Π΅Π΅ Π½Π΅ ΡΡΠ°ΡΠΈΠ»: ΠΏΠΎΡΡΠ°Π²ΠΈΠ», ΠΏΠΎΡΠΌΠΎΡΡΠ΅Π», ΡΠ²ΠΈΠ΄Π΅Π» Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΈ ΡΠ΄Π°Π»ΠΈΠ».
yiisoft/yii2-queue
ΠΡ ΡΡΡ ΡΡΠ°Π·Ρ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π»ΠΎΡΡ ΠΈΠ· Π½Π°Π·Π²Π°Π½ΠΈΡ, ΠΎΠΏΡΡΡ ΠΆΠ΅ ΠΆΡΡΡΠΊΠ°Ρ ΠΏΡΠΈΠ²ΡΠ·ΠΊΠ° ΠΊ Yii2. ΠΡΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΎΠΉ ΠΌΠ½Π΅ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΠ»ΠΎΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΠΈ ΠΎΠ½Π° Π±ΡΠ»Π° Π½Π΅ΠΏΠ»ΠΎΡ ΠΎΠΉ, Π½ΠΎ ΠΎ ΡΠΎΠΌ, ΡΡΠΎ ΠΎΠ½Π° ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π·Π°Π²ΠΈΡΠΈΡ ΠΎΡ Yii2 Ρ Π½Π΅ Π΄ΡΠΌΠ°Π».
ΠΡΡΠ°Π»ΡΠ½ΡΠ΅
ΠΡΡ Π΄ΡΡΠ³ΠΎΠ΅, ΡΡΠΎ Ρ Π½Π°Ρ ΠΎΠ΄ΠΈΠ» Π½Π° Π³ΠΈΡΡ Π°Π±Π΅ β Π½Π΅Π½Π°Π΄Π΅ΠΆΠ½ΡΠ΅ ΡΡΡΠ°ΡΠ΅Π²ΡΠΈΠ΅ ΠΈ Π·Π°Π±ΡΠΎΡΠ΅Π½Π½ΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡΠΈΠΊΠΈ Π±Π΅Π· Π·Π²Π΅Π·Π΄, ΡΠΎΡΠΊΠΎΠ² ΠΈ Π±ΠΎΠ»ΡΡΠΎΠ³ΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ².
ΠΠΎΠ·Π²ΡΠ°Ρ ΠΊ symfony/messenger, ΡΠ΅Ρ Π½ΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ
ΠΡΠΈΡΠ»ΠΎΡΡ ΡΠ°Π·ΠΎΠ±ΡΠ°ΡΡΡΡ Ρ ΡΡΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΎΠΉ ΠΈ, ΠΏΠΎΡΡΠ°ΡΠΈΠ² Π΅ΡΠ΅ ΠΊΠ°ΠΊΠΎΠΉ-ΡΠΎ Π²ΡΠ΅ΠΌΡ, Ρ ΡΠΌΠΎΠ³. ΠΠΊΠ°Π·Π°Π»ΠΎΡΡ, ΡΡΠΎ Π²ΡΡ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π»Π°ΠΊΠΎΠ½ΠΈΡΠ½ΠΎ ΠΈ ΠΏΡΠΎΡΡΠΎ. ΠΠ»Ρ ΠΈΠ½ΡΡΠ°Π½ΡΠΈΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΠΈΠ½Ρ Ρ ΡΠ΄Π΅Π»Π°Π» Π½Π΅Π±ΠΎΠ»ΡΡΡΡ ΡΠ°Π±ΡΠΈΠΊΡ, Ρ.ΠΊ. ΡΠΈΠ½ Ρ ΠΌΠ΅Π½Ρ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π»ΠΎΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΈ Ρ ΡΠ°Π·Π½ΡΠΌΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°ΠΌΠΈ.
ΠΡΠ΅Π³ΠΎ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°Π³ΠΎΠ²:
- Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ ΠΏΡΠΎΡΡΠΎ 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 Π΄Π»Ρ Π΄Π²ΡΡ ΡΠ°Π·Π½ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΌΡ ΠΏΡΠΈΡΠ²ΠΎΠΈΠ»ΠΈ ΡΠ°Π·Π½ΡΠΉ Β«ΡΡΠ°Π½ΡΠΏΠΎΡΡΒ», ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· ΠΊΠΎΡΠΎΡΡΡ ΠΈΠΌΠ΅Π΅Ρ ΡΠ²ΠΎΠΉ ΠΊΠΎΠ½Π½Π΅ΠΊΡ Π½Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ ΡΡΡΠΈΠΌΡ.
Π― ΡΠ΄Π΅Π»Π°Π» ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ Π΄Π΅ΠΌΠΎ-ΠΏΡΠΎΠ΅ΠΊΡ, Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΡΠΈΠΉ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ· ΡΡΡΡ
Π΄Π΅ΠΌΠΎΠ½ΠΎΠ², ΠΎΠ±ΡΠ°ΡΡΠΈΡ
ΡΡ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΎΠ±ΠΎΠΉ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠ°ΠΊΠΎΠΉ ΡΠΈΠ½Ρ:
ΠΠΎ ΠΏΠΎΠΊΠ°ΠΆΡ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΡΡΡΠΎΠ΅Π½ ΠΊΠΎΠ½ΡΡΡΠΌΠ΅Ρ:
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. Π’.ΠΊ. ΡΡΠΎΡ ΠΏΡΠΎΡΠ΅ΡΡ ΡΠ°ΠΊΠΆΠ΅ ΡΡΠ΅Π±ΡΠ΅Ρ ΠΈΡΡ
ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ½ΡΠ΅Π½Ρ, ΡΠΎ Ρ
ΡΠ½Π΄Π»Π΅Ρ-ΠΈΠ·Π²Π»Π΅ΠΊΠ°ΡΠ΅Π»Ρ ΡΡΡΠ»ΠΊΠΈ Π½Π° rss ΡΠ°ΠΊΠΆΠ΅ ΠΊΠ°ΠΊ ΠΈ WebsiteIndexHistoryPersistor ΠΏΠΎΠ΄ΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ Π½Π° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Β«Content/HtmlContentΒ», ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ Π΅Π³ΠΎ ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅Ρ Π½ΡΠΆΠ½ΠΎΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠ²ΠΎΠ΅ΠΌΡ ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½Ρ Π΄Π°Π»ΡΡΠ΅.
Π ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΌ ΠΈΡΠΎΠ³Π΅ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΎΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π΄Π΅ΠΌΠΎΠ½ΠΎΠ², ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΈΠ· ΠΊΠΎΡΠΎΡΡΡ
Π΄Π΅ΡΠΆΠΈΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΊ Π½ΡΠΆΠ½ΡΠΌ ΡΠ΅ΡΡΡΡΠ°ΠΌ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ Π΄Π΅ΠΌΠΎΠ½ crawlers ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π² ΡΠ΅Π±Π΅ Π²ΡΠ΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΡΠ΅Π±ΡΡΡ ΠΏΠΎΡ
ΠΎΠ΄Π° Π² ΠΈΠ½ΡΠ΅ΡΠ½Π΅Ρ Π·Π° ΠΊΠΎΠ½ΡΠ΅Π½ΡΠΎΠΌ, Π° Π΄Π΅ΠΌΠΎΠ½ persister Π΄Π΅ΡΠΆΠΈΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½ΡΡ
.
Π’Π΅ΠΏΠ΅ΡΡ Π²ΠΌΠ΅ΡΡΠΎ ΡΠ΅Π»Π΅ΠΊΡΠΎΠ² ΠΈΠ· Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ
, Π½ΡΠΆΠ½ΡΠ΅ id ΠΏΠΎΡΠ»Π΅ Π²ΡΡΠ°Π²ΠΊΠΈ persisterβΠΎΠΌ ΠΏΡΠΎΡΡΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ ΡΠ΅ΡΠ΅Π· ΡΠΈΠ½Ρ Π²ΡΠ΅ΠΌ Π·Π°ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠΎΠ²Π°Π½Π½ΡΠΌ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°ΠΌ.
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com