ΠΏΡΠ΅Π΄Π³ΠΎΠ²ΠΎΡ
ΠΠΎΡΡ ΡΠ΅Π±ΡΠ°ΠΉΡ, ΠΊΠΎΠΉΡΠΎ ΡΠΏΡΠ°Π²Π»ΡΠ²Π°ΠΌ ΠΊΠ°ΡΠΎ Ρ
ΠΎΠ±ΠΈ, Π΅ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ Π΄Π° Ρ
ΠΎΡΡΠ²Π° ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΈ Π½Π°ΡΠ°Π»Π½ΠΈ ΡΡΡΠ°Π½ΠΈΡΠΈ ΠΈ Π»ΠΈΡΠ½ΠΈ ΡΠ°ΠΉΡΠΎΠ²Π΅. Π’Π°Π·ΠΈ ΡΠ΅ΠΌΠ° Π·Π°ΠΏΠΎΡΠ½Π° Π΄Π° ΠΌΠ΅ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΡΠ²Π° Π² ΡΠ°ΠΌΠΎΡΠΎ Π½Π°ΡΠ°Π»ΠΎ Π½Π° ΠΌΠΎΠ΅ΡΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ°Π½Π΅; Π² ΡΠΎΠ·ΠΈ ΠΌΠΎΠΌΠ΅Π½Ρ Π±ΡΡ
ΠΎΡΠ°ΡΠΎΠ²Π°Π½ ΠΎΡ Π½Π°ΠΌΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° ΡΡΡΠ°Ρ
ΠΎΡΠ½ΠΈ ΠΏΡΠΎΡΠ΅ΡΠΈΠΎΠ½Π°Π»ΠΈΡΡΠΈ, ΠΊΠΎΠΈΡΠΎ ΠΏΠΈΡΠ°Ρ Π·Π° ΡΠ΅Π±Π΅ ΡΠΈ, ΡΠ²ΠΎΠΈΡΠ΅ Ρ
ΠΎΠ±ΠΈΡΠ° ΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠΈ. ΠΠ°Π²ΠΈΠΊΡΡ Π΄Π° Π³ΠΈ ΠΎΡΠΊΡΠΈΠ²Π°ΠΌ Π·Π° ΡΠ΅Π±Π΅ ΡΠΈ ΠΎΡΡΠ°Π²Π° ΠΈ Π΄ΠΎ Π΄Π½Π΅Ρ: Π½Π° ΠΏΠΎΡΡΠΈ Π²ΡΠ΅ΠΊΠΈ ΠΊΠΎΠΌΠ΅ΡΡΠΈΠ°Π»Π΅Π½ ΠΈ Π½Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠ΅ΡΡΠΈΠ°Π»Π΅Π½ ΡΠ°ΠΉΡ ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠ°Π²Π°ΠΌ Π΄Π° Π³Π»Π΅Π΄Π°ΠΌ Π² Π΄ΠΎΠ»Π½ΠΈΡ ΠΊΠΎΠ»ΠΎΠ½ΡΠΈΡΡΠ» Π² ΡΡΡΡΠ΅Π½Π΅ Π½Π° Π²ΡΡΠ·ΠΊΠΈ ΠΊΡΠΌ Π°Π²ΡΠΎΡΠΈΡΠ΅.
ΠΡΡΡΠ΅ΡΡΠ²ΡΠ²Π°Π½Π΅ Π½Π° ΠΈΠ΄Π΅ΡΡΠ°
ΠΡΡΠ²Π°ΡΠ° Π²Π΅ΡΡΠΈΡ Π±Π΅ΡΠ΅ ΠΏΡΠΎΡΡΠΎ 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, Π±Π΅Π· Π½Π°Π»ΠΈΡΠΈΠ΅ΡΠΎ Π½Π° ΡΠ°ΠΌΠ°ΡΠ° ΡΠ°ΠΌΠΊΠ°.
symfony/messenger
ΠΡΡΠ²ΠΈΡΡ ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ Π²Π΅Π΄Π½Π°Π³Π° ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°ΡΠ΅ ΠΈΠ΄Π΅Π°Π»Π΅Π½ ΠΈ Π±Π΅Π· ΡΡΠΌΠ½Π΅Π½ΠΈΠ΅ Π³ΠΎ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Ρ . ΠΠΎ ΡΠ΅ ΠΎΠΊΠ°Π·Π° ΠΏΠΎ-ΡΡΡΠ΄Π½ΠΎ Π΄Π° ΡΠ΅ ΡΡΡΡΡΡ Π² Google ΠΏΡΠΈΠΌΠ΅ΡΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ ΠΈΠ·Π²ΡΠ½ Symfony. ΠΠ°ΠΊ Π΄Π° ΡΠ΅ ΡΠ³Π»ΠΎΠ±ΠΈ ΠΎΡ ΠΊΡΠΏ ΠΊΠ»Π°ΡΠΎΠ²Π΅ Ρ ΡΠ½ΠΈΠ²Π΅ΡΡΠ°Π»Π½ΠΈ, Π±Π΅Π·ΡΠΌΠΈΡΠ»Π΅Π½ΠΈ ΠΈΠΌΠ΅Π½Π°, Π°Π²ΡΠΎΠ±ΡΡ Π·Π° ΠΏΡΠ΅Π΄Π°Π²Π°Π½Π΅ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΈ Π΄ΠΎΡΠΈ Π½Π° Redis?
ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΡΠ° Π½Π° ΠΎΡΠΈΡΠΈΠ°Π»Π½ΠΈΡ ΡΠ°ΠΉΡ Π±Π΅ΡΠ΅ Π΄ΠΎΡΡΠ° ΠΏΠΎΠ΄ΡΠΎΠ±Π½Π°, Π½ΠΎ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡΡΠ° Π±Π΅ΡΠ΅ ΠΎΠΏΠΈΡΠ°Π½Π° ΡΠ°ΠΌΠΎ Π·Π° Symfony, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΡΠ΅Ρ
Π½ΠΈΡ Π»ΡΠ±ΠΈΠΌ YML ΠΈ Π΄ΡΡΠ³ΠΈ ΠΌΠ°Π³ΠΈΡΠ΅ΡΠΊΠΈ ΠΌΠ΅ΡΠΎΠ΄ΠΈ Π·Π° Π½Π΅-ΡΠΈΠΌΡΠΎΠ½ΠΈΡΡ. ΠΡΠΌΠ°Ρ
ΠΈΠ½ΡΠ΅ΡΠ΅Ρ ΠΊΡΠΌ ΡΠ°ΠΌΠΈΡ ΠΏΡΠΎΡΠ΅Ρ Π½Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅, ΠΎΡΠΎΠ±Π΅Π½ΠΎ ΠΏΠΎ Π²ΡΠ΅ΠΌΠ΅ Π½Π° Π½ΠΎΠ²ΠΎΠ³ΠΎΠ΄ΠΈΡΠ½ΠΈΡΠ΅ ΠΏΡΠ°Π·Π½ΠΈΡΠΈ. ΠΠΎ ΡΡΡΠ±Π²Π°ΡΠ΅ Π΄Π° ΠΏΡΠ°Π²Ρ ΡΠΎΠ²Π° Π½Π΅ΠΎΡΠ°ΠΊΠ²Π°Π½ΠΎ Π΄ΡΠ»Π³ΠΎ Π²ΡΠ΅ΠΌΠ΅.
ΠΠΏΠΈΡΡΡ Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ΅ΡΠ΅ ΠΊΠ°ΠΊ Π΄Π° ΡΡΠ·Π΄Π°Π΄Π΅ΡΠ΅ ΠΈΠ½ΡΡΠ°Π½ΡΠΈΡ Π½Π° ΡΠΈΡΡΠ΅ΠΌΠ°, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΠΈΠ·ΡΠΎΡΠ½ΠΈΡΠΈ Π½Π° Symfony, ΡΡΡΠΎ Π½Π΅ Π΅ Π½Π°ΠΉ-ΡΡΠΈΠ²ΠΈΠ°Π»Π½Π°ΡΠ° Π·Π°Π΄Π°ΡΠ° Π·Π° ΠΊΡΠ°ΡΡΠΊ ΡΡΠΎΠΊ:
Π‘Π»Π΅Π΄ ΠΊΠ°ΡΠΎ ΡΠ΅ Π·Π°ΡΠΎΠ²ΠΈΡ
Π²ΡΠ² Π²ΡΠΈΡΠΊΠΎ ΡΠΎΠ²Π° ΠΈ ΡΠ΅ ΠΎΠΏΠΈΡΠ°Ρ
Π΄Π° Π½Π°ΠΏΡΠ°Π²Ρ Π½Π΅ΡΠΎ Ρ ΡΡΡΠ΅ΡΠ΅ ΡΠΈ, ΡΡΠΈΠ³Π½Π°Ρ
Π΄ΠΎ ΠΈΠ·Π²ΠΎΠ΄Π°, ΡΠ΅ ΠΏΡΠ°Π²Ρ Π½ΡΠΊΠ°ΠΊΠ²ΠΈ ΠΏΠ°ΡΠ΅ΡΠΈΡΠΈ ΠΈ ΡΠ΅ΡΠΈΡ
Π΄Π° ΠΎΠΏΠΈΡΠ°ΠΌ Π½Π΅ΡΠΎ Π΄ΡΡΠ³ΠΎ.
ΠΎΡΠ²Π΅ΡΠ΅Π½ΠΈ/ΠΎΠΏΠ°ΡΠΊΠ°
ΠΠΊΠ°Π·Π° ΡΠ΅, ΡΠ΅ ΡΠ°Π·ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π΅ ΡΡΡΠ½ΠΎ ΡΠ²ΡΡΠ·Π°Π½Π° Ρ ΠΈΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΠ°ΡΠ° Π½Π° Laravel ΠΈ ΠΊΡΠΏ Π΄ΡΡΠ³ΠΈ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ, ΡΠ°ΠΊΠ° ΡΠ΅ Π½Π΅ ΠΎΡΠ΄Π΅Π»ΠΈΡ ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅ Π·Π° Π½Π΅Ρ: ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Ρ Ρ, ΠΏΠΎΠ³Π»Π΅Π΄Π½Π°Ρ Ρ, Π²ΠΈΠ΄ΡΡ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈΡΠ΅ ΠΈ Ρ ΠΈΠ·ΡΡΠΈΡ .
yiisoft/yii2-ΠΎΠΏΠ°ΡΠΊΠ°
Π, ΡΡΠΊ Π²Π΅Π΄Π½Π°Π³Π° ΡΠ΅ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈ ΠΎΡ ΠΈΠΌΠ΅ΡΠΎ, ΠΎΡΠ½ΠΎΠ²ΠΎ, ΡΡΡΠΎΠ³Π° Π²ΡΡΠ·ΠΊΠ° Ρ Yii2. Π’ΡΡΠ±Π²Π°ΡΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ ΡΠ°Π·ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΠΈ Π½Π΅ Π±Π΅ΡΠ΅ Π»ΠΎΡΠΎ, Π½ΠΎ Π½Π΅ ΡΠ΅ Π·Π°ΠΌΠΈΡΠ»ΠΈΡ , ΡΠ΅ Π·Π°Π²ΠΈΡΠΈ Π½Π°ΠΏΡΠ»Π½ΠΎ ΠΎΡ Yii2.
ΠΡΡΠ°Π½Π°Π»ΠΈΡΠ΅
ΠΡΠΈΡΠΊΠΎ ΠΎΡΡΠ°Π½Π°Π»ΠΎ, ΠΊΠΎΠ΅ΡΠΎ Π½Π°ΠΌΠ΅ΡΠΈΡ Π² GitHub, Π±ΡΡ Π° Π½Π΅Π½Π°Π΄Π΅ΠΆΠ΄Π½ΠΈ, ΠΎΡΡΠ°ΡΠ΅Π»ΠΈ ΠΈ ΠΈΠ·ΠΎΡΡΠ°Π²Π΅Π½ΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠΈ Π±Π΅Π· Π·Π²Π΅Π·Π΄ΠΈ, ΡΠΎΡΠΊΠΎΠ²Π΅ ΠΈ Π³ΠΎΠ»ΡΠΌ Π±ΡΠΎΠΉ Π°Π½Π³Π°ΠΆΠΈΠΌΠ΅Π½ΡΠΈ.
ΠΡΡΠ½Π΅ΡΠ΅ ΡΠ΅ ΠΊΡΠΌ symfony/messenger, ΡΠ΅Ρ Π½ΠΈΡΠ΅ΡΠΊΠΈ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ
Π’ΡΡΠ±Π²Π°ΡΠ΅ Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ° ΡΠ°Π·ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΠΈ ΡΠ»Π΅Π΄ ΠΊΠ°ΡΠΎ ΠΏΡΠ΅ΠΊΠ°ΡΠ°Ρ ΠΎΡΠ΅ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ Π²ΡΠ΅ΠΌΠ΅, ΡΡΠΏΡΡ . ΠΠΊΠ°Π·Π° ΡΠ΅, ΡΠ΅ Π²ΡΠΈΡΠΊΠΎ Π΅ ΡΡΠ²ΡΠ΅ΠΌ ΠΊΡΠ°ΡΠΊΠΎ ΠΈ ΠΏΡΠΎΡΡΠΎ. ΠΠ° Π΄Π° ΡΡΠ·Π΄Π°ΠΌ Π°Π²ΡΠΎΠ±ΡΡΠ°, Π½Π°ΠΏΡΠ°Π²ΠΈΡ ΠΌΠ°Π»ΠΊΠ° ΡΠ°Π±ΡΠΈΠΊΠ°, Π·Π°ΡΠΎΡΠΎ... Π’ΡΡΠ±Π²Π°ΡΠ΅ Π΄Π° ΠΈΠΌΠ°ΠΌ Π½ΡΠΊΠΎΠ»ΠΊΠΎ Π³ΡΠΌΠΈ ΠΈ Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΌΠ°Π½ΠΈΠΏΡΠ»Π°ΡΠΎΡΠΈ.
Π‘Π°ΠΌΠΎ Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΡΡΡΠΏΠΊΠΈ:
- ΠΠΈΠ΅ ΡΡΠ·Π΄Π°Π²Π°ΠΌΠ΅ ΠΌΠ°Π½ΠΈΠΏΡΠ»Π°ΡΠΎΡΠΈ Π½Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΡ, ΠΊΠΎΠΈΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° ΠΌΠΎΠ³Π°Ρ ΠΏΡΠΎΡΡΠΎ Π΄Π° ΡΠ΅ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ
- ΠΠ±Π²ΠΈΠ²Π°ΠΌΠ΅ Π³ΠΈ Π² HandlerDescriptor (ΠΊΠ»Π°Ρ ΠΎΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ°)
- ΠΠΈΠ΅ ΠΎΠ±Π²ΠΈΠ²Π°ΠΌΠ΅ ΡΠ΅Π·ΠΈ βΠ΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠΈβ Π² Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ Π½Π° HandlersLocator
- ΠΠΎΠ±Π°Π²ΡΠ½Π΅ Π½Π° HandlersLocator ΠΊΡΠΌ Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° Π½Π° MessageBus
- ΠΡΠ΅Π΄Π°Π²Π°ΠΌΠ΅ Π½Π°Π±ΠΎΡ ΠΎΡ `SenderInterface` ΠΊΡΠΌ SendersLocator, Π² ΠΌΠΎΡ ΡΠ»ΡΡΠ°ΠΉ Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΈ Π½Π° `RedisTransport` ΠΊΠ»Π°ΡΠΎΠ²Π΅, ΠΊΠΎΠΈΡΠΎ ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°Π½ΠΈ ΠΏΠΎ ΠΎΡΠ΅Π²ΠΈΠ΄Π΅Π½ Π½Π°ΡΠΈΠ½
- ΠΠΎΠ±Π°Π²ΡΠ½Π΅ Π½Π° SendersLocator ΠΊΡΠΌ Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° Π½Π° MessageBus
MessageBus ΠΈΠΌΠ° ΠΌΠ΅ΡΠΎΠ΄ `->dispatch()`, ΠΊΠΎΠΉΡΠΎ ΡΡΡΡΠΈ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΈΡΠ΅ ΠΌΠ°Π½ΠΈΠΏΡΠ»Π°ΡΠΎΡΠΈ Π² HandlersLocator ΠΈ ΠΈΠΌ ΠΏΡΠ΅Π΄Π°Π²Π° ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΡΡΠΎΡΠ²Π΅ΡΠ½ΠΈΡ `SenderInterface` Π·Π° ΠΈΠ·ΠΏΡΠ°ΡΠ°Π½Π΅ ΠΏΡΠ΅Π· ΡΠΈΠ½Π°ΡΠ° (Redis ΠΏΠΎΡΠΎΡΠΈ).
Π ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡΠ° Π½Π° ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ° (Π² ΡΠΎΠ·ΠΈ ΡΠ»ΡΡΠ°ΠΉ 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β, ΠΎΠ±ΡΠ°Π±ΠΎΡΠ²Π° Π³ΠΎ ΠΈ ΠΏΡΠ΅Π΄Π°Π²Π° ΠΆΠ΅Π»Π°Π½ΠΎΡΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ Π½Π΅Π³ΠΎΠ²ΠΈΡ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ ΠΏΠΎ-Π½Π°ΡΠ°ΡΡΠΊ.
Π ΠΊΡΠ°ΠΉΠ½Π° ΡΠΌΠ΅ΡΠΊΠ° ΠΏΠΎΠ»ΡΡΠΈΡ
ΠΌΠ΅ Π½ΡΠΊΠΎΠ»ΠΊΠΎ Π΄Π΅ΠΌΠΎΠ½Π°, Π²ΡΠ΅ΠΊΠΈ ΠΎΡ ΠΊΠΎΠΈΡΠΎ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ° Π²ΡΡΠ·ΠΊΠΈ ΡΠ°ΠΌΠΎ Ρ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΈΡΠ΅ ΡΠ΅ΡΡΡΡΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ Π΄Π΅ΠΌΠΎΠ½ Π΄Π΅ΡΡΠΊΠΎ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΠ·ΠΎΠ½ΡΠ΅ Π·Π° Π»Π°Π·Π΅Π½Π΅ ΡΡΠ΄ΡΡΠΆΠ° Π²ΡΠΈΡΠΊΠΈ ΠΌΠ°Π½ΠΈΠΏΡΠ»Π°ΡΠΎΡΠΈ, ΠΊΠΎΠΈΡΠΎ ΠΈΠ·ΠΈΡΠΊΠ²Π°Ρ Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ ΠΈΠ½ΡΠ΅ΡΠ½Π΅Ρ Π·Π° ΡΡΠ΄ΡΡΠΆΠ°Π½ΠΈΠ΅, ΠΈ Π΄Π΅ΠΌΠΎΠ½Π° ΡΠΏΠΎΡΡΡΠ²Π°ΠΌ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ° Π²ΡΡΠ·ΠΊΠ° Ρ Π±Π°Π·Π°ΡΠ° Π΄Π°Π½Π½ΠΈ.
Π‘Π΅Π³Π°, Π²ΠΌΠ΅ΡΡΠΎ Π΄Π° ΠΈΠ·Π±ΠΈΡΠ°Ρ ΠΎΡ Π±Π°Π·Π°ΡΠ° Π΄Π°Π½Π½ΠΈ, Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΈΡΠ΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΎΠ½Π½ΠΈ Π½ΠΎΠΌΠ΅ΡΠ° ΡΠ»Π΅Π΄ Π²ΠΌΡΠΊΠ²Π°Π½Π΅ ΠΎΡ persister ΠΏΡΠΎΡΡΠΎ ΡΠ΅ ΠΏΡΠ΅Π΄Π°Π²Π°Ρ ΠΏΡΠ΅Π· Π°Π²ΡΠΎΠ±ΡΡΠ° Π΄ΠΎ Π²ΡΠΈΡΠΊΠΈ Π·Π°ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠΎΠ²Π°Π½ΠΈ ΠΌΠ°Π½ΠΈΠΏΡΠ»Π°ΡΠΎΡΠΈ.
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com