{"id":87393,"date":"2020-07-08T01:42:02","date_gmt":"2020-07-07T23:42:02","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws"},"modified":"2020-07-08T01:42:02","modified_gmt":"2020-07-07T23:42:02","slug":"sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws","status":"publish","type":"post","link":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws","title":{"rendered":"Creazione di un'API scalabile su istanze spot di AWS","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Ciao a tutti! Mi chiamo Kirill, sono CTO in Adapty. Gran parte della nostra architettura si trova su AWS e oggi vi parler\u00f2 di come abbiamo ridotto i costi sui server di 3 volte grazie all'utilizzo di istanze spot in un ambiente di produzione e di come configurare il loro autoscaling. Inizier\u00f2 con una panoramica su come funziona, seguita da istruzioni dettagliate per l'implementazione.<\/p>\n<p><\/p>\n<h2 id=\"chto-takoe-spotovye-instansy\">Cosa sono le istanze spot?<\/h2>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/ru\/ec2\/spot\/\">Le<\/a><\/noindex> istanze spot sono server di altri utenti AWS che al momento sono inattivi e vengono venduti a un grande sconto (Amazon scrive fino al 90%, ma dalla nostra esperienza circa ~3x, varia a seconda della regione, AZ e tipo di istanza). La principale differenza rispetto alle normali \u00e8 che possono spegnersi in qualsiasi momento. Pertanto, a lungo abbiamo ritenuto che fosse normale utilizzarle per ambienti di sviluppo, o per calcoli di qualcosa, mantenendo i risultati intermedi su S3 o in un database, ma non per la produzione. Esistono soluzioni di terze parti che consentono di utilizzare le istanze spot in produzione, ma per il nostro caso presentano molti problemi, quindi non le abbiamo implementate. L'approccio descritto in questo articolo funziona interamente all'interno delle funzionalit\u00e0 standard di AWS, senza script aggiuntivi, cron e simili.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Di seguito mostrer\u00f2 alcuni screenshot che mostrano la storia dei prezzi delle istanze spot.<\/p>\n<p><\/p>\n<p>m5.large nella regione eu-west-1 (Irlanda). Il prezzo \u00e8 prevalentemente stabile per 3 mesi, attualmente il risparmio \u00e8 di 2.9x.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/901a259955c386493557280489f582fe.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>m5.large nella regione us-east-1 (Virginia del Nord). Il prezzo cambia costantemente per 3 mesi; attualmente il risparmio va da 2.3x a 2.8x a seconda della zona di disponibilit\u00e0.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/49c89430f03b2c7025355562d2873b6b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>t3.small nella regione us-east-1 (Virginia del Nord). Il prezzo \u00e8 stabile da 3 mesi; attualmente il risparmio \u00e8 di 3.4x.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/2e139dcc6d44bd37caf9d75eb6ec4835.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h2 id=\"arhitektura-servisa\">Architettura del servizio<\/h2>\n<p><\/p>\n<p>L'architettura di base del servizio di cui parleremo in questo articolo \u00e8 mostrata nel diagramma qui sotto.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/d89bd595675400861360670adaacaf03.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h3 id=\"application-load-balancer--ec2-target-group--elastic-container-service\">Application Load Balancer \u2192 EC2 Target Group \u2192 Elastic Container Service<\/h3>\n<p><\/p>\n<p>Come bilanciatore, utilizziamo l'Application Load Balancer (ALB), che invia le richieste al EC2 Target Group (TG). TG \u00e8 responsabile dell'apertura delle porte sugli istanze per l'ALB e della loro associazione con le porte dei contenitori del Elastic Container Service (ECS). ECS \u00e8 l'equivalente di Kubernetes in AWS, che gestisce i contenitori Docker.<\/p>\n<p><\/p>\n<p>Su un'istanza possono esserci pi\u00f9 contenitori attivi con le stesse porte, quindi non possiamo definirle in modo fisso. ECS informa TG che sta avviando un nuovo task (chiamato pod in terminologia Kubernetes), effettua un controllo sulle porte libere sull'istanza e ne assegna una per il task in avvio. TG controlla anche regolarmente se l'istanza e le API su di essa funzionano tramite un health check e, se riscontra dei problemi, smette di inviare richieste a quella istanza.<\/p>\n<p><\/p>\n<h3 id=\"ec2-auto-scaling-groups--ecs-capacity-providers\">EC2 Auto Scaling Groups + ECS Capacity Providers<\/h3>\n<p><\/p>\n<p>Nella diagramma riportata sopra non \u00e8 mostrato il servizio EC2 Auto Scaling Groups (ASG). Dal nome si pu\u00f2 capire che \u00e8 responsabile della scalabilit\u00e0 delle istanze. Fino a poco tempo fa, AWS non aveva una funzionalit\u00e0 integrata per gestire il numero di macchine avviate da ECS. ECS consentiva di scalare il numero di task, ad esempio, in base all'uso della CPU, RAM o al numero di richieste. Ma se i task occupavano tutte le istanze disponibili, nuove macchine non venivano avviate automaticamente.<\/p>\n<p><\/p>\n<p>Questo \u00e8 cambiato con l'introduzione di ECS Capacity Providers (ECS CP). Ora ogni servizio in ECS pu\u00f2 essere associato a un ASG e, se i task non possono essere contenuti nelle istanze attive, verr\u00e0 avviata una nuova (ma nel rispetto dei limiti impostati per l'ASG). Funziona anche in senso opposto: se ECS CP rileva istanze inattive senza task, ordina all'ASG di spegnerle. ECS CP ha la possibilit\u00e0 di specificare una percentuale di carico target delle istanze, in modo che un certo numero di macchine rimanga sempre libero per una rapida scalabilit\u00e0 dei task, vi parler\u00f2 di questo tra poco.<\/p>\n<p><\/p>\n<h3 id=\"ec2-launch-templates\">EC2 Launch Templates<\/h3>\n<p><\/p>\n<p>L'ultimo servizio di cui parler\u00f2, prima di passare a una descrizione dettagliata della creazione di questa infrastruttura, \u00e8 EC2 Launch Templates. Permette di creare un modello secondo il quale verranno avviate tutte le macchine, in modo da non dover ripetere il processo ogni volta da zero. Qui si possono scegliere il tipo di macchina da avviare, il gruppo di sicurezza, l'immagine del disco e molti altri parametri. \u00c8 possibile specificare anche dati utente che saranno caricati su tutte le istanze avviate. Nei dati utente \u00e8 possibile eseguire script, ad esempio, \u00e8 possibile modificare il contenuto di un file <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/ecs-agent-config.html\">di configurazione dell'agente ECS<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Uno dei parametri di configurazione pi\u00f9 importanti ai fini di questo articolo \u00e8 <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/container-instance-spot.html\">ECS_ENABLE_SPOT_INSTANCE_DRAINING<\/a><\/noindex>=true. Se questo parametro \u00e8 attivato, non appena ECS riceve un segnale che l'istanza spot viene ritirata, tutti i task in esecuzione su di essa vengono messi nello stato Draining. Nessun nuovo task verr\u00e0 assegnato a questa istanza e se ci sono task che vogliono passare su di essa, verranno annullati. Anche le richieste dal bilanciatore di carico smettono di arrivare. La notifica di rimozione dell'istanza arriva 2 minuti prima dell'evento effettivo. Quindi, se il tuo servizio non esegue attivit\u00e0 per pi\u00f9 di 2 minuti e non salva nulla su disco, puoi usare le istanze spot senza perdita di dati.<\/p>\n<p><\/p>\n<p>Riguardo al disco - AWS recentemente <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/about-aws\/whats-new\/2020\/04\/amazon-ecs-aws-fargate-support-amazon-efs-filesystems-generally-available\/#:~:text=To%20use%20EFS%20with%20ECS,or%20TLS%20encryption%20in%20transit.\">ha reso<\/a><\/noindex> possibile l'uso di Elastic File System (EFS) insieme a ECS, con questo schema anche il disco non rappresenta un ostacolo, ma non l'abbiamo provato poich\u00e9, in linea di principio, non abbiamo bisogno di un disco per memorizzare lo stato. Per impostazione predefinita, dopo aver ricevuto SIGINT (inviato nel momento in cui il task passa allo stato Draining), tutti i task in esecuzione verranno arrestati entro 30 secondi, anche se non hanno potuto completarsi, questo tempo pu\u00f2 essere modificato tramite il parametro <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/ecs-agent-config.html\">ECS_CONTAINER_STOP_TIMEOUT<\/a><\/noindex>. L'importante \u00e8 non impostarlo a pi\u00f9 di 2 minuti per le macchine spot.<\/p>\n<p><\/p>\n<h2 id=\"sozdanie-servisa\">Creazione del servizio<\/h2>\n<p><\/p>\n<p>Passiamo direttamente alla creazione del servizio descritto. Durante il processo descriver\u00f2 anche alcuni punti utili che non sono stati menzionati in precedenza. In generale, questa \u00e8 una guida passo passo, ma non tratter\u00f2 casi molto fondamentali o viceversa molto specifici. Tutte le azioni vengono eseguite nella console visuale di AWS, ma possono essere replicate programmaticamente utilizzando CloudFormation o Terraform. In Adapty utilizziamo Terraform.<\/p>\n<p><\/p>\n<h3 id=\"ec2-launch-template\"><strong>EC2 Launch Template<\/strong><\/h3>\n<p><\/p>\n<p>In questo servizio viene creata la configurazione delle macchine che verranno utilizzate. La gestione dei template avviene nella sezione EC2 -&gt; Instances -&gt; Launch templates.<\/p>\n<p><\/p>\n<p><strong>Amazon machine image (AMI)<\/strong> \u2014 specifichiamo l'immagine del disco da cui verranno avviate tutte le istanze. Per ECS, nella maggior parte dei casi, \u00e8 consigliabile utilizzare l'immagine ottimizzata di Amazon. Viene aggiornata regolarmente e contiene tutto il necessario per il funzionamento di ECS. Per scoprire l'ID dell'immagine attuale, accediamo alla pagina <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/ecs-optimized_AMI.html\">Amazon ECS-optimized AMIs<\/a><\/noindex>, selezioniamo la regione utilizzata e copiamo l'AMI ID per essa. Ad esempio, per la regione us-east-1, l'ID attuale al momento della scrittura di questo articolo \u00e8 <em>ami-00c7c1cf5bdc913ed<\/em>. Questo ID deve essere inserito nella voce Specifica un valore personalizzato.<\/p>\n<p><\/p>\n<p><strong>Tipo di istanza<\/strong> \u2014 specifichiamo il tipo di istanza. Scegli quello che meglio si adatta alle tue esigenze.<\/p>\n<p><\/p>\n<p><strong>Chiave di accesso (login)<\/strong> \u2014 specifichiamo il certificato che consente di connettersi all'istanza tramite SSH, se necessario.<\/p>\n<p><\/p>\n<p><strong>Impostazioni di rete<\/strong> \u2014 specifichiamo i parametri di rete. <strong>Piattaforma di networking<\/strong> nella maggior parte dei casi dovrebbe essere Virtual Private Cloud (VPC). <strong>Gruppi di sicurezza<\/strong> \u2014 gruppi di sicurezza per le tue istanze. Poich\u00e9 utilizzeremo un bilanciatore di carico davanti alle istanze, ti consiglio di specificare qui un gruppo che consenta solo le connessioni in entrata dal bilanciatore. Ci\u00f2 significa che avrai 2 gruppi di sicurezza, uno per il bilanciatore che consente le connessioni in entrata (inbound) da qualsiasi parte sulle porte 80 (http) e 443 (https), e un secondo per le macchine, che consente le connessioni in entrata su tutte le porte dal gruppo del bilanciatore. Le connessioni in uscita (outbound) in entrambi i gruppi devono essere aperte per il protocollo TCP su tutte le porte verso tutti gli indirizzi. \u00c8 possibile limitare le porte e gli indirizzi per le connessioni in uscita, ma in tal caso \u00e8 necessario monitorare costantemente di non tentare di accedere a porte chiuse.<\/p>\n<p><\/p>\n<p><strong>Archiviazione (volumi)<\/strong> \u2014 specifichiamo i parametri dei dischi per le macchine. La dimensione del disco non pu\u00f2 essere inferiore a quella specificata nell'AMI, per ECS Optimized \u2014 30 GiB.<\/p>\n<p><\/p>\n<p><strong>Dettagli avanzati<\/strong> \u2014 specifichiamo parametri aggiuntivi.<\/p>\n<p><\/p>\n<p><strong>Opzione di acquisto<\/strong> \u2014 vogliamo acquistare istanze spot. Vogliamo farlo, ma qui non segneremo questa casella, lo configureremo nel gruppo di scaling automatico, dove ci sono pi\u00f9 opzioni.<\/p>\n<p><\/p>\n<p><strong>Profilo istanza IAM<\/strong> \u2014 specifichiamo il ruolo con cui verranno avviate le istanze. Affinch\u00e9 le istanze funzionino in ECS, hanno bisogno dei permessi, che di solito si trovano nel ruolo <em>ecsInstanceRole<\/em>. In alcuni casi pu\u00f2 essere creato, se non c'\u00e8, qui <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/instance_IAM_role.html\">istruzioni<\/a><\/noindex> informazioni su come farlo. Dopo la creazione, lo specifichiamo nel modello.<br \/>\nDopo ci sono molti parametri, in genere si possono lasciare i valori predefiniti, ma ciascuno di essi ha una chiara descrizione. Attivo sempre i parametri istanza EBS-ottimizzata e T2\/T3 Unlimited, se sono utilizzati <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AWSEC2\/latest\/UserGuide\/burstable-performance-instances.html\">burstable<\/a><\/noindex> istanze.<\/p>\n<p><\/p>\n<p><strong>Dati utente<\/strong> \u2014 specifichiamo i dati utente. Modificheremo il file <code>\/etc\/ecs\/ecs.config<\/code>, in cui si trova la configurazione dell'agente ECS.<br \/>\nEsempio di come potrebbero apparire i dati utente:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">#!\/bin\/bash\necho ECS_CLUSTER=DemoApiClusterProd &gt;&gt; \/etc\/ecs\/ecs.config\necho ECS_ENABLE_SPOT_INSTANCE_DRAINING=true &gt;&gt; \/etc\/ecs\/ecs.config\necho ECS_CONTAINER_STOP_TIMEOUT=1m &gt;&gt; \/etc\/ecs\/ecs.config\necho ECS_ENGINE_AUTH_TYPE=docker &gt;&gt; \/etc\/ecs\/ecs.config\necho &quot;ECS_ENGINE_AUTH_DATA={&quot;registry.gitlab.com&quot;:{&quot;username&quot;:&quot;username&quot;,&quot;password&quot;:&quot;password&quot;}}&quot; &gt;&gt; \/etc\/ecs\/ecs.config<\/code><\/pre>\n<p><\/p>\n<p><code>ECS_CLUSTER=DemoApiClusterProd<\/code> \u2014 il parametro indica che l'istanza appartiene a un cluster con un nome specificato, cio\u00e8 questo cluster sar\u00e0 in grado di eseguire i propri task su questo server. Non abbiamo ancora creato un cluster, ma quando lo faremo utilizzeremo questo nome.<\/p>\n<p><\/p>\n<p><code>ECS_ENABLE_SPOT_INSTANCE_DRAINING=true<\/code> \u2014 il parametro indica che, quando si riceve un segnale di spegnimento dell'istanza spot, tutti i task su di essa devono essere messi in stato Draining.<\/p>\n<p><\/p>\n<p><code>ECS_CONTAINER_STOP_TIMEOUT=1m<\/code> \u2014 il parametro indica che, dopo aver ricevuto il segnale SIGINT, tutte le attivit\u00e0 hanno 1 minuto prima di essere terminate.<\/p>\n<p><\/p>\n<p><code>ECS_ENGINE_AUTH_TYPE=docker<\/code> \u2014 il parametro indica che viene utilizzato il meccanismo di autorizzazione docker.<\/p>\n<p><\/p>\n<p><code>ECS_ENGINE_AUTH_DATA=...<\/code> \u2014 parametri di connessione al registry privato dei container, dove sono memorizzate le tue immagini Docker. Se \u00e8 pubblico, non \u00e8 necessario indicare nulla.<\/p>\n<p><\/p>\n<p>In questo articolo utilizzer\u00f2 un'immagine pubblica da Docker Hub, quindi non indicher\u00f2 parametri. <code>ECS_ENGINE_AUTH_TYPE<\/code> e <code>ECS_ENGINE_AUTH_DATA<\/code> non \u00e8 necessario.<\/p>\n<p><\/p>\n<p><strong>\u00c8 utile sapere<\/strong>: si raccomanda di aggiornare regolarmente l'AMI, poich\u00e9 nelle nuove versioni si aggiornano le versioni di Docker, Linux, dell'agente ECS e altro. Per non dimenticarlo, puoi <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/ECS-AMI-SubscribeTopic.html\">configurare notifiche<\/a><\/noindex> per il rilascio di nuove versioni. Puoi ricevere notifiche via email e aggiornare manualmente, oppure puoi scrivere una funzione Lambda che creer\u00e0 automaticamente una nuova versione del Launch Template con l'AMI aggiornato.<\/p>\n<p><\/p>\n<h3 id=\"ec2-auto-scaling-group\"><strong>EC2 Auto Scaling Group<\/strong><\/h3>\n<p><\/p>\n<p>L'Auto Scaling Group \u00e8 responsabile dell'avvio e dello scaling delle istanze. La gestione dei gruppi avviene nella sezione EC2 -&gt; Auto Scaling -&gt; Auto Scaling Groups.<\/p>\n<p><\/p>\n<p><strong>Template di avvio<\/strong> \u2014 selezioniamo il template creato nel passaggio precedente. Manteniamo la versione predefinita.<\/p>\n<p><\/p>\n<p><strong>Opzioni di acquisto e tipi di istanza<\/strong> \u2014 indichiamo i tipi di istanza per il cluster. Adhere to launch template utilizza il tipo di istanza dal Launch Template. Combine purchase options and instance types consente di configurare flessibilmente i tipi di istanza. Lo utilizzeremo.<\/p>\n<p><\/p>\n<p><strong>Base On-Demand opzionale<\/strong> \u2014 il numero di istanze normali, non spot, che saranno sempre attive.<\/p>\n<p><\/p>\n<p><strong>Percentuale On-Demand sopra la base<\/strong> \u2014 la proporzione percentuale tra istanze normali e spot, 50-50 distribuisce equamente, 20-80 per ogni istanza normale verranno sollevate 4 istanze spot. In questo esempio indicher\u00f2 50-50, ma nella realt\u00e0 facciamo spesso 20-80 e, in alcuni casi, 0-100.<\/p>\n<p><\/p>\n<p><strong>Tipi di istanza<\/strong> \u2014 qui puoi specificare tipi aggiuntivi di istanze che saranno utilizzati nel cluster. Non li abbiamo mai usati, perch\u00e9 non ne comprendo molto il significato. Potrebbe essere una questione di limiti per tipi specifici di istanze, ma possono essere aumentati facilmente attraverso il supporto. Se conosci un'applicazione, sarei felice di leggerne nei commenti)<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/c1ee742d2059674f39a53cac6b9f2347.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Network\n   global\n   log \/dev\/log local0\n   log \/dev\/log local1 notice\n   chroot \/var\/lib\/haproxy\n   stats timeout 30s\n   user haproxy\n   group haproxy\n   daemon\n\ndefaults\n   log global\n   mode http\n   option httplog\n   option dontlognull\n   timeout connect 5000\n   timeout client 50000\n   timeout server 50000\n\nfrontend http_front\n   bind *:80\n   stats uri \/haproxy?stats\n   default_backend http_back\n\nbackend http_back\n   balance roundrobin\n   server server_name1 private_ip1:80 check\n   server server_name2 private_ip2:80 check<\/strong> \u2014 impostazioni di rete, scegli VPC e sottoreti per le macchine, nella maggior parte dei casi \u00e8 consigliabile selezionare tutte le sottoreti disponibili.<\/p>\n<p><\/p>\n<p><strong>Bilanciamento del carico<\/strong> \u2014 impostazioni del bilanciatore, ma lo faremo separatamente, qui non tocchiamo nulla. <strong>Controlli di salute<\/strong> saranno anche configurati pi\u00f9 tardi.<\/p>\n<p><\/p>\n<p><strong>Dimensione del gruppo<\/strong> \u2014 specifichiamo i limiti sul numero di macchine nel cluster e il numero desiderato di macchine all'avvio. Il numero di macchine nel cluster non diminuir\u00e0 mai sotto il numero minimo specificato e non superer\u00e0 il massimo, anche se le metriche richiederebbero un scaling.<\/p>\n<p><\/p>\n<p><strong>Politiche di scaling<\/strong> \u2014 parametri di scaling, ma scaleremo in base ai task ECS in esecuzione, quindi configureremo lo scaling pi\u00f9 tardi.<\/p>\n<p><\/p>\n<p><strong>Protezione dallo scaling delle istanze<\/strong> \u2014 protezione delle istanze dalla cancellazione durante lo scaling verso il basso. Attiviamo questa opzione per evitare che l'ASG elimini una macchina su cui sono presenti task attivi. Disattivare la protezione per le istanze senza task sar\u00e0 l'ECS Capacity Provider.<\/p>\n<p><\/p>\n<p><strong>Aggiungi tag<\/strong> \u2014 puoi specificare tag per le istanze (per questo deve essere selezionata l'opzione Tag new instances). Ti consiglio di indicare il tag Nome, cos\u00ec tutte le istanze avviate all'interno del gruppo avranno lo stesso nome, facilitandone la visualizzazione nella console.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/61fa0ccb38c11f61431db0938140efb7.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dopo aver creato il gruppo, aprilo e vai alla sezione Configurazioni avanzate, perch\u00e9 in fase di creazione non sono visibili tutte le opzioni nella console.<\/p>\n<p><\/p>\n<p><strong>Politiche di terminazione<\/strong> \u2014 regole considerate durante la cancellazione delle istanze. Vengono applicate in sequenza. Di solito utilizziamo quelle come nell'immagine qui sotto. Prima vengono eliminate le istanze con il Launch Template pi\u00f9 vecchio (ad esempio, se abbiamo aggiornato l'AMI, si \u00e8 creata una nuova versione, ma tutte le istanze sono riuscite a passarvi). Poi vengono selezionate le istanze pi\u00f9 vicine all'ora di fatturazione successiva. E infine vengono scelte le pi\u00f9 vecchie in base alla data di avvio.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/8236624fe08a03f36aedc7665e18b060.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>\u00c8 utile sapere<\/strong>: per aggiornare tutte le macchine nel cluster, \u00e8 comodo utilizzare <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/autoscaling\/ec2\/userguide\/asg-instance-refresh.html\">Aggiornamento dell'istanza<\/a><\/noindex>. Se combini questo con la funzione Lambda del passaggio precedente, avrai un sistema di aggiornamento completamente automatizzato per le istanze. Prima di aggiornare tutte le macchine, \u00e8 necessario disattivare la protezione dallo scale-in per tutte le istanze nel gruppo. Non la configurazione nel gruppo, ma proprio la protezione delle macchine stesse, che si effettua nella scheda Gestione delle istanze.<\/p>\n<p><\/p>\n<h3 id=\"application-load-balancer-i-ec2-target-group\">Application Load Balancer e EC2 Target Group<\/h3>\n<p><\/p>\n<p>Il bilanciatore viene creato nella sezione EC2 \u2192 Load Balancing \u2192 Load Balancers. Utilizzeremo l'Application Load Balancer, \u00e8 possibile leggere il confronto tra i diversi tipi di bilanciatori su <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/elasticloadbalancing\/features\/#compare\">pagina del servizio<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><strong>Listeners<\/strong> \u2014 ha senso impostare le porte 80 e 443 e fare un reindirizzamento da 80 a 443 tramite le regole del bilanciatore.<\/p>\n<p><\/p>\n<p><strong>Availability Zones<\/strong> \u2014 nella maggior parte dei casi scegliamo tutte le zone di disponibilit\u00e0.<\/p>\n<p><\/p>\n<p><strong>Configura le impostazioni di sicurezza<\/strong> \u2014 qui si indica il certificato SSL per il bilanciatore, l'opzione pi\u00f9 conveniente \u00e8 <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/acm\/latest\/userguide\/gs-acm-request-public.html\">creare un certificato<\/a><\/noindex> in ACM. Si possono leggere le differenze <strong>Security Policy<\/strong> nel <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/elasticloadbalancing\/latest\/classic\/elb-security-policy-table.html\">documentazione<\/a><\/noindex>, si pu\u00f2 lasciare quello predefinito <code>ELBSecurityPolicy-2016-08<\/code>. Dopo la creazione del bilanciatore, vedrai il suo <strong>nome DNS<\/strong>, per il quale \u00e8 necessario impostare un CNAME per il tuo dominio. Ad esempio, ecco come appare in Cloudflare.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/899ff0f30df4117fc0ccd91af135def3.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Gruppo di Sicurezza<\/strong> \u2014 creiamo o selezioniamo un gruppo di sicurezza per il bilanciatore, ho scritto pi\u00f9 in alto su questo nel paragrafo EC2 Launch Template \u2192 Impostazioni di rete.<\/p>\n<p><\/p>\n<p><strong>Gruppo target<\/strong> \u2014 creiamo un gruppo che gestisce il routing delle richieste dal bilanciatore alle macchine e ne verifica la disponibilit\u00e0, in modo da sostituirle in caso di problemi. <strong>Tipo target<\/strong> deve essere Instance, <strong>Protocollo<\/strong> e <strong>Porta<\/strong> qualsiasi, se utilizzi HTTPS per la comunicazione tra il bilanciatore e le istanze, \u00e8 necessario caricare il certificato su di esse. In questo esempio non lo faremo, lasceremo semplicemente la porta 80.<\/p>\n<p><\/p>\n<p><strong>Controlli di salute<\/strong> \u2014 parametri di verifica della funzionalit\u00e0 del servizio. Nel servizio attuale dovrebbe essere una richiesta separata, che implementa parti importanti della logica di business. In questo esempio, lascer\u00f2 le impostazioni predefinite. Successivamente, puoi scegliere l'intervallo delle richieste, il timeout, i codici delle risposte di successo, ecc. Nel nostro esempio indicheremo i codici di successo 200-399, poich\u00e9 l'immagine Docker che verr\u00e0 utilizzata restituisce il codice 304.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/e295ab1c3bf1dfe13c76b4942a31c7ee.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Registrare i Target<\/strong> \u2014 qui si scelgono le macchine per il gruppo, ma nel nostro caso ci\u00f2 sar\u00e0 gestito da ECS, quindi saltiamo semplicemente questo passaggio.<\/p>\n<p><\/p>\n<p><strong>\u00c8 utile sapere<\/strong>: a livello del bilanciatore puoi attivare i log, che verranno salvati in S3 in un file specifico <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/elasticloadbalancing\/latest\/application\/load-balancer-access-logs.html\">in formato<\/a><\/noindex>. Da l\u00ec possono essere esportati in servizi esterni per l'analisi, oppure \u00e8 possibile eseguire query SQL direttamente sui dati in S3 con <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/athena\/latest\/ug\/application-load-balancer-logs.html\">l'aiuto di Athena<\/a><\/noindex>. \u00c8 comodo e funziona senza alcun codice aggiuntivo. Consiglio anche di impostare l'eliminazione dei log dal bucket S3 dopo un periodo di tempo definito.<\/p>\n<p><\/p>\n<h3 id=\"ecs-task-definition\">Definizione del Compito ECS<\/h3>\n<p><\/p>\n<p>Nei passaggi precedenti abbiamo creato tutto quello che riguarda l'infrastruttura del servizio, ora passiamo alla descrizione dei container che andremo a lanciare. Questo si fa nella sezione ECS \u2192 Definizioni dei Compiti.<\/p>\n<p><\/p>\n<p><strong>Compatibilit\u00e0 del tipo di avvio<\/strong> \u2014 scegliamo EC2.<\/p>\n<p><\/p>\n<p><strong>Ruolo IAM per l'esecuzione del compito<\/strong> \u2014 selezioniamo <code>ecsTaskExecutionRole<\/code>. Con questo vengono scritti i log, viene fornito accesso a variabili segrete, ecc.<\/p>\n<p><\/p>\n<p>Nella sezione Definizioni del Container facciamo clic su Aggiungi Container.<\/p>\n<p><\/p>\n<p><strong>Immagine<\/strong> \u2014 link all'immagine con il codice del progetto, per questo esempio user\u00f2 un'immagine pubblica da Docker Hub <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/bitnami\/node-example\">bitnami\/node-example:0.0.1<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><strong>Limiti di Memoria<\/strong> \u2014 limiti della memoria per il container. <strong>Limite Rigido<\/strong> \u2014 limite rigido, se il container supera il valore specificato, verr\u00e0 eseguita il comando docker kill, il container morir\u00e0 immediatamente. <strong>Limite Morbido<\/strong> \u2014 limite morbido, il container pu\u00f2 superare il valore specificato, ma questo parametro sar\u00e0 preso in considerazione quando si pianificano i compiti sulle macchine. Ad esempio, se una macchina ha 4 GiB di RAM e il limite morbido del container \u00e8 2048 MiB, allora su quella macchina possono esserci al massimo 2 task attivi con questo container. In realt\u00e0, 4 GiB di RAM \u00e8 un po' meno di 4096 MiB, questo pu\u00f2 essere verificato nella scheda ECS Instances nel cluster. Il limite morbido non pu\u00f2 essere maggiore del limite rigido. \u00c8 importante capire che se in un task ci sono pi\u00f9 container, i loro limiti si sommano.<\/p>\n<p><\/p>\n<p><strong>Mappature delle porte<\/strong> \u2014 in <strong>Porta Host<\/strong> impostiamo 0, questo significa che la porta sar\u00e0 assegnata dinamicamente, sar\u00e0 monitorata dal Target Group. <strong>Porta del Container<\/strong> \u2014 la porta su cui gira la vostra applicazione, spesso \u00e8 specificata nel comando di esecuzione, oppure viene assegnata nel codice della vostra applicazione, Dockerfile, ecc. Per il nostro esempio utilizziamo 3000, poich\u00e9 \u00e8 specificato nell' <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/bitnami\/bitnami-docker-node\/blob\/master\/example\/Dockerfile\">Dockerfile<\/a><\/noindex> immagine utilizzata.<\/p>\n<p><\/p>\n<p><strong>Controllo della salute<\/strong> \u2014 parametri per il controllo del funzionamento del container, da non confondere con quello impostato nel Target Group.<\/p>\n<p><\/p>\n<p><strong>Ambiente<\/strong> \u2014 impostazioni dell'ambiente. <strong>unit\u00e0 CPU<\/strong> \u2014 sembra che sia simile ai limiti di memoria, ma riguarda la CPU. Ogni core della CPU equivale a 1024 unit\u00e0, quindi se il server ha una CPU dual-core e il container ha un valore impostato a 512, possono essere eseguite 4 attivit\u00e0 con quel container su uno stesso server. Le unit\u00e0 CPU corrispondono sempre al numero di core, non possono essere inferiori come nel caso della memoria.<\/p>\n<p><\/p>\n<p><strong>Comando<\/strong> \u2014 comando per avviare il servizio all'interno del container, tutti i parametri sono separati da virgole. Pu\u00f2 essere gunicorn, npm, ecc. Se non specificato, verr\u00e0 utilizzato il valore della direttiva CMD dal Dockerfile. Indichiamo <code>npm,start<\/code>.<\/p>\n<p><\/p>\n<p><strong>Variabili d'ambiente<\/strong> \u2014 variabili d'ambiente del container. Possono essere semplici dati testuali o variabili riservate da <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/specifying-sensitive-data-secrets.html\">Secrets Manager<\/a><\/noindex> o <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/specifying-sensitive-data-parameters.html\">Parameter Store<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><strong>Archiviazione e Registrazione<\/strong> \u2014 qui configureremo la registrazione su CloudWatch Logs (servizio di logging di AWS). Per farlo, basta abilitare l'opzione Auto-configure CloudWatch Logs. Dopo la creazione della Task Definition, verr\u00e0 automaticamente creata un gruppo di log in CloudWatch. Per impostazione predefinita, i log vengono conservati indefinitamente, consiglio di cambiare il periodo di conservazione da Never Expire al termine desiderato. Questo si fa nel gruppo di log di CloudWatch, \u00e8 necessario cliccare sul periodo attuale e scegliere il nuovo.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/c9ad7ca39dfde9343be89eb9ab1aef10.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h3 id=\"ecs-cluster-i-ecs-capacity-provider\">Cluster ECS e Provider di Capacit\u00e0 ECS<\/h3>\n<p><\/p>\n<p>Andiamo alla sezione ECS \u2192 Clusters per creare un cluster. Come modello, scegliamo EC2 Linux + Networking.<\/p>\n<p><\/p>\n<p><strong>Nome del cluster<\/strong> \u2014 molto importante, qui diamo lo stesso nome indicato nel Launch Template nel parametro <code>ECS_CLUSTER<\/code>, nel nostro caso \u2014 <code>DemoApiClusterProd<\/code>. Spuntiamo l'opzione Crea un cluster vuoto. Facoltativamente, \u00e8 possibile abilitare Container Insights per monitorare le metriche dei servizi in CloudWatch. Se hai fatto tutto correttamente, nella sezione ECS Instances vedrai le macchine create nel gruppo di Auto Scaling.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/cd70062c9783ae359a2b27cbfc66cbe3.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Andiamo alla scheda <strong>Capacity Providers<\/strong> e creiamo un nuovo. Ricordo che \u00e8 necessario per gestire la creazione e lo spegnimento delle macchine in base al numero di attivit\u00e0 ECS in esecuzione. \u00c8 importante notare che il provider pu\u00f2 essere collegato solo a un gruppo.<\/p>\n<p><\/p>\n<p><strong>Auto Scaling group<\/strong> \u2014 scegliamo il gruppo creato in precedenza.<\/p>\n<p><\/p>\n<p><strong>Scaling gestito<\/strong> \u2014 attiviamo per consentire al provider di scalare il servizio.<\/p>\n<p><\/p>\n<p><strong>Capacit\u00e0 target %<\/strong> \u2014 quale percentuale di utilizzo delle macchine desideriamo per i task. Se impostiamo il 100%, tutte le macchine saranno sempre occupate da task attivi. Se impostiamo il 50%, la met\u00e0 delle macchine sar\u00e0 sempre libera. In questo caso, se si verifica un improvviso aumento del carico, i nuovi task verranno immediatamente assegnati alle macchine disponibili, senza dover aspettare il deployment delle istanze.<\/p>\n<p><\/p>\n<p><strong>Protezione da terminazione gestita<\/strong> \u2014 attiviamo, questo parametro consente al fornitore di rimuovere la protezione delle istanze dalla cancellazione. Ci\u00f2 avviene quando non ci sono task attivi sulla macchina e consente di rispettare la percentuale di capacit\u00e0 target.<\/p>\n<p><\/p>\n<h3 id=\"ecs-service-i-nastroyka-masshtabirovaniya\">Servizio ECS e impostazione della scalabilit\u00e0<\/h3>\n<p><\/p>\n<p>Ultimo passo :) Per creare un servizio, \u00e8 necessario accedere al cluster precedentemente creato nella scheda Servizi.<\/p>\n<p><\/p>\n<p><strong>Tipo di avvio<\/strong> \u2014 dobbiamo cliccare su Passa alla strategia del fornitore di capacit\u00e0 e selezionare i fornitori creati in precedenza.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/9d9dfdd8e333cce24bfb048ac84097e4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Definizione del task<\/strong> \u2014 selezioniamo la Definizione del task creata in precedenza e la sua revisione.<\/p>\n<p><\/p>\n<p><strong>Nome del servizio<\/strong> \u2014 per evitare confusioni, indichiamo sempre lo stesso nome della Definizione del task.<\/p>\n<p><\/p>\n<p><strong>Tipo di servizio<\/strong> \u2014 sempre Replica.<\/p>\n<p><\/p>\n<p><strong>Numero di task<\/strong> \u2014 numero desiderato di task attivi nel servizio. Questo parametro \u00e8 gestito dalla scalabilit\u00e0, ma deve comunque essere specificato.<\/p>\n<p><\/p>\n<p><strong>Percentuale di salute minima<\/strong> e <strong>Percentuale massima<\/strong> \u2014 definiscono il comportamento dei task durante il deployment. I valori predefiniti di 100 e 200 indicano che durante il deployment il numero di task aumenter\u00e0 di un fattore, per poi tornare al desiderato. Se si utilizza 1 task, min=0 e max=100, esso verr\u00e0 terminato durante il deployment e un nuovo task verr\u00e0 avviato, quindi ci sar\u00e0 un'interruzione. Se \u00e8 attivo 1 task, min=50 e max=150, il deployment non avverr\u00e0 affatto, poich\u00e9 non \u00e8 possibile dividere un task in due o aumentarlo di un fattore e mezzo.<\/p>\n<p><\/p>\n<p><strong>Tipo di deployment<\/strong> \u2014 lasciamo Aggiornamento continuo.<\/p>\n<p><\/p>\n<p><strong>Modelli di posizionamento<\/strong> \u2014 regole di posizionamento dei task sulle macchine. Per impostazione predefinita \u00e8 impostato su AZ Balanced Spread - ci\u00f2 significa che ogni nuovo task sar\u00e0 collocato su una nuova istanza fino a quando non verranno attivate macchine in tutte le zone di disponibilit\u00e0. Di solito utilizziamo BinPack - CPU e Spread - AZ, in questa politica i task vengono allocati il pi\u00f9 densamente possibile su una macchina in base alla CPU. Quando \u00e8 necessario creare una nuova macchina, essa viene creata in una nuova zona di disponibilit\u00e0.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/6430bdf046fc5b970e0afbbf0d9ef65e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Tipo di bilanciatore di carico<\/strong> \u2014 selezioniamo il Bilanciatore di carico applicativo.<\/p>\n<p><\/p>\n<p><strong>Ruolo IAM del servizio<\/strong> \u2014 selezioniamo <code>ecsServiceRole<\/code>.<\/p>\n<p><\/p>\n<p><strong>Nome del bilanciatore di carico<\/strong> \u2014 selezioniamo il bilanciatore di carico creato in precedenza.<\/p>\n<p><\/p>\n<p><strong>Periodo di grazia per il controllo di integrit\u00e0<\/strong> \u2014 pausa prima di eseguire i controlli di integrit\u00e0 dopo il rilascio di un nuovo task, di solito impostiamo 60 secondi.<\/p>\n<p><\/p>\n<p><strong>Contenitore da bilanciare<\/strong> \u2014 nel campo Nome gruppo target selezioniamo il gruppo creato in precedenza e tutto si compiler\u00e0 automaticamente.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/c067868ff73c25c3d9b65e02be64f5c9.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Auto Scaling del servizio<\/strong> \u2014 parametri di scaling del servizio. Selezioniamo Configura Auto Scaling del servizio per regolare il conteggio desiderato del tuo servizio. Impostiamo il numero minimo e massimo di task durante il scaling.<\/p>\n<p><\/p>\n<p><strong>Ruolo IAM per Auto Scaling del servizio<\/strong> \u2014 selezioniamo <code>AWSServiceRoleForApplicationAutoScaling_ECSService<\/code>.<\/p>\n<p><\/p>\n<p><strong>Politiche di scaling automatico dei task<\/strong> \u2014 regole per il scaling. Ci sono 2 tipi:<\/p>\n<p><\/p>\n<ol>\n<li><strong>Monitoraggio del target<\/strong> \u2014 monitoraggio di una metrica target (utilizzo di CPU\/RAM o numero di richieste per ogni task). Ad esempio, vogliamo che il carico medio della CPU sia dell'85%, quando supera questa soglia, verranno aggiunti nuovi task fino a raggiungere il valore target. Se il carico \u00e8 inferiore, i task verranno invece rimossi, a meno che non sia attivata la protezione dallo scaling verso il basso (<strong>Disabilita scaling verso il basso<\/strong>).<\/li>\n<li><strong>Scaling a step<\/strong> \u2014 reazione a un evento casuale. Qui puoi impostare la risposta a qualsiasi evento (Allerta CloudWatch), quando si verifica, puoi aggiungere o rimuovere un numero specificato di task, oppure indicare un numero esatto di task.<\/li>\n<\/ol>\n<p><\/p>\n<p>Il servizio pu\u00f2 avere pi\u00f9 regole di scaling, il che pu\u00f2 essere utile; \u00e8 importante assicurarsi che non conflittino tra loro.<\/p>\n<p><\/p>\n<h2 id=\"zaklyuchenie\">Conclusione<\/h2>\n<p><\/p>\n<p>Se hai seguito le istruzioni e utilizzato la stessa immagine Docker, il tuo servizio dovrebbe restituire questa pagina.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creazione di un&#039;API scalabile su istanze spot di AWS\" src=\"\/wp-content\/uploads\/2020\/07\/ac592e3194480ac8b347a3a1faf0cee0.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ol>\n<li>Abbiamo creato un modello secondo cui tutte le macchine nel servizio vengono avviate. Abbiamo anche imparato ad aggiornare le macchine quando il modello viene modificato.<\/li>\n<li>Abbiamo impostato la gestione del segnale di arresto per le istanze spot, quindi entro un minuto dalla ricezione, tutti i task in esecuzione vengono rimossi dalla macchina, in questo modo nulla viene perso o interrotto.<\/li>\n<li>Abbiamo avviato un bilanciatore di carico per distribuire uniformemente il carico tra le macchine.<\/li>\n<li>Abbiamo creato un servizio che funziona su istanze spot, riducendo cos\u00ec i costi delle macchine di circa 3 volte.<\/li>\n<li>Abbiamo configurato l'auto scaling in entrambe le direzioni per gestire l'aumento del carico, ma allo stesso tempo non pagare per inattivit\u00e0.<\/li>\n<li>Utilizziamo il Capacity Provider affinch\u00e9 l'applicazione gestisca l'infrastruttura (macchine) e non viceversa.<\/li>\n<li>Siamo dei bravi.<\/li>\n<\/ol>\n<p><\/p>\n<p>Se hai picchi di carico prevedibili, ad esempio, se fai pubblicit\u00e0 in una grande newsletter via email, puoi impostare lo scaling in base a <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/autoscaling\/application\/userguide\/application-auto-scaling-scheduled-scaling.html\">un programma<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>\u00c8 possibile anche eseguire la scalabilit\u00e0 basata sui dati provenienti da diverse parti del sistema. Ad esempio, abbiamo una funzionalit\u00e0 <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.adapty.io\/promo-campaigns\">di invio di promozioni individuali<\/a><\/noindex> agli utenti dell'app mobile. A volte la campagna viene inviata a oltre 1 milione di persone. Dopo tale invio, si osserva sempre un grande aumento delle richieste all'API, poich\u00e9 molti utenti accedono all'app contemporaneamente. Quindi, se vediamo che ci sono molte pi\u00f9 richieste nella coda per l'invio di notifiche promozionali rispetto ai valori standard, possiamo immediatamente avviare diverse macchine e task aggiuntivi per essere pronti al carico.<\/p>\n<p><\/p>\n<p>Sarei felice se nei commenti condivideste interessanti casi d'uso delle istanze spot e ECS o qualcosa sulla scalabilit\u00e0.<\/p>\n<p><\/p>\n<p>Presto ci saranno articoli su come gestiamo migliaia di eventi analitici al secondo su uno stack principalmente serverless (con risorse finanziarie) e su come \u00e8 strutturato il deployment dei servizi tramite GitLab CI e Terraform Cloud.<\/p>\n<p><\/p>\n<p>Iscriviti a noi, sar\u00e0 interessante!<\/p>\n<p class=\"for_users_only_msg\">Solo gli utenti registrati possono partecipare al sondaggio. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Accedi<\/a><\/noindex>, per favore.<\/p>\n<h2 class=\"default-block__polling-title\">Utilizzate le istanze spot in produzione?<\/h2>\n<ul class=\"poll-result\">\n<li class=\"poll-result__item\">\n<p>                <strong class=\"poll-result__data-percent\">22,2%<\/strong>S\u00ec6<\/p>\n<\/li>\n<li class=\"poll-result__item\">\n<p>                <strong class=\"poll-result__data-percent  poll-result__data-percent_winner\">66,7%<\/strong>No18<\/p>\n<\/li>\n<li class=\"poll-result__item\">\n<p>                <strong class=\"poll-result__data-percent\">11,1%<\/strong>Ne ho sentito parlare in un articolo, ho intenzione di utilizzarle<\/p>\n<\/li>\n<\/ul>\n<p>    Hanno votato 27 utenti. Si sono astenuti 5 utenti.<br \/>\n<br \/>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/509790\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041a\u0438\u0440\u0438\u043b\u043b, \u044f CTO \u0432 Adapty. \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 AWS, \u0438 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u043b\u0438 \u0440\u0430\u0441\u0445\u043e\u0434\u044b \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 3 \u0440\u0430\u0437\u0430 \u0437\u0430 \u0441\u0447\u0451\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u043e\u0442\u043e\u0432\u044b\u0445 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u043e\u0432 \u043d\u0430 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u0445 \u0430\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0437\u043e\u0440 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0430 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":87394,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-87393","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041a\u0438\u0440\u0438\u043b\u043b, \u044f CTO \u0432 Adapty.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e API \u043d\u0430 \u0441\u043f\u043e\u0442\u043e\u0432\u044b\u0445 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430\u0445 AWS | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041a\u0438\u0440\u0438\u043b\u043b, \u044f CTO \u0432 Adapty.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-07-07T23:42:02+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-07-07T23:42:02+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Creazione di un'API scalabile su istanze spot AWS | ProHoster","description":"Ciao a tutti! Mi chiamo Kirill, sono CTO in Adapty.","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e API \u043d\u0430 \u0441\u043f\u043e\u0442\u043e\u0432\u044b\u0445 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430\u0445 AWS | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041a\u0438\u0440\u0438\u043b\u043b, \u044f CTO \u0432 Adapty.","og:url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-07-07T23:42:02+00:00","article:modified_time":"2020-07-07T23:42:02+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"87393","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:44:41","updated":"2022-09-28 14:12:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/87393","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=87393"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/87393\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/87394"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=87393"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=87393"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=87393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}