Как Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚Π΅ свой собствСн автоскалСр Π·Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€

Π—Π΄Ρ€Π°Π²Π΅ΠΉΡ‚Π΅! НиС ΠΎΠ±ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ Ρ…ΠΎΡ€Π° Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с Π³ΠΎΠ»Π΅ΠΌΠΈ Π΄Π°Π½Π½ΠΈ. НСвъзмоТно Π΅ Π΄Π° си прСдставим ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚Π΅Π»Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π·Π° Π³ΠΎΠ»Π΅ΠΌΠΈ Π΄Π°Π½Π½ΠΈ Π±Π΅Π· собствСн ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€, Π²ΡŠΡ€Ρ…Ρƒ ΠΊΠΎΠΉΡ‚ΠΎ всички участници работят Π·Π°Π΅Π΄Π½ΠΎ. ΠŸΠΎΡ€Π°Π΄ΠΈ Ρ‚Π°Π·ΠΈ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π° Π½Π°ΡˆΠ°Ρ‚Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π²ΠΈΠ½Π°Π³ΠΈ я ΠΈΠΌΠ° πŸ™‚ НиС смС Π°Π½Π³Π°ΠΆΠΈΡ€Π°Π½ΠΈ с Π½Π΅ΠΉΠ½Π°Ρ‚Π° конфигурация, настройка ΠΈ администриранС, Π° ΠΌΠΎΠΌΡ‡Π΅Ρ‚Π°Ρ‚Π° Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ стартират MapReduce задания Ρ‚Π°ΠΌ ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Spark.

Π’ Ρ‚Π°Π·ΠΈ публикация Ρ‰Π΅ Π²ΠΈ Ρ€Π°Π·ΠΊΠ°ΠΆΠ΅ΠΌ ΠΊΠ°ΠΊ Ρ€Π΅ΡˆΠΈΡ…ΠΌΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° с Π½Π΅Ρ€Π°Π²Π½ΠΎΠΌΠ΅Ρ€Π½ΠΎΡ‚ΠΎ Π·Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π°, ΠΊΠ°Ρ‚ΠΎ написахмС наш собствСн Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π΅Π½ скалСр с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° ΠΎΠ±Π»Π°ΠΊΠ° ΠžΠ±Π»Π°Ρ‡Π½ΠΈ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π½Π° Mail.ru.

ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ

ΠΠ°ΡˆΠΈΡΡ‚ ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€ Π½Π΅ сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π² Ρ‚ΠΈΠΏΠΈΡ‡Π΅Π½ Ρ€Π΅ΠΆΠΈΠΌ. Π˜Π·Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅Ρ‚ΠΎ Π΅ силно Π½Π΅Ρ€Π°Π²Π½ΠΎΠΌΠ΅Ρ€Π½ΠΎ. НапримСр, ΠΈΠΌΠ° практичСски занятия, ΠΊΠΎΠ³Π°Ρ‚ΠΎ всичкитС 30 Π΄ΡƒΡˆΠΈ ΠΈ Π΅Π΄ΠΈΠ½ ΡƒΡ‡ΠΈΡ‚Π΅Π» ΠΎΡ‚ΠΈΠ²Π°Ρ‚ Π² ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π° ΠΈ Π·Π°ΠΏΠΎΡ‡Π²Π°Ρ‚ Π΄Π° Π³ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚. Или ΠΏΠ°ΠΊ ΠΈΠΌΠ° Π΄Π½ΠΈ ΠΏΡ€Π΅Π΄ΠΈ крайния срок, ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅Ρ‚ΠΎ сС ΡƒΠ²Π΅Π»ΠΈΡ‡Π°Π²Π° ΠΌΠ½ΠΎΠ³ΠΎ. ΠŸΡ€Π΅Π· останалото Π²Ρ€Π΅ΠΌΠ΅ ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€ΡŠΡ‚ Ρ€Π°Π±ΠΎΡ‚ΠΈ Π² Ρ€Π΅ΠΆΠΈΠΌ Π½Π° Π½Π΅Π΄ΠΎΡ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅.

