Útmutatás szabályozott kérelmekhez az Azure Resource Graph-ban

Az Azure Resource Graph-adatok programozott és gyakori használata során figyelembe kell venni, hogy a szabályozás hogyan befolyásolja a lekérdezések eredményeit. Az adatok kérésének módosítása segíthet Önnek és a szervezetnek elkerülni a szabályozást, és fenntartani az Azure-erőforrásokra vonatkozó időalapú adatok áramlását.

Ez a cikk négy olyan területet és mintát mutat be, amelyek a lekérdezések Azure Resource Graph-ban való létrehozásával kapcsolatosak:

  • A szabályozás fejléceinek ismertetése.
  • Lekérdezések csoportosítása.
  • Megdöbbentő lekérdezések.
  • A lapozás hatása.

Understand throttling headers

Azure Resource Graph allocates a quota number for each user based on a time window. A felhasználók például 5 másodpercenként legfeljebb 15 lekérdezést küldhetnek szabályozás nélkül. A kvóta értékét számos tényező határozza meg, és változhat.

In every query response, Azure Resource Graph adds two throttling headers:

  • x-ms-user-quota-remaining (int): A felhasználó fennmaradó erőforráskvótája. Ez az érték a lekérdezések számának megfeleltetésére van leképzve.
  • x-ms-user-quota-resets-after (óó:mm:ss): A felhasználó kvótahasználatának alaphelyzetbe állításáig eltelt idő.

Ha egy biztonsági tag több mint 10 000 előfizetéshez fér hozzá a bérlői vagy felügyeleti csoport lekérdezési hatókörében, a válasz az első 10 000 előfizetésre korlátozódik, és a fejlécet truea x-ms-tenant-subscription-limit-hit rendszer visszaadja.

A fejlécek működésének szemléltetéséhez tekintsünk meg egy lekérdezési választ, amelynek fejléce x-ms-user-quota-remaining: 10 és értéke és x-ms-user-quota-resets-after: 00:00:03értéke.

  • A következő 3 másodpercben legfeljebb 10 lekérdezés küldhető el szabályozás nélkül.
  • 3 másodpercen belül a rendszer visszaállítja és visszaállítja x-ms-user-quota-remainingx-ms-user-quota-resets-after1500:00:05 az értékeket.

Ha egy példát szeretne látni arra, hogyan használhatja a fejléceket a lekérdezési kérések visszalépésére , tekintse meg a lekérdezésben található mintát párhuzamosan.

Grouping queries

A lekérdezések előfizetés, erőforráscsoport vagy egyéni erőforrás szerinti csoportosítása hatékonyabb, mint a lekérdezések párhuzamosítása. The quota cost of a larger query is often less than the quota cost of many small and targeted queries. A csoport mérete 300-nál kisebbnek ajánlott.

  • Példa a rosszul optimalizált megközelítésre.

    // NOT RECOMMENDED
    var header = /* your request header */
    var subscriptionIds = /* A big list of subscriptionIds */
    
    foreach (var subscriptionId in subscriptionIds)
    {
        var userQueryRequest = new QueryRequest(
            subscriptions: new[] { subscriptionId },
            query: "Resoures | project name, type");
    
        var azureOperationResponse = await this.resourceGraphClient
            .ResourcesWithHttpMessagesAsync(userQueryRequest, header)
            .ConfigureAwait(false);
    
    // ...
    }
    
  • Példa az optimalizált csoportosítási megközelítésre.

    // RECOMMENDED
    var header = /* your request header */
    var subscriptionIds = /* A big list of subscriptionIds */
    
    const int groupSize = 100;
    for (var i = 0; i <= subscriptionIds.Count / groupSize; ++i)
    {
        var currSubscriptionGroup = subscriptionIds.Skip(i * groupSize).Take(groupSize).ToList();
        var userQueryRequest = new QueryRequest(
            subscriptions: currSubscriptionGroup,
            query: "Resources | project name, type");
    
        var azureOperationResponse = await this.resourceGraphClient
            .ResourcesWithHttpMessagesAsync(userQueryRequest, header)
            .ConfigureAwait(false);
    
      // ...
    }
    
  • Példa egy optimalizált csoportosítási módszerre, amely több erőforrást kér le egy lekérdezésben.

    Resources | where id in~ ({resourceIdGroup}) | project name, type
    
    // RECOMMENDED
    var header = /* your request header */
    var resourceIds = /* A big list of resourceIds */
    
    const int groupSize = 100;
    for (var i = 0; i <= resourceIds.Count / groupSize; ++i)
    {
        var resourceIdGroup = string.Join(",",
            resourceIds.Skip(i * groupSize).Take(groupSize).Select(id => string.Format("'{0}'", id)));
        var userQueryRequest = new QueryRequest(
            subscriptions: subscriptionList,
            query: $"Resources | where id in~ ({resourceIdGroup}) | project name, type");
    
        var azureOperationResponse = await this.resourceGraphClient
            .ResourcesWithHttpMessagesAsync(userQueryRequest, header)
            .ConfigureAwait(false);
    
      // ...
    }
    

Staggering queries

Because of the way throttling is enforced, we recommend queries to be staggered. Például ahelyett, hogy egyszerre 60 lekérdezést küldene, a lekérdezéseket négy 5 másodperces ablakba bonthatja.

  • Nem átmeneti lekérdezés ütemezése.

    Lekérdezések száma 60 0 0 0
    Időintervallum (mp) 0-5 5-10 10-15 15-20
  • Átmeneti lekérdezés ütemezése.

    Lekérdezések száma 15 15 15 15
    Időintervallum (mp) 0-5 5-10 10-15 15-20

