Managed Queues: autoscaling dei queue worker su Laravel Cloud | Laravel - Lo stack pulito per Artisans e agent
Ci sono tre cose che ogni utente dovrebbe ottenere dalla propria infrastruttura di elaborazione dei job in background. Primo, i job dovrebbero essere eseguiti in modo affidabile senza richiedere attenzione costante. Secondo, quando qualcosa fallisce, dovresti poterlo vedere immediatamente e risolverlo senza escalation al team di engineering. E terzo, quando le tue code sono vuote, non dovresti pagare per compute inattivo.
La funzionalità managed queues di Laravel Cloud affronta tutti e tre gli aspetti. Ogni applicazione Laravel Cloud può eseguire queue worker in isolamento rispetto al cluster dell'applicazione, che scalano in base a diversi fattori, tra cui il numero di job in attesa e l'età dei messaggi. I worker poi scendono a zero quando non c'è più nulla da elaborare, riducendo i costi.
Quando arrivano i job, i worker si risvegliano in meno di un secondo, mantenendo veloci anche le applicazioni più sensibili alla latenza. Non c'è alcun compromesso tra costo e velocità.
Cosa volevamo risolvere
I clienti che eseguivano job in background su Laravel Cloud continuavano a incontrare lo stesso insieme di problemi, e questo feedback ha plasmato ogni decisione presa durante la realizzazione delle managed queues.
Il nostro precedente tentativo di risolvere i job di lunga durata, i queue cluster, si scontrava con i seguenti problemi:
- Eseguire le code su larga scala era imprevedibile. I clienti avevano bisogno di una base più affidabile in grado di gestire job non uniformi per dimensione.
- La profondità della coda non poteva essere misurata in modo indipendente. Cloud doveva passare attraverso l'applicazione per leggere le metriche di profondità. Le applicazioni a basso traffico mantenevano i worker in esecuzione anche quando le code erano vuote.
- Lo scaling aggiungeva capacità inutilizzata. Più worker erano stipati in un singolo pod, scalando all'interno di quel pod fino a raggiungerne la capacità, per poi provisionare un nuovo pod e ripetere il ciclo. Gli utenti pagavano per capacità che non avevano ancora utilizzato.
- I job falliti erano invisibili. I clienti non potevano visualizzare i job falliti, dovendo scavare nei log per scoprire cosa fosse successo.
Managed Queues: un nuovo modo di eseguire job in background
Managed queues è una ricostruzione da zero che risolve ognuno di questi problemi.
Quando le code sono vuote, i worker scendono a zero. Quando arrivano i job, i worker riscalano in base a quanti sono in attesa e da quanto tempo lo sono. Paghi per il compute e per le operazioni di coda che sono state eseguite, non per la capacità che hai riservato.
- Worker isolati: i worker girano separatamente dal cluster dell'applicazione, così i job in background non competono mai con il traffico web.
- Autoscaling basato sulla pressione della coda: Cloud scala i worker man mano che i job si accumulano e li riporta a zero quando la coda si svuota.
- Pausa e purge: La pausa interrompe l'elaborazione senza perdere job. Il purge svuota completamente la coda.
- Dashboard delle code: una vista in tempo reale del volume dei job, della durata, della memoria media utilizzata e del numero di repliche. I job falliti emergono con tutti i dettagli e puoi approfondire per capire perché un job è fallito e riprovarlo con un clic.
Per la prima volta su Laravel Cloud, i team possono vedere esattamente cosa è fallito, capire perché e recuperare senza interrogare un database. Un membro del team di supporto che gestisce una segnalazione su un'email mancante o un export fallito può indagare e riprovare direttamente dalla dashboard.
Miglioramenti delle managed queues dal lancio
Risolvere i cold start
Avviare un nuovo pod Kubernetes richiedeva circa 30 secondi, il che rendeva lo scaling a zero doloroso per le applicazioni sensibili alla latenza. I team mantenevano un worker caldo in esecuzione solo per evitare l'attesa, vanificando proprio il senso dello scale to zero.
Ora i worker inattivi dormono invece di spegnersi, e si risvegliano in meno di un secondo — 30 volte più velocemente di prima — quando arriva un job, misurato dal dispatch del job all'esecuzione dello stesso da parte del worker. Lo scale to zero è ora la scelta predefinita, non un compromesso che fai per risparmiare denaro.
Un'altra modifica riguarda il fatto che prima ogni worker controllava SQS per conto proprio per vedere se c'erano nuovi job in attesa, a intervalli che i clienti dovevano calibrare. Ora è stato sostituito da una flotta condivisa di poller che monitora SQS per conto dell'applicazione e spinge i job ai worker non appena arrivano. Non c'è alcun intervallo da configurare e il prelievo è più rapido in pratica rispetto al vecchio polling per-worker.
Impostare un numero minimo di worker
Se non vuoi mai vedere un cold start su una coda specifica, ora puoi impostare un numero minimo di worker che restano attivi in ogni momento. Assegna a una coda un minimo di uno, e avrà sempre un worker caldo e pronto. Assegna a una coda critica un minimo di 500, e il traffico a burst verrà elaborato nell'istante in cui arriva.
Il minimo stabilisce il livello base; l'algoritmo di autoscaling continua comunque ad adattarsi fino al massimo in base alla pressione della coda in tempo reale.
Code FIFO e come abilitano la consegna ordinata
Con l'introduzione delle code FIFO, sono disponibili due tipi di coda.
In una coda Standard, i job vengono elaborati all'incirca nell'ordine in cui arrivano, ma la coda può occasionalmente consegnarli fuori ordine o più di una volta. Va bene per la maggior parte del lavoro in background, ma non per i casi in cui l'ordine conta.
Se un cliente aggiorna il proprio indirizzo di spedizione e poi effettua un ordine, non vuoi che questi due job vengano elaborati nella sequenza sbagliata. Se un ledger registra un deposito e un prelievo, riprodurli fuori ordine cambia il saldo.
Le code FIFO garantiscono che i job siano consegnati esattamente una volta e nell'esatto ordine in cui sono stati inviati (first in, first out). Usale per workload come l'elaborazione dei pagamenti, gli aggiornamenti di ledger o qualsiasi sequenza di eventi in cui sbagliare l'ordine corromperebbe lo stato.
I nomi delle code FIFO ricevono il suffisso .fifo, il tipo di coda è fisso una volta creata e la modalità high-throughput è attiva per impostazione predefinita.
Override di scaling programmati
Se sai che il carico della coda aumenterà in un momento specifico, come l'elaborazione notturna dei feed, un'importazione batch programmata o una finestra promozionale, ora puoi creare regole di scaling basate su cron per portare i worker in anticipo, prima che la domanda arrivi.
Imposta una schedulazione, definisci l'intervallo min/max per quella finestra e scegli il fuso orario. Quando la finestra si chiude, lo scaling torna alla normalità.
Creazione di code indipendente e zero-config
Ogni coda ha il proprio compute, i propri worker e le proprie impostazioni di scaling come prima, ma crearne una richiede solo un nome, un tipo, una dimensione e un intervallo di autoscaling. Una scheda Advanced espone gli override per i team che ne hanno bisogno.
Azioni in blocco sui job falliti
Ora puoi riprovare o eliminare i job falliti su un'intera coda invece di gestirli uno alla volta.
Se stai già usando le managed queues, puoi accedere a questi miglioramenti eseguendo composer update e facendo il deploy.
Come abbiamo costruito le managed queues
Costruire le managed queues ha significato ripensare le assunzioni precedenti fatte con le soluzioni queue cluster. Ecco cosa è cambiato e perché.
Possedere la coda
La decisione più rilevante è stata rendere Laravel Cloud il queue driver. Con i queue cluster, supportare qualsiasi queue driver significava affidarsi all'applicazione dell'utente per leggere le metriche di profondità. "Avevamo bisogno di usare la loro applicazione Laravel per ottenere metriche come la profondità", afferma Kieran Brown, Senior Software Engineer del team infrastruttura di Laravel.
Possedere le code elimina completamente questa dipendenza. Cloud legge la profondità direttamente da SQS, indipendentemente dal fatto che l'applicazione del cliente sia in salute.
Un worker, un pod
I queue cluster stipavano più worker in un singolo pod. Quando un worker esauriva la memoria, faceva crashare il pod e tutto ciò che vi girava accanto.
Le managed queues eseguono ogni worker nel proprio pod Kubernetes isolato. Un worker configurato per 512 MB ottiene esattamente quello, garantito, senza nient'altro che condivida l'allocazione. "Non c'è più nulla che gira insieme", spiega Kieran. "Ogni singolo worker di managed queue gira nel proprio pod isolato, il che significa che possiamo garantire quelle allocazioni di risorse". Il fallimento di un worker non può influire su un altro.
Anche lo scaling orizzontale ha cambiato il modello di costo. Prima, scalare orizzontalmente significava provisionare un cluster completamente nuovo per eseguire un solo worker aggiuntivo. Con le managed queues, ogni nuovo worker è un pod a sé. Questo significa che lo scaling aggiunge incrementi da 256 MB, non da 4 GB.
Ottenere la formula di scaling corretta
La parte più difficile nella costruzione delle managed queues, e una che continueremo a perfezionare, è l'algoritmo di scaling stesso. La sola profondità della coda non è un segnale sufficiente. Cinque job in una coda sembrano gestibili finché ognuno non richiede due minuti di elaborazione. "Se guardi solo la profondità della coda, potresti far partire un solo worker, ma la tua coda impiegherebbe un'eternità", osserva Kieran. "Se ogni job richiede da 60 secondi a due minuti, anche con soli cinque messaggi, stai guardando dieci minuti o più per svuotarla".
Questa sfida è stata risolta sostituendo le euristiche basate sulla profondità della coda con un nuovo algoritmo di scaling che pesa la pressione della coda e il runtime medio dei job, tra gli altri criteri, e può scalare da 1 worker a 10 nel momento in cui rileva che il lavoro non verrà smaltito abbastanza velocemente. Non c'è nulla da calibrare per i clienti e il prelievo è più rapido in pratica rispetto al vecchio approccio basato sulla profondità della coda.
Compute Flex e Pro
Laravel Cloud ora ha due classi di coda per adattare il comportamento dei worker al tuo workload.
Flex è quella predefinita. Scala a zero, si risveglia in meno di un secondo e gira su hardware spot-backed in dimensioni da 256 MB a 2 GB. È pensata per lavoro a picchi o prevalentemente inattivo, e costa quanto costa oggi il compute delle managed queue.
Pro resta sempre attiva senza cold start, gira su hardware on-demand e supporta dimensioni fino a 8 GB (16 GB negli ambienti dedicati). Gestisce runtime dei job di circa un'ora, con il visibility timeout esteso automaticamente quando un job dura a lungo. Questa estensione automatica è disponibile anche su Flex, così un job che occasionalmente dura a lungo non fallisce solo perché è scalato da zero.
Flex è disponibile su tutti i piani. Pro è disponibile da Growth in su.
A chi sono destinate le managed queues?
Le managed queues sono progettate per scalare dalla più piccola applicazione hobby ai workload enterprise.
Hobby e side project: Su Flex, i worker scalano a zero insieme al resto della tua applicazione. Metti in pausa un progetto per qualche giorno e non paghi per il compute dei worker inattivi mentre resta intoccato.
Applicazioni con carico variabile o a burst: Se la tua applicazione ha bisogno di un'elevata concorrenza di worker per una frazione del mese, paghi per quelle ore, non per capacità continua provisionata per gestire il picco di carico. Le managed queues si adattano automaticamente e fatturano di conseguenza.
Team con più tipi di job: Ogni nome di coda Laravel ottiene la propria managed queue con configurazione indipendente. Una piccola allocazione di compute gestisce le email transazionali. Una più grande gestisce l'elaborazione video o la generazione di report. Ogni coda sceglie anche la propria classe di compute, così le email transazionali possono girare su Flex e scendere a zero quando sono inattive, mentre un generatore di report resta caldo su Pro.
Applicazioni enterprise su larga scala: I clienti su larga scala stanno già eseguendo managed queues con più di 1.000 repliche massime, e i piani Growth ora possono scalare fino a 100 worker per coda, rispetto ai 25 precedenti. A quella scala, le managed queues non riguardano solo il costo; si tratta di scaricare completamente il lavoro operativo della gestione dell'infrastruttura delle code. Dimensionare correttamente i worker, fare debug dei fallimenti su milioni di job e mantenere un throughput sano richiede tempo di engineering reale che ora Cloud gestisce per te.
Prezzi delle Managed Queues
Le managed queues sono fatturate al secondo più per milione di operazioni di coda.
| Piano | Starter | Growth | Business |
|---|---|---|---|
| Worker massimi per coda | 3 | 100 | Illimitati |
| Code per ambiente | 1 | 10 | Illimitate |
Inizia
Le managed queues sono ora disponibili su Laravel Cloud. Apri la tua dashboard di Laravel Cloud e seleziona la tua applicazione per creare la tua prima managed queue. Se non sei ancora un utente Cloud, puoi iniziare con 5 $ di crediti di utilizzo gratuiti.
Se stavi già usando le managed queues e vuoi accedere ai nuovi miglioramenti, esegui composer update e fai il deploy.
I dettagli completi della configurazione sono nella documentazione delle managed queues.
Altri articoli recenti
Laravel AI 1.1 e 1.2: Agent Skills, Cohere e structured output più solidi
Le release 1.1.0 e 1.2.0 di laravel/ai portano gli Agent Skills, l'approvazione obbligatoria per i tool built-in e nuovi provider come Cohere e Laya self-hosted. Sul fronte qualità arrivano i fix allo structured output per Bedrock e il supporto alle provider options. Aggiornati anche i modelli di default, con Claude 4.7+ che ignora i sampling params.
Laravel 13.35.0: scheduler più controllabile, code più flessibili e response Markdown
Laravel 13.35.0 porta Schedule::alwaysOnOneServer(), il supporto a schedule:interrupt per i comandi di lunga durata, --memory in percentuale per queue:work e il nuovo metodo markdown() sulla response factory. Tante piccole migliorie anche a test, view compilate in parallelo e dischi local.
BashBox: un interprete Bash in sandbox per agenti AI in PHP
BashBox è un interprete bash scritto in puro PHP che permette di eseguire gli script generati dagli agenti AI senza mai ricorrere a proc_open, exec o shell_exec. Ogni comando è una classe PHP che lavora su un filesystem virtuale, con limiti di esecuzione, quote disco e accesso di rete configurabili. Ideale per chi sviluppa agenti con il Laravel AI SDK o altre librerie simili.