РСшСниС β„–1 Π΅ Π΄Π° Π·Π°ΠΏΠ°Π·ΠΈΡ‚Π΅ ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ ΠΈΠ·Π΄ΡŠΡ€ΠΆΠΈ Π½Π° ΠΏΠΈΠΊΠΎΠ²ΠΈΡ‚Π΅ натоварвания, Π½ΠΎ Ρ‰Π΅ бъдС бСздСйстващ ΠΏΡ€Π΅Π· останалото Π²Ρ€Π΅ΠΌΠ΅.

РСшСниС β„–2 Π΅ Π΄Π° Π·Π°ΠΏΠ°Π·ΠΈΡ‚Π΅ малък ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€, към ΠΊΠΎΠΉΡ‚ΠΎ Ρ€ΡŠΡ‡Π½ΠΎ добавятС възли ΠΏΡ€Π΅Π΄ΠΈ класовС ΠΈ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° ΠΏΠΈΠΊΠΎΠ²ΠΈ натоварвания.

РСшСниС #3 Π΅ Π΄Π° Π·Π°ΠΏΠ°Π·ΠΈΡ‚Π΅ малък ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€ ΠΈ Π΄Π° Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π΅Π½ скалСр, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ слСди Ρ‚Π΅ΠΊΡƒΡ‰ΠΎΡ‚ΠΎ Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅ Π½Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π° ΠΈ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ API, добавя ΠΈ ΠΏΡ€Π΅ΠΌΠ°Ρ…Π²Π° възли ΠΎΡ‚ ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π°.

Π’ Ρ‚Π°Π·ΠΈ публикация Ρ‰Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π·Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ β„–3. Π’ΠΎΠ·ΠΈ автоскалСр Π΅ силно зависим ΠΎΡ‚ външни Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈ, Π° Π½Π΅ ΠΎΡ‚ Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ½ΠΈ, ΠΈ доставчицитС чСсто Π½Π΅ Π³ΠΎ прСдоставят. НиС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΎΠ±Π»Π°Ρ‡Π½Π°Ρ‚Π° инфраструктура Π½Π° Mail.ru Cloud Solutions ΠΈ написахмС Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π΅Π½ скалСр, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ MCS API. И Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Π½ΠΈΠ΅ ΡƒΡ‡ΠΈΠΌ ΠΊΠ°ΠΊ Π΄Π° Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌ с Π΄Π°Π½Π½ΠΈ, Ρ€Π΅ΡˆΠΈΡ…ΠΌΠ΅ Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΏΠΎΠ΄ΠΎΠ±Π΅Π½ автоскалСр Π·Π° Π²Π°ΡˆΠΈΡ‚Π΅ собствСни Ρ†Π΅Π»ΠΈ ΠΈ Π΄Π° Π³ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ с вашия ΠΎΠ±Π»Π°ΠΊ

ΠŸΡ€Π΅Π΄ΠΏΠΎΡΡ‚Π°Π²ΠΊΠΈ

ΠŸΡŠΡ€Π²ΠΎ, трябва Π΄Π° ΠΈΠΌΠ°Ρ‚Π΅ Hadoop ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€. НапримСр, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Ρ€Π°Π·ΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° HDP.

Π—Π° Π΄Π° ΠΌΠΎΠ³Π°Ρ‚ Π²Π°ΡˆΠΈΡ‚Π΅ възли Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ Π±ΡŠΡ€Π·ΠΎ добавяни ΠΈ ΠΏΡ€Π΅ΠΌΠ°Ρ…Π²Π°Π½ΠΈ, трябва Π΄Π° ΠΈΠΌΠ°Ρ‚Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΎ Ρ€Π°Π·ΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π½Π° Ρ€ΠΎΠ»ΠΈΡ‚Π΅ ΠΌΠ΅ΠΆΠ΄Ρƒ Π²ΡŠΠ·Π»ΠΈΡ‚Π΅.

  1. Π“Π»Π°Π²Π΅Π½ възСл. Π•, няма Π½ΡƒΠΆΠ΄Π° Π΄Π° обясняватС Π½ΠΈΡ‰ΠΎ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ: основният възСл Π½Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π°, Π½Π° ΠΊΠΎΠΉΡ‚ΠΎ Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ сС стартира Π΄Ρ€Π°ΠΉΠ²Π΅Ρ€ΡŠΡ‚ Π½Π° Spark, Π°ΠΊΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ интСрактивния Ρ€Π΅ΠΆΠΈΠΌ.
  2. Π’ΡŠΠ·Π΅Π» Π·Π° Π΄Π°Ρ‚Π°. Π’ΠΎΠ²Π° Π΅ Π²ΡŠΠ·Π΅Π»ΡŠΡ‚, Π½Π° ΠΊΠΎΠΉΡ‚ΠΎ ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Ρ‚Π΅ Π΄Π°Π½Π½ΠΈ Π·Π° HDFS ΠΈ ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π°Ρ‚ изчислСнията.
  3. Π˜Π·Ρ‡ΠΈΡΠ»ΠΈΡ‚Π΅Π»Π΅Π½ възСл. Π’ΠΎΠ²Π° Π΅ възСл, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ Π½Π΅ ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Ρ‚Π΅ Π½ΠΈΡ‰ΠΎ Π² HDFS, Π½ΠΎ ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π°Ρ‚ изчислСния.

