Квоты и тарификация

Google Maps JavaScript API относится к набору облачных сервисов платформы Google Maps Platform и использует модель оплаты по фактическому потреблению. Каждый запрос к картографическим сервисам учитывается в статистике проекта Google Cloud и влияет на расход квоты.

Система квот выполняет несколько задач:

  • контроль нагрузки на инфраструктуру Google;
  • защита от чрезмерного использования API;
  • прогнозирование затрат;
  • разграничение доступа между различными проектами;
  • предотвращение злоупотреблений и ошибочных циклических запросов.

Понимание механизма тарификации особенно важно при разработке коммерческих веб-приложений, поскольку ошибки в архитектуре способны привести к значительному росту расходов.


Связь Google Maps JavaScript API с Google Cloud

Для работы Google Maps JavaScript API требуется:

  1. Создать проект в Google Cloud.
  2. Подключить биллинг (Billing Account).
  3. Активировать необходимые API.
  4. Создать API-ключ.
  5. Настроить ограничения доступа.

После активации биллинга все обращения к сервисам начинают учитываться в рамках конкретного проекта.

С точки зрения тарификации Google Maps JavaScript API является лишь одной из множества служб платформы Google Maps Platform. Стоимость приложения зависит не только от отображения карты, но и от использования связанных сервисов:

  • Maps JavaScript API;
  • Geocoding API;
  • Places API;
  • Directions API;
  • Distance Matrix API;
  • Elevation API;
  • Roads API;
  • Geolocation API;
  • Street View Static API;
  • Maps Static API.

Каждый сервис имеет собственную модель учета запросов.


Понятие SKU

В основе тарификации Google Maps Platform лежит понятие SKU (Stock Keeping Unit).

SKU представляет собой отдельную платную операцию или группу операций.

Например:

Действие Возможный SKU
Загрузка интерактивной карты Dynamic Maps
Поиск места Places Search
Автодополнение адреса Autocomplete
Геокодирование адреса Geocoding
Построение маршрута Directions

Стоимость определяется не самим фактом использования API, а количеством операций конкретного SKU.


Что считается использованием Maps JavaScript API

При работе с Google Maps JavaScript API тарифицируются не все действия одинаково.

Загрузка карты

Наиболее распространённый сценарий — отображение интерактивной карты.

const map = new google.maps.Map(
    document.getElementById("map"),
    {
        center: { lat: 51.1605, lng: 71.4704 },
        zoom: 10
    }
);

Каждая загрузка карты может учитываться как отдельная операция Dynamic Maps.

Под загрузкой понимается создание экземпляра карты на странице.

Если пользователь обновил страницу:

F5 → новая загрузка карты

Если открыта новая вкладка:

Новая вкладка → новая загрузка карты

Если карта создаётся повторно после уничтожения объекта:

destroy() → create() → новая операция

Панорамный просмотр Street View

Использование панорам также может тарифицироваться отдельно.

const panorama =
    new google.maps.StreetViewPanorama(
        document.getElementById("street-view"),
        {
            position: {
                lat: 40.6892,
                lng: -74.0445
            }
        }
    );

Каждая загрузка панорамы учитывается по собственному SKU.


Бесплатный лимит и кредит

Google периодически обновляет ценовую модель.

Исторически платформа предоставляла ежемесячный кредит для покрытия небольших проектов. Размер такого кредита и условия его предоставления могут изменяться, поэтому актуальные значения необходимо проверять в документации Google Maps Platform.

Даже если проект находится в пределах бесплатного объёма использования, подключение биллинга обычно остаётся обязательным.

Типичный жизненный цикл выглядит следующим образом:

Запрос
   ↓
Учёт использования
   ↓
Применение бесплатного кредита
   ↓
Расчёт итоговой стоимости

Если расходы не превышают размер доступного кредита, фактическое списание средств может не происходить.


Квоты

Квота — это ограничение на объём использования сервиса.

Существует несколько типов квот.

Суточные квоты

Ограничивают количество запросов за сутки.

Пример:

100 000 запросов в день

После исчерпания лимита сервис может начать возвращать ошибки.


Квоты по скорости запросов

Ограничивают количество обращений за единицу времени.

Пример:

3000 запросов в минуту

или

50 запросов в секунду

Подобные ограничения защищают инфраструктуру от всплесков нагрузки.


Пользовательские квоты

Администратор проекта может самостоятельно установить ограничения ниже максимальных значений Google.

Например:

Google разрешает:
100 000 запросов

Проект ограничен:
20 000 запросов

Такой подход помогает контролировать бюджет.


Проверка текущих квот

Квоты настраиваются через консоль Google Cloud.

Для каждого API отображаются:

  • текущие лимиты;
  • фактическое потребление;
  • процент использования;
  • история нагрузки.

Особенно важно отслеживать:

  • Maps JavaScript API;
  • Places API;
  • Geocoding API;
  • Directions API.

Именно эти сервисы чаще всего становятся источником неожиданных расходов.


Мониторинг использования

Google предоставляет подробную статистику использования сервисов.

Отслеживаются:

  • количество запросов;
  • стоимость операций;
  • распределение по SKU;
  • динамика по дням;
  • динамика по часам.

Пример сценария анализа:

Понедельник:
  15 000 запросов

Вторник:
  18 000 запросов

Среда:
  120 000 запросов

Резкий скачок в среду может указывать на:

  • программную ошибку;
  • бесконечный цикл запросов;
  • DDoS-атаку;
  • некорректную интеграцию клиента.

Ограничение расходов через бюджет Google Cloud

Для предотвращения непредвиденных затрат рекомендуется настраивать бюджет.

Бюджет позволяет получать уведомления при достижении заданного порога.

Например:

Бюджет: 100 USD

Уведомления:
50%
75%
90%
100%

После достижения порога отправляются сообщения администраторам проекта.


Ограничение API-ключей

Неправильно настроенный API-ключ способен привести к огромному количеству несанкционированных запросов.

Рекомендуется ограничивать ключ:

По доменам

example.com
*.example.com

Пример:

https://example.com/*

Тогда использование ключа на стороннем сайте станет невозможным.


По API

Разрешается использовать только необходимые сервисы.

Например:

Maps JavaScript API

Если приложению не нужен Geocoding API, доступ к нему лучше запретить.


Как возникают неожиданные расходы

Существует несколько распространённых ошибок.

Повторная инициализация карты

Плохо:

setInterval(() => {
    new google.maps.Map(
        document.getElementById("map"),
        options
    );
}, 1000);

Каждую секунду создаётся новая карта.

За сутки количество операций станет огромным.


Постоянное геокодирование

Плохо:

input.addEventListener("keyup", () => {
    geocoder.geocode(...);
});

Каждое нажатие клавиши отправляет запрос.

При наборе адреса из 30 символов выполняется 30 обращений.

Лучше использовать задержку (debounce).


Избыточное использование Autocomplete

Автодополнение адресов является отдельным сервисом тарификации.

Неэффективный вариант:

autocomplete.search();
autocomplete.search();
autocomplete.search();

выполняется многократно для одного и того же ввода.


Отсутствие кеширования

Плохо:

geocoder.geocode({
    address: "Moscow"
});

Запрос выполняется снова и снова.

Лучше хранить уже полученные результаты:

cache["Moscow"] = result;

Оптимизация затрат

Ленивая загрузка карты

Необязательно загружать карту сразу после открытия страницы.

Плохой вариант:

window.onl oad = initMap;

Лучший подход:

button.addEventListener(
    "click",
    initMap
);

Карта загружается только при необходимости.


Использование одного экземпляра карты

Плохо:

new google.maps.Map(...);
new google.maps.Map(...);
new google.maps.Map(...);

Лучше:

const map =
    new google.maps.Map(...);

Далее переиспользуется существующий объект.


Кеширование геоданных

Если адреса редко меняются, результаты геокодирования можно хранить в базе данных.

Схема:

Адрес
   ↓
Проверка локального кеша
   ↓
Нет данных?
   ↓
Google Geocoding API
   ↓
Сохранение результата

Это значительно уменьшает количество запросов.


Кластеризация маркеров

При большом количестве объектов возникает соблазн постоянно обновлять данные.

Например:

10000 markers

Использование кластеризации позволяет уменьшить нагрузку на клиентскую часть и сократить количество дополнительных операций.

new MarkerClusterer({
    markers,
    map
});

Ошибки, связанные с квотами

OVER_QUERY_LIMIT

Одна из наиболее распространённых ошибок.

Пример:

status === "OVER_QUERY_LIMIT"

Причины:

  • превышена скорость запросов;
  • превышена дневная квота;
  • временное ограничение сервиса.

Обработка:

if (status === "OVER_QUERY_LIMIT") {
    console.log("Лимит превышен");
}

REQUEST_DENIED

Пример:

status === "REQUEST_DENIED"

Причины:

  • отключён API;
  • неверный API-ключ;
  • ограничения по домену;
  • проблемы с биллингом.

INVALID_KEY_MAP_ERROR

Означает проблему с API-ключом.

Типичные причины:

  • ключ удалён;
  • ключ заблокирован;
  • ключ не привязан к проекту;
  • отсутствует биллинг.

Оценка стоимости проекта

При проектировании системы полезно заранее рассчитывать предполагаемую нагрузку.

Пример:

20 000 пользователей в день

Каждый пользователь:

1 загрузка карты
3 геокодирования
1 построение маршрута

Итого:

20 000 Dynamic Maps
60 000 Geocoding
20 000 Directions

После определения количества операций по каждому SKU можно оценить ежемесячные расходы и сравнить их с действующими тарифами Google Maps Platform.


Стратегия контроля расходов в производственной среде

Для коммерческих приложений обычно применяется комплексный подход:

  1. Ограничение API-ключей.
  2. Настройка бюджетов Google Cloud.
  3. Контроль квот.
  4. Мониторинг стоимости по SKU.
  5. Кеширование результатов.
  6. Ленивая загрузка карты.
  7. Использование одного экземпляра карты.
  8. Регулярный аудит статистики использования.
  9. Автоматические оповещения о росте расходов.
  10. Анализ аномальной активности и подозрительных запросов.

Такая архитектура позволяет сохранять предсказуемость затрат даже при значительном росте аудитории и интенсивном использовании Google Maps JavaScript API.