Condividi tramite


Gestire i problemi di limitazione (429 - Errori "Troppe richieste") in App per la logica di Azure

Si applica a: App per la logica di Azure (consumo + Standard)

Se il flusso di lavoro dell'app per la logica sperimenta la limitazione, che si verifica quando il numero di richieste supera la frequenza in cui la destinazione può gestire in un intervallo di tempo specifico, viene visualizzato l'errore "HTTP 429 Troppo molte richieste". La limitazione può creare problemi come l'elaborazione dei dati ritardata, la riduzione della velocità delle prestazioni e gli errori, ad esempio il superamento dei criteri di ripetizione dei tentativi specificati.

Ad esempio, l'azione SQL Server seguente in un flusso di lavoro Consumo mostra un errore 429, che segnala un problema di limitazione:

Screenshot che mostra un flusso di lavoro Consumo con un'azione SQL Server con un errore 429.

Le sezioni seguenti descrivono i livelli comuni in cui il flusso di lavoro potrebbe sperimentare la limitazione:

Limitazione delle risorse dell'app per la logica

App per la logica di Azure ha i propri limiti di velocità effettiva. Se la risorsa dell'app per la logica supera questi limiti, la risorsa dell'app per la logica viene limitata, non solo un'istanza o un'esecuzione del flusso di lavoro specifici.

Per trovare eventi di limitazione a questo livello, seguire questa procedura:

  1. Nella portale di Azure aprire la risorsa dell'app per la logica.

  2. Nel menu delle risorse dell'app per la logica selezionare Metriche in Monitoraggio.

  3. In Titolo grafico selezionare Aggiungi metrica, che aggiunge un'altra barra delle metriche al grafico.

  4. Nella prima barra delle metriche, nell'elenco Metriche selezionare Eventi con limitazione delle azioni. Nell'elenco Aggregazioni selezionare Conteggio.

  5. Nella seconda barra delle metriche, dall'elenco Metriche selezionare Attiva eventi limitati. Nell'elenco Aggregazioni selezionare Conteggio.

Il grafico mostra ora gli eventi limitati per le azioni e i trigger nel flusso di lavoro dell'app per la logica. Per altre informazioni, vedere Visualizzare le metriche per l'integrità e le prestazioni del flusso di lavoro in App per la logica di Azure.

Per gestire la limitazione a questo livello, sono disponibili le opzioni seguenti:

  • Limitare il numero di istanze del flusso di lavoro che possono essere eseguite contemporaneamente.

    Per impostazione predefinita, se la condizione del trigger del flusso di lavoro viene soddisfatta più volte contemporaneamente, più istanze di tale trigger vengono attivate e eseguite simultaneamente o in parallelo. Ogni istanza del trigger viene attivata prima del completamento dell'esecuzione dell'istanza del flusso di lavoro precedente.

    Anche se il numero predefinito di istanze di trigger che possono essere eseguite simultaneamente è illimitato, è possibile limitare questo numero attivando l'impostazione di concorrenza del trigger e, se necessario, selezionare un limite diverso dal valore predefinito.

  • Abilitare la modalità velocità effettiva elevata.

  • Disabilitare il comportamento della matrice di discussione o "Split On" nei trigger.

    Se un trigger restituisce una matrice per le azioni del flusso di lavoro rimanenti da elaborare, l'impostazione Split On del trigger divide gli elementi della matrice e avvia un'istanza del flusso di lavoro per ogni elemento della matrice. Questo comportamento attiva in modo efficace più esecuzioni simultanee fino al limite Split On.

    Per controllare la limitazione, disattivare il comportamento Split On del trigger e elaborare l'intera matrice con una singola chiamata anziché gestire un singolo elemento per chiamata.

  • Eseguire il refactoring delle azioni in più flussi di lavoro più piccoli.

    Come accennato in precedenza, un flusso di lavoro dell'app per la logica di consumo è limitato a un numero predefinito di azioni che possono essere eseguite in un periodo di 5 minuti. Anche se è possibile aumentare questo limite abilitando la modalità velocità effettiva elevata, è anche possibile considerare se si desidera suddividere le azioni del flusso di lavoro in flussi di lavoro più piccoli in modo che il numero di azioni eseguite in ogni flusso di lavoro rimanga sotto il limite. In questo modo, si riduce il carico su un singolo flusso di lavoro e si distribuisce il carico in più flussi di lavoro. Questa soluzione funziona meglio per le azioni che gestiscono set di dati di grandi dimensioni o spin up così tante azioni contemporaneamente in esecuzione, iterazioni cicliche o azioni all'interno di ogni iterazione del ciclo che superano il limite di esecuzione dell'azione.

    Ad esempio, il flusso di lavoro Consumo seguente esegue tutte le operazioni per ottenere tabelle da un database SQL Server e ottiene le righe da ogni tabella. L'oggetto For ogni ciclo esegue simultaneamente l'iterazione di ogni tabella in modo che l'azione Recupera righe restituisca le righe per ogni tabella. In base alle quantità di dati nelle tabelle, queste azioni potrebbero superare il limite per le esecuzioni di azioni.

    Screenshot che mostra il refactoring del flusso di lavoro di consumo

    Dopo il refactoring, il flusso di lavoro originale viene suddiviso in un flusso di lavoro padre e in un flusso di lavoro figlio.

    Il flusso di lavoro padre seguente ottiene le tabelle da SQL Server e quindi chiama il flusso di lavoro figlio per ogni tabella per ottenere le righe:

    Screenshot che mostra il flusso di lavoro padre consumo che ottiene le tabelle SQL Server e chiama il flusso di lavoro figlio.

    Il flusso di lavoro figlio seguente viene chiamato dal flusso di lavoro padre per ottenere le righe per ogni tabella:

    Screenshot che mostra il flusso di lavoro figlio consumo che ottiene le righe per ogni tabella.