Π’Π°ΠΆΠ΅Π½ ΠΌΠΎΠΌΠ΅Π½Ρ‚. Автоматичното ΠΌΠ°Ρ‰Π°Π±ΠΈΡ€Π°Π½Π΅ Ρ‰Π΅ сС случи ΠΏΠΎΡ€Π°Π΄ΠΈ възли ΠΎΡ‚ Ρ‚Ρ€Π΅Ρ‚ΠΈ Ρ‚ΠΈΠΏ. Ако Π·Π°ΠΏΠΎΡ‡Π½Π΅Ρ‚Π΅ Π΄Π° ΠΏΡ€ΠΈΠ΅ΠΌΠ°Ρ‚Π΅ ΠΈ добавятС възли ΠΎΡ‚ втория Ρ‚ΠΈΠΏ, скоростта Π½Π° рСакция Ρ‰Π΅ бъдС ΠΌΠ½ΠΎΠ³ΠΎ ниска - ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ ΠΎΡ‚ Сксплоатация ΠΈ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΡ‚ΠΎ ΠΏΠΎΠ΄Π°Π²Π°Π½Π΅ Ρ‰Π΅ ΠΎΡ‚Π½Π΅ΠΌΠ΅ часовС Π½Π° вашия ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€. Π’ΠΎΠ²Π°, Ρ€Π°Π·Π±ΠΈΡ€Π° сС, Π½Π΅ Π΅ Ρ‚ΠΎΠ²Π°, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΡ‡Π°ΠΊΠ²Π°Ρ‚Π΅ ΠΎΡ‚ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎΡ‚ΠΎ ΠΌΠ°Ρ‰Π°Π±ΠΈΡ€Π°Π½Π΅. ВоСст Π½Π΅ докосвамС възли ΠΎΡ‚ ΠΏΡŠΡ€Π²ΠΈ ΠΈ Π²Ρ‚ΠΎΡ€ΠΈ Ρ‚ΠΈΠΏ. Π’Π΅ Ρ‰Π΅ прСдставляват ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π΅Π½ ТизнСспособСн ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π° ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠΈΡ‚Π΅Π»Π½ΠΎΡΡ‚Ρ‚Π° Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°.

И Ρ‚Π°ΠΊΠ°, Π½Π°ΡˆΠΈΡΡ‚ autoscaler Π΅ написан Π½Π° Python 3, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Ambari API Π·Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π½ΠΈ услуги, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° API ΠΎΡ‚ Mail.ru Cloud Solutions (MCS) Π·Π° стартиранС ΠΈ спиранС Π½Π° машини.

