Ограничение скорости Google Cloud Tasks

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

Я создал свою очередь с:

gcloud tasks queues create my-queue \
          --max-dispatches-per-second=1 \
          --max-concurrent-dispatches=1 \
          --max-attempts=2 \
          --min-backoff=60s

Описание этого дает мне:

name: projects/my-project/locations/us-central1/queues/my-queue
rateLimits:
  maxBurstSize: 10
  maxConcurrentDispatches: 1
  maxDispatchesPerSecond: 1.0
retryConfig:
  maxAttempts: 2
  maxBackoff: 3600s
  maxDoublings: 16
  minBackoff: 60s
state: RUNNING

После создания группы задач я вижу в журналах, что многие из них нежелательно обрабатываются в течение 1 секунды:

2019-07-27 02:37:48 default[20190727t043306]  Received task with payload: {'id': 51}
2019-07-27 02:37:48 default[20190727t043306]  "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306]  Received task with payload: {'id': 52}
2019-07-27 02:37:49 default[20190727t043306]  "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306]  Received task with payload: {'id': 53}
2019-07-27 02:37:49 default[20190727t043306]  "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306]  Received task with payload: {'id': 54}
2019-07-27 02:37:49 default[20190727t043306]  "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306]  Received task with payload: {'id': 55}
2019-07-27 02:37:49 default[20190727t043306]  "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306]  Received task with payload: {'id': 56}
2019-07-27 02:37:49 default[20190727t043306]  "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306]  Received task with payload: {'id': 57}
2019-07-27 02:37:49 default[20190727t043306]  "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306]  Received task with payload: {'id': 58}

Как правильно заставить его запускать не более 1 задачи в течение 1 секунды?

Обновление 30/06:

Я попробовал это снова с базовой настройкой, та же проблема.

Более подробная информация о настройке и процессе:

  1. Исходный код https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/appengine/flexible/tasks, без изменений
  2. Разверните app.yaml, а не app.f flex.yaml
  3. Запускать задачу несколько раз: python create_app_engine_queue_task.py --project=$PROJECT_ID --queue=$QUEUE_ID --location=$LOCATION_ID --payload= привет
  4. Проверьте журналы: прочитаны журналы приложений gcloud

На этот раз им потребовалось некоторое время, чтобы начать обработку, но после этого кажется, что все они были обработаны более или менее одновременно:

Полные журналы:

2019-07-30 00:22:37 default[20190730t021951]  [2019-07-30 00:22:37 +0000] [9] [INFO] Starting gunicorn 19.9.0
2019-07-30 00:22:37 default[20190730t021951]  [2019-07-30 00:22:37 +0000] [9] [INFO] Listening at: http://0.0.0.0:8081 (9)
2019-07-30 00:22:37 default[20190730t021951]  [2019-07-30 00:22:37 +0000] [9] [INFO] Using worker: threads
2019-07-30 00:22:37 default[20190730t021951]  [2019-07-30 00:22:37 +0000] [23] [INFO] Booting worker with pid: 23
2019-07-30 00:22:37 default[20190730t021951]  [2019-07-30 00:22:37 +0000] [26] [INFO] Booting worker with pid: 26
2019-07-30 00:27:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:27:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:27:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:27:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:27:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:27:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:37:42 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:42 default[20190730t021951]  Received task with payload: hello
2019-07-30 00:37:43 default[20190730t021951]  "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:43 default[20190730t021951]  Received task with payload: hello

1 ответ

Tl ;dr Это, вероятно, работает как задумано. Вы можете ожидать первоначальный всплеск maxBurstSize задачи, которые затем замедляются до maxDispatchesPerSecond,

Причиной этого является алгоритм "Token Bucket": есть корзина, которая может вместить максимум maxBurstSize токены, и изначально имеет столько токенов в нем. Задача отправляется, если пришло запланированное время, и в корзине есть токен И меньше, чем maxConcurrentDispatches в полете, в противном случае мы ждем выполнения этих условий. Когда задача отправляется, токен удаляется из корзины. Когда ведро не заполнено, токены добавляются со скоростью maxDispatchesPerSecond, Таким образом, скорость не является точным ограничением для отправки задач. Задачи можно отправлять с произвольной скоростью, если в корзине есть токены и задачи готовы к запуску. Только когда задачи должны ждать токенов, мы должны замедляться до заданной скорости. Так как ведро начинает заполняться, вы можете получить первоначальный взрыв.

В API и консоли Cloud Tasks размер корзины доступен только для чтения (и API вызывает его max_burst_size). Но с использованием старшего queue.yaml Конфигурация вы можете контролировать размер ковша наряду с другими параметрами, например,

queue:
- name: my-appengine-queue
  rate: 2/s
  bucket_size: 20
  max_concurrent_requests: 5

затем gcloud app deploy queue.yaml, Однако, если вы это сделаете, учтите эти ловушки: https://cloud.google.com/tasks/docs/queue-yaml

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

Очереди, созданные с помощью queue.yaml, и очереди, созданные Cloud Tasks - как бы вы это ни делали - это одни и те же очереди. Однако существуют проблемы, которые могут возникнуть, если вы смешиваете методы queue.yaml и Cloud Tasks Queue Management. См. https://cloud.google.com/tasks/docs/queue-yaml для получения дополнительной информации.

Краткий ответ: это просто невозможно прямо сейчас с API Cloud Tasks, поскольку конфигурация максимального размера пакета не отображается.

Обходной путь: управляйте своими задачами с помощью queue.yaml App Engine https://cloud.google.com/tasks/docs/queue-yaml

Если вас также интересует эта функция, вы можете проголосовать за ее https://issuetracker.google.com/issues/138813037.

Другие вопросы по тегам