Az alábbi kód egy példa a fejlécek szabályozásának tiszteletben tartására az Azure Resource Graph lekérdezése során.

while (/* Need to query more? */)
{
    var userQueryRequest = /* ... */
    // Send post request to Azure Resource Graph
    var azureOperationResponse = await this.resourceGraphClient
        .ResourcesWithHttpMessagesAsync(userQueryRequest, header)
        .ConfigureAwait(false);

    var responseHeaders = azureOperationResponse.response.Headers;
    int remainingQuota = /* read and parse x-ms-user-quota-remaining from responseHeaders */
    TimeSpan resetAfter = /* read and parse x-ms-user-quota-resets-after from responseHeaders */
    if (remainingQuota == 0)
    {
        // Need to wait until new quota is allocated
        await Task.Delay(resetAfter).ConfigureAwait(false);
    }
}

Lekérdezés párhuzamosan

Annak ellenére, hogy a csoportosítás párhuzamosítással javasolt, vannak olyan esetek, amikor a lekérdezések nem csoportosíthatók könnyen. Ezekben az esetekben érdemes lehet több lekérdezés párhuzamos elküldésével lekérdezni az Azure Resource Graphot. Az alábbi példa bemutatja, hogyan lehet visszalépést elvégezni a szabályozás fejlécei alapján.

IEnumerable<IEnumerable<string>> queryGroup = /* Groups of queries  */
// Run groups in parallel.
await Task.WhenAll(queryGroup.Select(ExecuteQueries)).ConfigureAwait(false);

async Task ExecuteQueries(IEnumerable<string> queries)
{
    foreach (var query in queries)
    {
        var userQueryRequest = new QueryRequest(
            subscriptions: subscriptionList,
            query: query);
        // Send post request to Azure Resource Graph.
        var azureOperationResponse = await this.resourceGraphClient
            .ResourcesWithHttpMessagesAsync(userQueryRequest, header)
            .ConfigureAwait(false);

        var responseHeaders = azureOperationResponse.response.Headers;
        int remainingQuota = /* read and parse x-ms-user-quota-remaining from responseHeaders */
        TimeSpan resetAfter = /* read and parse x-ms-user-quota-resets-after from responseHeaders */
        if (remainingQuota == 0)
        {
            // Delay by a random period to avoid bursting when the quota is reset.
            var delay = (new Random()).Next(1, 5) * resetAfter;
            await Task.Delay(delay).ConfigureAwait(false);
        }
    }
}

Pagination

Mivel az Azure Resource Graph legfeljebb 1000 bejegyzést ad vissza egyetlen lekérdezési válaszban, előfordulhat, hogy a lekérdezéseket többoldalasra kell helyeznie a kívánt teljes adatkészlet lekéréséhez. Egyes Azure Resource Graph-ügyfelek azonban másként kezelik a lapozást, mint mások.

A ResourceGraph SDK használatakor a lapozást úgy kell kezelnie, hogy az előző lekérdezési válaszból visszaadott kihagyó jogkivonatot átadja a következő lapszámozott lekérdezésnek. Ez a kialakítás azt jelenti, hogy az összes lapszámozott hívás eredményét össze kell gyűjtenie, és a végén össze kell egyesítenie őket. Ebben az esetben minden elküldött lapszámozott lekérdezés egy lekérdezési kvótát vesz igénybe.

var results = new List<object>();
var queryRequest = new QueryRequest(
  subscriptions: new[] { mySubscriptionId },
  query: "Resources | project id, name, type");
var azureOperationResponse = await this.resourceGraphClient
  .ResourcesWithHttpMessagesAsync(queryRequest, header)
  .ConfigureAwait(false);
while (!string.IsNullOrEmpty(azureOperationResponse.Body.SkipToken))
{
  queryRequest.Options ??= new QueryRequestOptions();
  queryRequest.Options.SkipToken = azureOperationResponse.Body.SkipToken;
  var azureOperationResponse = await this.resourceGraphClient
      .ResourcesWithHttpMessagesAsync(queryRequest, header)
      .ConfigureAwait(false);
  results.Add(azureOperationResponse.Body.Data.Rows);

// Inspect throttling headers in query response and delay the next call if needed.
}

Még mindig szabályozva van?

Ha a cikk ajánlásait használta, és az Azure Resource Graph-lekérdezések szabályozása még folyamatban van, forduljon az Azure Resource Graph csapatához. A csapat támogatja az Azure Resource Graphot, de nem támogatja a Microsoft Graph szabályozását.

Adja meg ezeket a részleteket, amikor kapcsolatba lép az Azure Resource Graph csapatával:

  • Az adott használati esetnek és üzleti illesztőprogramnak magasabb szabályozási korlátra van szüksége.
  • Hány erőforráshoz rendelkezik hozzáféréssel? Hányat adnak vissza egyetlen lekérdezésből?
  • Milyen típusú erőforrások érdeklik?
  • Mi a lekérdezési minta? X lekérdezések Y másodpercenként és így tovább.

További lépések

  • Tekintse meg a kezdő lekérdezésekben használt nyelvet.
  • A speciális lekérdezések speciális felhasználási módjai.
  • További információ az erőforrások felfedezéséről.