АрхитСктура Π½Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ

  1. ΠœΠΎΠ΄ΡƒΠ» autoscaler.py. Π‘ΡŠΠ΄ΡŠΡ€ΠΆΠ° Ρ‚Ρ€ΠΈ класа: 1) Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с Ambari, 2) Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с MCS, 3) Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ пряко с Π»ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π° Π½Π° autoscaler.
  2. Π‘ΠΊΡ€ΠΈΠΏΡ‚ observer.py. По ΡΡŠΡ‰Π΅ΡΡ‚Π²ΠΎ сС ΡΡŠΡΡ‚ΠΎΠΈ ΠΎΡ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π°: ΠΊΠΎΠ³Π° ΠΈ Π² ΠΊΠ°ΠΊΠ²ΠΈ ΠΌΠΎΠΌΠ΅Π½Ρ‚ΠΈ Π΄Π° сС ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈΡ‚Π΅ Π·Π° Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎ ΠΌΠ°Ρ‰Π°Π±ΠΈΡ€Π°Π½Π΅.
  3. ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π΅Π½ Ρ„Π°ΠΉΠ» config.py. Π’ΠΎΠΉ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ списък с възли, Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈ Π·Π° Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎ ΠΌΠ°Ρ‰Π°Π±ΠΈΡ€Π°Π½Π΅ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ влияят Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π½Π° Ρ‚ΠΎΠ²Π° ΠΊΠΎΠ»ΠΊΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π΄Π° сС ΠΈΠ·Ρ‡Π°ΠΊΠ° ΠΎΡ‚ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°, Π² ΠΊΠΎΠΉΡ‚ΠΎ Π΅ Π΄ΠΎΠ±Π°Π²Π΅Π½ Π½ΠΎΠ² възСл. Има ΠΈ Π²Ρ€Π΅ΠΌΠ΅Π²ΠΈ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠΈ Π·Π° Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° класовСтС, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ ΠΏΡ€Π΅Π΄ΠΈ класа Π΄Π° сС стартира максимално Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½Π°Ρ‚Π° конфигурация Π½Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π°.

НСка сСга Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΠ°Ρ€Ρ‡Π΅Ρ‚Π°Ρ‚Π° ΠΊΠΎΠ΄ Π² ΠΏΡŠΡ€Π²ΠΈΡ‚Π΅ Π΄Π²Π° Ρ„Π°ΠΉΠ»Π°.

1. ΠœΠΎΠ΄ΡƒΠ» Autoscaler.py

Клас Амбари

Π•Ρ‚ΠΎ ΠΊΠ°ΠΊ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΠ°Ρ€Ρ‡Π΅ ΠΊΠΎΠ΄, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‰ клас Ambari:

class Ambari:
    def __init__(self, ambari_url, cluster_name, headers, auth):
        self.ambari_url = ambari_url
        self.cluster_name = cluster_name
        self.headers = headers
        self.auth = auth

    def stop_all_services(self, hostname):
        url = self.ambari_url + self.cluster_name + '/hosts/' + hostname + '/host_components/'
        url2 = self.ambari_url + self.cluster_name + '/hosts/' + hostname
        req0 = requests.get(url2, headers=self.headers, auth=self.auth)
        services = req0.json()['host_components']
        services_list = list(map(lambda x: x['HostRoles']['component_name'], services))
        data = {
            "RequestInfo": {
                "context":"Stop All Host Components",
                "operation_level": {
                    "level":"HOST",
                    "cluster_name": self.cluster_name,
                    "host_names": hostname
                },
                "query":"HostRoles/component_name.in({0})".format(",".join(services_list))
            },
            "Body": {
                "HostRoles": {
                    "state":"INSTALLED"
                }
            }
        }
        req = requests.put(url, data=json.dumps(data), headers=self.headers, auth=self.auth)
        if req.status_code in [200, 201, 202]:
            message = 'Request accepted'
        else:
            message = req.status_code
        return message

По-Π³ΠΎΡ€Π΅, ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°Ρ‚Π΅ ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° функцията stop_all_services, ΠΊΠΎΠ΅Ρ‚ΠΎ спира всички услуги Π½Π° ТСлания ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π΅Π½ възСл.

На Π²Ρ…ΠΎΠ΄Π° Π½Π° класа Ambari ΠΏΡ€Π΅ΠΌΠΈΠ½Π°Π²Π°Ρˆ:

  • ambari_url, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠ°Ρ‚ΠΎ 'http://localhost:8080/api/v1/clusters/',
  • cluster_name – ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° вашия ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€ Π² Ambari,
  • headers = {'X-Requested-By': 'ambari'}
  • ΠΈ Π²ΡŠΡ‚Ρ€Π΅ auth Π΅Ρ‚ΠΎ Π²Π°ΡˆΠ΅Ρ‚ΠΎ потрСбитСлско ΠΈΠΌΠ΅ ΠΈ ΠΏΠ°Ρ€ΠΎΠ»Π° Π·Π° Ambari: auth = ('login', 'password').