Limitazione del connettore

Ogni connettore ha i propri limiti di limitazione, che è possibile trovare nella pagina di riferimento tecnica di ogni connettore. Ad esempio, il connettore bus di servizio di Azure ha un limite di limitazione che consente fino a 6.000 chiamate al minuto, mentre il connettore SQL Server ha limiti di limitazione che variano in base al tipo di operazione.

Alcuni trigger e azioni, ad esempio HTTP, dispongono di un "criterio di ripetizione dei tentativi" che è possibile personalizzare in base ai limiti dei criteri di ripetizione dei tentativi per implementare la gestione delle eccezioni. Questo criterio specifica se e la frequenza con cui un trigger o un'azione esegue il tentativo di una richiesta quando la richiesta originale ha esito negativo o timeout e genera una risposta 408, 429 o 5xx. Quindi, quando viene avviata la limitazione e restituisce un errore 429, App per la logica segue i criteri di ripetizione dei tentativi in cui è supportato.

Per informazioni sul fatto che un trigger o un'azione supporti i criteri di ripetizione dei tentativi, controllare le impostazioni del trigger o dell'azione. Per visualizzare i tentativi di tentativi di trigger o azione, passare alla cronologia delle esecuzioni dell'app per la logica, selezionare l'esecuzione che si vuole esaminare e espandere tale trigger o azione per visualizzare i dettagli sugli input, gli output e i tentativi.

L'esempio di flusso di lavoro Consumo seguente illustra dove è possibile trovare queste informazioni per un'azione HTTP:

Screenshot che mostra il flusso di lavoro Consumo con la cronologia di esecuzione di un'azione HTTP, tentativi, input e output.

Anche se la cronologia dei tentativi fornisce informazioni sugli errori, potrebbe verificarsi un problema di differenziazione tra la limitazione della limitazione del connettore e la limitazione della destinazione. In questo caso, potrebbe essere necessario esaminare i dettagli della risposta o eseguire alcuni calcoli di intervallo di limitazione per identificare l'origine.

Per i flussi di lavoro delle app per la logica di consumo in App per la logica di Azure multi-tenant, la limitazione avviene a livello di connessione . Per i flussi di lavoro delle app per la logica eseguiti in un ambiente del servizio di integrazione (ISE), la limitazione avviene ancora per le connessioni non ISE perché vengono eseguite nelle app per la logica multi-tenant di Azure. Tuttavia, le connessioni ISE, create dai connettori ISE, non sono limitate perché vengono eseguite nell'ISE.

