L'API NerdGraph de New Relic applique une limite de 25 concurrent requests per user. Les exemples de code suivants peuvent être utilisés comme points de départ pour éviter ces limites ou recevoir des codes d’état HTTP 429
. Les deux exemples ci-dessous suivent le même cas d'utilisation où vous exécutez une requête sur plusieurs comptes New Relic en parallèle, mais vous tombez toujours sous la limite de simultanéité de NerdGraph.
Javascript
Une façon de gérer la simultanéité est d’utiliser un pool de travailleurs. L'exemple ci-dessous utilise le module async pour ce faire. Il crée une file d'attente qui a une limite d'exécution de simultanéité définie, envoie requests sous forme de tâches sur cette file d'attente et vide la file d'attente une fois toutes les tâches terminées.
import got from "got";import async from "async";
const API_KEY = "YOUR_GRAPHQL_USER_KEY"; // GraphQL User Keyconst MAX_CONCURRENCY = 25; // Maximum amount of requests in queue at a given time
const GRAPH_API = "https://api.newrelic.com/graphql";const HEADERS = { "Content-Type": "application/json", "Api-Key": API_KEY };
async function main() { let accounts = await getAccounts(); // All accounts to run a query against var allResults = [];
//Queue initialization const q = async.queue(async (task, cb) => { let result = await makeRequest(task.acct); allResults.push({ transactionCount: result[0].count, account: task.acct.id, }); cb(); }, MAX_CONCURRENCY);
// Push requests on to the queue (one for each account) accounts.forEach((acct) => { q.push({ acct: acct }); });
await q.drain(); // Drain event listener when all tasks are complete
console.log(allResults);}
async function makeRequest(acct) { let nrql = `SELECT count(*) FROM Transaction`; let gql = `{ actor { account(id: ${acct.id}) { nrql(query: "${nrql}", timeout: 90) { results } } } }`;
let opts = { url: GRAPH_API, headers: HEADERS, json: { query: gql, variables: {} }, };
let response = await got.post(opts).json(); if (!response.errors) { return response.data.actor.account.nrql.results; } else { console.log("Query Error"); console.log(response.errors); }}
async function getAccounts() { var q = `{ actor { accounts { id name } } }`;
var opts = { url: GRAPH_API, headers: HEADERS, json: { query: q, variables: {} }, };
let resp = await got.post(opts).json(); return resp.data.actor.accounts;}
main();
Python
Vous pouvez également utiliser Python en exploitant le package suivant pour gérer requests asynchrones et simultanées :
- aiohttp - Utilisé pour effectuer requestshttp asynchrones
- asyncio - Utilisé pour gérer la simultanéité
Ci-dessous, un sémaphore qui gère le nombre de requests simultanées. Il utilise ensuite asyncio.gather()
pour exécuter plusieurs co-routines simultanément et attend leur achèvement.
import aiohttpimport asyncio
API_KEY = "YOUR_GRAPHQL_USER_KEY"MAX_CONCURRENCY = 25GRAPHQL_API = "https://api.newrelic.com/graphql"HEADERS = {"Content-Type": "application/json", "Api-Key": API_KEY}
async def main(): # All accounts to run a query against accounts = await get_accounts()
# Semaphore for controlling concurrency limit = asyncio.Semaphore(MAX_CONCURRENCY)
# Add all accounts to run a query against tasks = [send_request(acct, limit) for acct in accounts]
# Schedule all tasks to run concurrently allResults = await asyncio.gather(*tasks)
print(allResults)
async def send_request(acct, limit): nrql = "SELECT count(*) FROM Transaction" gql = f""" {{ actor {{ account(id: {acct['id']}) {{ nrql(query: "{nrql}", timeout: 90) {{ results }} }} }} }} """
async with limit: try: async with aiohttp.ClientSession() as session: async with session.post( GRAPHQL_API, json={"query": gql, "variables": {}}, headers=HEADERS ) as response: result = await response.json() return { "transactionCount": result["data"]["actor"]["account"]["nrql"]["results"][0]["count"],"account": acct["id"], } except Exception as error: print("Query Error") raise error
async def get_accounts(): gql = """ { actor { accounts { id name } } } """
async with aiohttp.ClientSession() as session: async with session.post( GRAPHQL_API, json={"query": gql, "variables": {}}, headers=HEADERS ) as response: result = await response.json() return result["data"]["actor"]["accounts"]
if __name__ == "__main__": asyncio.run(main()) # Run event loop
Pour plus de détails sur les limites de NerdGraph, voir Limites d'utilisation de NerdGraph.