Π‘Π°ΠΌΠ°Ρ‚Π° функция Π½Π΅ Π΅ Π½ΠΈΡ‰ΠΎ ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ няколко извиквания ΠΏΡ€Π΅Π· REST API към Ambari. ΠžΡ‚ логичСска Π³Π»Π΅Π΄Π½Π° Ρ‚ΠΎΡ‡ΠΊΠ° ΠΏΡŠΡ€Π²ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ списък с изпълнявани услуги Π½Π° възСл ΠΈ слСд Ρ‚ΠΎΠ²Π° искамС ΠΎΡ‚ Π΄Π°Π΄Π΅Π½ ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€, ΠΎΡ‚ Π΄Π°Π΄Π΅Π½ възСл, Π΄Π° ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΠΈΠΌ услуги ΠΎΡ‚ списъка към ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅Ρ‚ΠΎ INSTALLED. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π° стартиранС Π½Π° всички услуги, Π·Π° ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° възли Π² ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅ Maintenance ΠΈ Ρ‚.Π½. ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°Ρ‚ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΈ - Ρ‚Π΅ са само няколко заявки ΠΏΡ€Π΅Π· API.

Клас Mcs

Π•Ρ‚ΠΎ ΠΊΠ°ΠΊ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΠ°Ρ€Ρ‡Π΅ ΠΊΠΎΠ΄, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‰ клас Mcs:

class Mcs:
    def __init__(self, id1, id2, password):
        self.id1 = id1
        self.id2 = id2
        self.password = password
        self.mcs_host = 'https://infra.mail.ru:8774/v2.1'

    def vm_turn_on(self, hostname):
        self.token = self.get_mcs_token()
        host = self.hostname_to_vmname(hostname)
        vm_id = self.get_vm_id(host)
        mcs_url1 = self.mcs_host + '/servers/' + self.vm_id + '/action'
        headers = {
            'X-Auth-Token': '{0}'.format(self.token),
            'Content-Type': 'application/json'
        }
        data = {'os-start' : 'null'}
        mcs = requests.post(mcs_url1, data=json.dumps(data), headers=headers)
        return mcs.status_code

На Π²Ρ…ΠΎΠ΄Π° Π½Π° класа Mcs ΠΏΡ€Π΅Π΄Π°Π²Π°ΠΌΠ΅ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π² ΠΎΠ±Π»Π°ΠΊΠ° ΠΈ потрСбитСлския ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ Π½Π΅Π³ΠΎΠ²Π°Ρ‚Π° ΠΏΠ°Ρ€ΠΎΠ»Π°. Π’ΡŠΠ² функция vm_turn_on искамС Π΄Π° Π²ΠΊΠ»ΡŽΡ‡ΠΈΠΌ Π΅Π΄Π½Π° ΠΎΡ‚ ΠΌΠ°ΡˆΠΈΠ½ΠΈΡ‚Π΅. Π›ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π° Ρ‚ΡƒΠΊ Π΅ ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎ-слоТна. Π’ Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° ΠΊΠΎΠ΄Π° сС ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ‚ Ρ‚Ρ€ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ: 1) трябва Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ Ρ‚ΠΎΠΊΠ΅Π½, 2) трябва Π΄Π° ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π°ΠΌΠ΅ ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° хоста Π² ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° ΠΌΠ°ΡˆΠΈΠ½Π°Ρ‚Π° Π² MCS, 3) Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° Π½Π° Ρ‚Π°Π·ΠΈ машина. Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° просто ΠΏΡ€Π°Π²ΠΈΠΌ заявка Π·Π° ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΠ²Π°Π½Π΅ ΠΈ стартирамС Ρ‚Π°Π·ΠΈ машина.

Π•Ρ‚ΠΎ ΠΊΠ°ΠΊ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° функцията Π·Π° ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Π½Π΅ Π½Π° Ρ‚ΠΎΠΊΠ΅Π½:

def get_mcs_token(self):
        url = 'https://infra.mail.ru:35357/v3/auth/tokens?nocatalog'
        headers = {'Content-Type': 'application/json'}
        data = {
            'auth': {
                'identity': {
                    'methods': ['password'],
                    'password': {
                        'user': {
                            'id': self.id1,
                            'password': self.password
                        }
                    }
                },
                'scope': {
                    'project': {
                        'id': self.id2
                    }
                }
            }
        }
        params = (('nocatalog', ''),)
        req = requests.post(url, data=json.dumps(data), headers=headers, params=params)
        self.token = req.headers['X-Subject-Token']
        return self.token

Клас на Autoscaler

Π’ΠΎΠ·ΠΈ клас ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ със самата ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π° Π»ΠΎΠ³ΠΈΠΊΠ°.

Π•Ρ‚ΠΎ ΠΊΠ°ΠΊ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° част ΠΎΡ‚ ΠΊΠΎΠ΄Π° Π·Π° Ρ‚ΠΎΠ·ΠΈ клас:

class Autoscaler:
    def __init__(self, ambari, mcs, scaling_hosts, yarn_ram_per_node, yarn_cpu_per_node):
        self.scaling_hosts = scaling_hosts
        self.ambari = ambari
        self.mcs = mcs
        self.q_ram = deque()
        self.q_cpu = deque()
        self.num = 0
        self.yarn_ram_per_node = yarn_ram_per_node
        self.yarn_cpu_per_node = yarn_cpu_per_node

    def scale_down(self, hostname):
        flag1 = flag2 = flag3 = flag4 = flag5 = False
        if hostname in self.scaling_hosts:
            while True:
                time.sleep(5)
                status1 = self.ambari.decommission_nodemanager(hostname)
                if status1 == 'Request accepted' or status1 == 500:
                    flag1 = True
                    logging.info('Decomission request accepted: {0}'.format(flag1))
                    break
            while True:
                time.sleep(5)
                status3 = self.ambari.check_service(hostname, 'NODEMANAGER')
                if status3 == 'INSTALLED':
                    flag3 = True
                    logging.info('Nodemaneger decommissioned: {0}'.format(flag3))
                    break
            while True:
                time.sleep(5)
                status2 = self.ambari.maintenance_on(hostname)
                if status2 == 'Request accepted' or status2 == 500:
                    flag2 = True
                    logging.info('Maintenance request accepted: {0}'.format(flag2))
                    break
            while True:
                time.sleep(5)
                status4 = self.ambari.check_maintenance(hostname, 'NODEMANAGER')
                if status4 == 'ON' or status4 == 'IMPLIED_FROM_HOST':
                    flag4 = True
                    self.ambari.stop_all_services(hostname)
                    logging.info('Maintenance is on: {0}'.format(flag4))
                    logging.info('Stopping services')
                    break
            time.sleep(90)
            status5 = self.mcs.vm_turn_off(hostname)
            while True:
                time.sleep(5)
                status5 = self.mcs.get_vm_info(hostname)['server']['status']
                if status5 == 'SHUTOFF':
                    flag5 = True
                    logging.info('VM is turned off: {0}'.format(flag5))
                    break
            if flag1 and flag2 and flag3 and flag4 and flag5:
                message = 'Success'
                logging.info('Scale-down finished')
                logging.info('Cooldown period has started. Wait for several minutes')
        return message

ΠŸΡ€ΠΈΠ΅ΠΌΠ°ΠΌΠ΅ класовС Π·Π° Π²Π»ΠΈΠ·Π°Π½Π΅. Ambari ΠΈ Mcs, списък с възли, ΠΊΠΎΠΈΡ‚ΠΎ са Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈ Π·Π° ΠΌΠ°Ρ‰Π°Π±ΠΈΡ€Π°Π½Π΅, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ Π·Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½Π΅ Π½Π° възСл: ΠΏΠ°ΠΌΠ΅Ρ‚ ΠΈ процСсор, Ρ€Π°Π·ΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈ Π·Π° възСла Π² YARN. Има ΠΈ 2 Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ½ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚ΡŠΡ€Π° q_ram, q_cpu, ΠΊΠΎΠΈΡ‚ΠΎ са опашки. Използвайки Π³ΠΈ, Π½ΠΈΠ΅ ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°ΠΌΠ΅ стойноститС Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰ΠΎΡ‚ΠΎ Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅ Π½Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π°. Ако Π²ΠΈΠ΄ΠΈΠΌ, Ρ‡Π΅ ΠΏΡ€Π΅Π· послСднитС 5 ΠΌΠΈΠ½ΡƒΡ‚ΠΈ Π΅ ΠΈΠΌΠ°Π»ΠΎ постоянно ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΎ Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅, Ρ‚ΠΎΠ³Π°Π²Π° Ρ€Π΅ΡˆΠ°Π²Π°ΠΌΠ΅, Ρ‡Π΅ трябва Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ +1 възСл към ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π°. Π‘ΡŠΡ‰ΠΎΡ‚ΠΎ Π²Π°ΠΆΠΈ ΠΈ Π·Π° ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Π½Π΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π°.