Per gestire la limitazione a questo livello, sono disponibili le opzioni seguenti:

  • Configurare più connessioni per un'unica azione in modo che il flusso di lavoro possa partizionare i dati per l'elaborazione.

    Valutare se è possibile distribuire il carico di lavoro suddividendo le richieste di un'azione tra più connessioni alla stessa destinazione usando le stesse credenziali.

    Si supponga, ad esempio, che il flusso di lavoro ottenga tabelle da un database SQL Server e quindi ottiene le righe da ogni tabella. In base al numero di righe che è necessario elaborare, è possibile usare più connessioni e più cicli per dividere il numero totale di righe in set più piccoli per l'elaborazione. Questo scenario usa due cicli Per ogni ciclo per dividere il numero totale di righe in metà. Il primo ciclo Per ogni ciclo usa un'espressione che ottiene la prima metà. L'altro Ciclo Per ogni ciclo usa un'espressione diversa che ottiene la seconda metà, ad esempio:

    • Espressione 1: la take() funzione ottiene la parte anteriore di una raccolta. Per altre informazioni, vedere la take() funzione.

      @take(collection-or-array-name, div(length(collection-or-array-name), 2))

    • Espressione 2: la skip() funzione rimuove la parte anteriore di una raccolta e restituisce tutti gli altri elementi. Per altre informazioni, vedere la skip() funzione.

      @skip(collection-or-array-name, div(length(collection-or-array-name), 2))

      Nell'esempio di flusso di lavoro Consumo seguente viene illustrato come usare queste espressioni:

      Screenshot che mostra un flusso di lavoro Consumo che usa più connessioni per una singola azione.

  • Configurare una connessione diversa per ogni azione.

    Valutare se è possibile distribuire il carico di lavoro distribuendo le richieste di ogni azione tramite la propria connessione, anche quando le azioni si connettono allo stesso servizio o sistema e usano le stesse credenziali.

    Si supponga, ad esempio, che il flusso di lavoro ottenga le tabelle da un database SQL Server e ottenga ogni riga in ogni tabella. È possibile usare connessioni separate in modo che il recupero delle tabelle usi una connessione, mentre il recupero di ogni riga usa un'altra connessione.

    Nell'esempio seguente viene illustrato un flusso di lavoro Consumo che crea e usa una connessione diversa per ogni azione:

    Screenshot che mostra un flusso di lavoro Consumo che crea e usa una connessione diversa per ogni azione.

  • Modificare la concorrenza o il parallelismo in un ciclo "For each".

    Per impostazione predefinita, le iterazioni del ciclo "Per ogni" vengono eseguite contemporaneamente fino al limite di concorrenza. Se si dispone di una connessione che viene limitata all'interno di un ciclo "For each", è possibile ridurre il numero di iterazioni del ciclo eseguite in parallelo. Per altre informazioni, vedere la documentazione seguente:

Limitazione del servizio di destinazione o del sistema

Anche se un connettore ha limiti di limitazione, il servizio di destinazione o il sistema chiamato dal connettore potrebbe anche avere limiti di limitazione. Ad esempio, alcune API in Microsoft Exchange Server hanno limiti di limitazione più rigorosi rispetto al connettore di Outlook Office 365.

Per impostazione predefinita, le istanze del flusso di lavoro di un'app per la logica e tutti i cicli o i rami all'interno di tali istanze vengono eseguiti in parallelo. Questo comportamento significa che più istanze possono chiamare lo stesso endpoint contemporaneamente. Ogni istanza non conosce l'esistenza dell'altra, quindi tenta di ripetere i tentativi di azioni non riuscite può creare condizioni di gara in cui più chiamate tentano di eseguire contemporaneamente, ma per esito positivo, tali chiamate devono arrivare al servizio di destinazione o al sistema prima che la limitazione inizi a verificarsi.

Si supponga, ad esempio, di avere una matrice con 100 elementi. Si usa un ciclo "For each" per scorrere la matrice e attivare il controllo di concorrenza del ciclo in modo da limitare il numero di iterazioni parallele a 20 o al limite predefinito corrente. All'interno di tale ciclo, un'azione inserisce un elemento dalla matrice in un database SQL Server, che consente solo 15 chiamate al secondo. Questo scenario comporta un problema di limitazione perché un backlog di tentativi viene compilato e non viene mai eseguito.

La tabella seguente descrive la sequenza temporale per ciò che accade nel ciclo quando l'intervallo di ripetizione dei tentativi dell'azione è 1 secondo:

Temporizzazione Numero di azioni eseguite Numero di azioni che hanno esito negativo Numero di tentativi in attesa
T + 0 secondi 20 inserimenti 5 errore, a causa del limite SQL 5 tentativi
T + 0,5 secondi 15 inserimenti, a causa dei tentativi precedenti di 5 tentativi in attesa Tutti i 15 errori, a causa del limite SQL precedente ancora in vigore per un altro 0,5 secondi 20 tentativi
(precedente 5 + 15 nuovi)
T + 1 secondo 20 inserimenti 5 errori più precedenti 20 tentativi, a causa del limite SQL 25 tentativi (precedente 20 + 5 nuovi)

Per gestire la limitazione a questo livello, sono disponibili le opzioni seguenti:

  • Creare singoli flussi di lavoro in modo che ogni operazione gestisca una singola operazione.

    • Continuando con l'esempio SQL Server scenario in questa sezione, è possibile creare un flusso di lavoro che inserisce gli elementi della matrice in una coda, ad esempio una coda di bus di servizio di Azure. Si crea quindi un altro flusso di lavoro che esegue solo l'operazione di inserimento per ogni elemento della coda. In questo modo, viene eseguita solo un'istanza del flusso di lavoro in qualsiasi momento specifico, che completa l'operazione di inserimento e passa all'elemento successivo nella coda oppure l'istanza ottiene 429 errori, ma non tenta tentativi di tentativi non produttivi.

    • Creare un flusso di lavoro padre che chiama un flusso di lavoro figlio o annidato per ogni azione. Se l'elemento padre deve chiamare flussi di lavoro figlio diversi in base al risultato dell'elemento padre, è possibile usare un'azione di condizione o un'azione switch che determina il flusso di lavoro figlio da chiamare. Questo modello consente di ridurre il numero di chiamate o operazioni.

      Si supponga, ad esempio, di avere due flussi di lavoro, ognuno con un trigger di polling che controlla l'account di posta elettronica ogni minuto per un oggetto specifico, ad esempio "Success" o "Failure". Questa configurazione comporta 120 chiamate all'ora. Se invece si crea un singolo flusso di lavoro padre che esegue il polling ogni minuto, ma chiama un flusso di lavoro figlio che viene eseguito in base al fatto che l'oggetto sia "Success" o "Failure", si taglia il numero di controlli di polling a metà o 60 in questo caso.

  • Configurare l'elaborazione batch. (solo flussi di lavoro a consumo)

    Se il servizio di destinazione supporta le operazioni batch, è possibile risolvere la limitazione dell'elaborazione di elementi in gruppi o batch anziché singolarmente. Per implementare la soluzione di elaborazione batch, si crea un flusso di lavoro dell'app per la logica "ricevitore batch" e un flusso di lavoro dell'app per la logica "mittente batch". Il mittente batch raccoglie messaggi o elementi fino a quando non vengono soddisfatti i criteri specificati e quindi invia tali messaggi o elementi in un singolo gruppo. Il ricevitore batch accetta il gruppo e elabora tali messaggi o elementi. Per altre informazioni, vedere Messaggi di elaborazione batch nei gruppi.

  • Usare le versioni webhook per trigger e azioni, anziché le versioni di polling.

    Perché? Un trigger di polling continua a controllare il servizio di destinazione o il sistema a intervalli specifici. Un intervallo molto frequente, ad esempio ogni secondo, può creare problemi di limitazione. Tuttavia, un trigger o un'azione webhook, ad esempio Webhook HTTP, crea solo una singola chiamata al servizio o al sistema di destinazione, che avviene in fase di sottoscrizione e richiede che la destinazione notifica il trigger o l'azione solo quando si verifica un evento. In questo modo, il trigger o l'azione non devono controllare continuamente la destinazione.

    Quindi, se il servizio di destinazione o il sistema supporta webhook o fornisce un connettore con una versione webhook, questa opzione è migliore rispetto all'uso della versione di polling. Per identificare i trigger e le azioni webhook, verificare che abbiano il ApiConnectionWebhook tipo o che non siano necessari per specificare una ricorrenza. Per altre informazioni, vedere l'azione trigger APIConnectionWebhook e APIConnectionWebhook.

Passaggi successivi