Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
При программной работе с данными из Azure Resource Graph важно учитывать, как ограничение ресурсов влияет на результаты запросов. Изменение способа запроса данных может помочь вам и вашей организации избежать проблем регулирования и поддерживать поток своевременных данных о ресурсах Azure.
В этой статье рассматриваются четыре области и шаблона, связанных с созданием запросов к Azure Resource Graph:
- Общие сведения о регулировании заголовков.
- Группирование запросов.
- Ошеломляющие запросы.
- Эффект разбиения на страницы.
Общие сведения о заголовках регулирования
Azure Resource Graph выделяет количественную квоту для каждого пользователя с учетом временного окна. Например, пользователь не может отправить более 15 запросов в течение 5 секунд, иначе применяется регулирование. Значение квоты определяется множеством факторов и может изменяться.
В каждый ответ на запрос Azure Resource Graph добавляет следующие два заголовка регулирования:
-
x-ms-user-quota-remaining(int): оставшаяся квота ресурсов для пользователя. Это значение соответствует количеству запросов. -
x-ms-user-quota-resets-after(hh:mm:ss): длительность до сброса квоты пользователя.
Если субъект безопасности имеет доступ к более чем 10 000 подписок в области запроса клиента или группы управления, ответ ограничен первым 10 000 подписками, а x-ms-tenant-subscription-limit-hit заголовок возвращается как true.
Чтобы продемонстрировать работу этих заголовков, давайте рассмотрим ответ на запрос со следующими значениями заголовков: x-ms-user-quota-remaining: 10 и x-ms-user-quota-resets-after: 00:00:03.
- В течение следующих 3 секунд можно отправлять не более 10 запросов без регулирования.
- Через 3 секунды значения
x-ms-user-quota-remainingи сбрасываются соответственноx-ms-user-quota-resets-after15.00:00:05
Чтобы просмотреть пример использования заголовков для возврата запросов, ознакомьтесь с примером в запросе параллельно.
Группирование запросов
Группирование запросов по подпискам, группам ресурсов или конкретному ресурсу работает более эффективно, чем параллельное выполнение. Более крупный запрос часто меньше влияет на квоту, чем множество мелких и конкретных запросов. Мы рекомендуем создавать группы размером не более 300 элементов.
Пример плохо оптимизированного подхода.
// 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: "Resources | project name, type"); var azureOperationResponse = await this.resourceGraphClient .ResourcesWithHttpMessagesAsync(userQueryRequest, header) .ConfigureAwait(false); // ... }Пример оптимизированного подхода к группировке.
// 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); // ... }Пример оптимизированного подхода к группировке для получения нескольких ресурсов в одном запросе.
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); // ... }
Поочередная отправка запросов
С учетом того, как применяется регулирование, есть смысл отправлять запросы поочередно. Например, вместо отправки 60 запросов одновременно ошеломляйте запросы в четыре 5-секундные окна.
Расписание запросов без тегов.
Число запросов шестьдесят 0 0 0 Интервал времени (с) 0-5 5-10 10-15 15–20 Расписание ошеломляемых запросов.
Число запросов 15 15 15 15 Интервал времени (с) 0-5 5-10 10-15 15–20
Следующий код является примером уважения заголовков регулирования при запросе Azure Resource Graph.
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);
}
}
Параллельное выполнение запросов
Хотя мы рекомендуем чаще применять группирование, чем распараллеливание, в некоторых случаях группирование выполнить сложно. В таких случаях может потребоваться запросить Azure Resource Graph, отправив несколько запросов параллельно. В следующем примере показано, как выполнять откат на основе заголовков регулирования.
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);
}
}
}
Разбиение на страницы
Так как Azure Resource Graph возвращает не более 1000 записей в одном ответе запроса, может потребоваться разместить запросы на страницы, чтобы получить полный набор данных. Но некоторые клиенты Azure Resource Graph обрабатывают разбиение на страницы по-разному, чем другие.
При использовании пакета SDK ResourceGraph для поддержки разбиения на страницы нужно передавать в запросе маркер пропуска, полученный в ответе на предыдущий запрос. Такой механизм означает, что вам придется самостоятельно объединять результаты из всех вызовов, получающих страницы одного набора. В этом случае каждый отправляемый запрос с разбивкой на страницы принимает одну квоту запроса.
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.
}
Различие между запросами регулирования для ARG и ARM
Важно понимать источник регулирования, чтобы обратиться к нужной команде для увеличения квоты. Если вы получаете следующее сообщение об ошибке, источник регулирования связан с ARM, а не ARG:
<value>
Number of 'read' requests for subscription '{1}' actor '{2}' exceeded. Please try again after '{3}' seconds after additional tokens are available. Refer to https://aka.ms/arm-throttling for additional information.
</value>
Отправьте запрос в службу поддержки для регулирования запросов, связанных с ARM.
ARG GET/LIST API
ARG представляет альтернативный подход к существующим вызовам API уровня управления Azure GET и List, которые повышают масштабируемость и производительность, устраняя проблемы регулирования для клиентов Azure. Этот API в настоящее время поддерживается только для ресурсов в resources таблице и computeresources таблице.
API ARG GET/LIST предназначен для решения сценариев, в которых требуется поиск одного ресурса по идентификатору, или вы перечисляете ресурсы в той же области и в определенной области (подписка, группа ресурсов или родительский ресурс).
Следует рассмотреть API ARG GET/LIST, если служба попадает в одну (или многие) из следующих категорий:
Служба выполняет большое количество вызовов GET для получения данных ресурса, предназначенного для одной подписки или одной группы ресурсов, и не требует пакетов записей из нескольких подписок с использованием сложной фильтрации или объединения данных.
Ваша служба отправляет большой объем запросов GET и находится под угрозой:
- Столкнувшись с ограничением.
- Конкуренция за ограничение квоты с другими клиентами.
- Ваша служба может быть склонна к выполнению большого объема одновременных запросов GET в течение короткого периода времени.
Служба требует высокой доступности и более быстрой производительности для запросов GET, для единого управления ресурсами или перечисления списка ресурсов в определенной области.
Вам требуется полный просмотр виртуальных машин и виртуальных машин VMSS в режиме Uniform, а также в режиме оркестрации Flex.
Замечание
API ARG GET/LIST не поддерживает состояние работоспособности виртуальных машин (VM и VMSS), а также статус запуска расширений в instanceView. Дополнительные сведения об ограничениях API ARG GET/LIST см. в известных ограничениях.
Если нужный ресурс находится в resources таблице или computeresources таблице, и он попадает в одну из указанных выше категорий, а затем используйте API ARG GET/LIST.
Все еще регулируется?
Если вы следовали рекомендациям этой статьи, пробовали решение API GET/LIST в Azure Resource Graph и ваши запросы в Azure Resource Graph по-прежнему ограничиваются, обратитесь к группе Azure Resource Graph. Команда поддерживает Azure Resource Graph, но не поддерживает регулирование Microsoft Graph.
Укажите эти сведения при обращении к группе Azure Resource Graph:
- Подробности о вашем варианте использования и бизнес-обоснование для повышения предела регулирования.
- К какому объему ресурсов у вас есть доступ? Сколько из них возвращаются из одного запроса?
- Какие типы ресурсов вас интересуют?
- Какой шаблон запросов вы используете? Данные о числе выполненных запросов в секунду и т. п.
Следующие шаги
- См. описание используемого языка в статье Примеры запросов к Resource Graph для начинающих.
- Описание расширенных вариантов использования см. в статье Примеры расширенных запросов к Resource Graph.
- Узнайте больше о том, как изучать ресурсы.