ΠšΠΎΠ΄ΡŠΡ‚ ΠΏΠΎ-Π³ΠΎΡ€Π΅ Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° функция, която ΠΏΡ€Π΅ΠΌΠ°Ρ…Π²Π° машина ΠΎΡ‚ ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π° ΠΈ я спира Π² ΠΎΠ±Π»Π°ΠΊΠ°. ΠŸΡŠΡ€Π²ΠΎ ΠΈΠΌΠ° ΠΈΠ·Π²Π΅ΠΆΠ΄Π°Π½Π΅ ΠΎΡ‚ Сксплоатация YARN Nodemanager, слСд ΠΊΠΎΠ΅Ρ‚ΠΎ Ρ€Π΅ΠΆΠΈΠΌΡŠΡ‚ сС Π²ΠΊΠ»ΡŽΡ‡Π²Π° Maintenance, слСд ΠΊΠΎΠ΅Ρ‚ΠΎ спирамС всички услуги Π½Π° ΠΌΠ°ΡˆΠΈΠ½Π°Ρ‚Π° ΠΈ ΠΈΠ·ΠΊΠ»ΡŽΡ‡Π²Π°ΠΌΠ΅ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π°Ρ‚Π° машина Π² ΠΎΠ±Π»Π°ΠΊΠ°.

2. Π‘ΠΊΡ€ΠΈΠΏΡ‚ Π½Π°Π±Π»ΡŽΠ΄Π°Ρ‚Π΅Π».py

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Π΅Π½ ΠΊΠΎΠ΄ ΠΎΡ‚ Ρ‚Π°ΠΌ:

if scaler.assert_up(config.scale_up_thresholds) == True:
        hostname = cloud.get_vm_to_up(config.scaling_hosts)
        if hostname != None:
            status1 = scaler.scale_up(hostname)
            if status1 == 'Success':
                text = {"text": "{0} has been successfully scaled-up".format(hostname)}
                post = {"text": "{0}".format(text)}
                json_data = json.dumps(post)
                req = requests.post(webhook, data=json_data.encode('ascii'), headers={'Content-Type': 'application/json'})
                time.sleep(config.cooldown_period*60)

Π’ Π½Π΅Π³ΠΎ провСрявамС Π΄Π°Π»ΠΈ са създадСни условия Π·Π° ΡƒΠ²Π΅Π»ΠΈΡ‡Π°Π²Π°Π½Π΅ Π½Π° ΠΊΠ°ΠΏΠ°Ρ†ΠΈΡ‚Π΅Ρ‚Π° Π½Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π° ΠΈ Π΄Π°Π»ΠΈ ΠΈΠΌΠ° Ρ€Π΅Π·Π΅Ρ€Π²Π½ΠΈ машини, ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° хоста Π½Π° Π΅Π΄Π½Π° ΠΎΡ‚ тях, добавямС я към ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π° ΠΈ ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΠ²Π°ΠΌΠ΅ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ Π·Π° Ρ‚ΠΎΠ²Π° Π² Slack Π½Π° нашия Π΅ΠΊΠΈΠΏ. Π‘Π»Π΅Π΄ ΠΊΠΎΠ΅Ρ‚ΠΎ Π·Π°ΠΏΠΎΡ‡Π²Π° cooldown_period, ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π½Π΅ добавямС ΠΈΠ»ΠΈ ΠΏΡ€Π΅ΠΌΠ°Ρ…Π²Π°ΠΌΠ΅ Π½ΠΈΡ‰ΠΎ ΠΎΡ‚ ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π°, Π° просто наблюдавамС Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅Ρ‚ΠΎ. Ако сС Π΅ стабилизирал ΠΈ Π΅ Π² ΠΊΠΎΡ€ΠΈΠ΄ΠΎΡ€Π° Π½Π° ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»Π½ΠΈΡ‚Π΅ стойности Π½Π° Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅, Ρ‚ΠΎΠ³Π°Π²Π° просто ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠ°Π²Π°ΠΌΠ΅ Π½Π°Π±Π»ΡŽΠ΄Π΅Π½ΠΈΠ΅Ρ‚ΠΎ. Ако Π΅Π΄ΠΈΠ½ възСл Π½Π΅ Π΅ Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π΅Π½, Ρ‚ΠΎΠ³Π°Π²Π° добавямС ΠΎΡ‰Π΅ Π΅Π΄ΠΈΠ½.

Π—Π° случаитС, ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π½ΠΈ прСдстои ΡƒΡ€ΠΎΠΊ, Π²Π΅Ρ‡Π΅ Π·Π½Π°Π΅ΠΌ със сигурност, Ρ‡Π΅ Π΅Π΄ΠΈΠ½ възСл няма Π΄Π° Π΅ Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π΅Π½, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Π²Π΅Π΄Π½Π°Π³Π° стартирамС всички свободни възли ΠΈ Π³ΠΈ ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°ΠΌΠ΅ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΈ Π΄ΠΎ края Π½Π° ΡƒΡ€ΠΎΠΊΠ°. Π’ΠΎΠ²Π° сС случва с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° списък с Π²Ρ€Π΅ΠΌΠ΅Π²ΠΈ ΠΊΠ»Π΅ΠΉΠΌΡ†Π° Π½Π° дСйността.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Autoscaler Π΅ Π΄ΠΎΠ±Ρ€ΠΎ ΠΈ ΡƒΠ΄ΠΎΠ±Π½ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π·Π° случаитС, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΠΈΠΌΠ°Ρ‚Π΅ Π½Π΅Ρ€Π°Π²Π½ΠΎΠΌΠ΅Ρ€Π½ΠΎ Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅ Π½Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π°. Π•Π΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ постигатС ΠΆΠ΅Π»Π°Π½Π°Ρ‚Π° конфигурация Π½Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π° Π·Π° ΠΏΠΈΠΊΠΎΠ²ΠΈ натоварвания ΠΈ Π² ΡΡŠΡ‰ΠΎΡ‚ΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π΅ Π·Π°Π΄ΡŠΡ€ΠΆΠ°Ρ‚Π΅ Ρ‚ΠΎΠ·ΠΈ ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° Π½Π΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°Π½Π΅, спСстявайки ΠΏΠ°Ρ€ΠΈ. Π•, освСн Ρ‚ΠΎΠ²Π° всичко Ρ‚ΠΎΠ²Π° сС случва Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎ, Π±Π΅Π· Π²Π°ΡˆΠ΅Ρ‚ΠΎ участиС. Бамият autoscaler Π½Π΅ Π΅ Π½ΠΈΡ‰ΠΎ ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ заявки към API Π½Π° ΠΌΠ΅Π½ΠΈΠ΄ΠΆΡŠΡ€Π° Π½Π° ΠΊΠ»ΡŠΡΡ‚Π΅Ρ€Π° ΠΈ API Π½Π° облачния доставчик, написани спорСд ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° Π»ΠΎΠ³ΠΈΠΊΠ°. Π’ΠΎΠ²Π°, ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΎ трябва Π΄Π° Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅, Π΅ раздСлянСто Π½Π° Π²ΡŠΠ·Π»ΠΈΡ‚Π΅ Π½Π° 3 Π²ΠΈΠ΄Π°, ΠΊΠ°ΠΊΡ‚ΠΎ писахмС ΠΏΠΎ-Ρ€Π°Π½ΠΎ. И Ρ‰Π΅ Π±ΡŠΠ΄Π΅Ρ‚Π΅ щастливи.

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

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€