Можно ли получить общее количество сообщений в SQS?

Я вижу, есть 2 отдельных показателя и .

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

Я пытаюсь масштабировать службу Kubernetes с помощью горизонтального автомасштабирования подов и внешней метрики из SQS. Вот внешний показатель шаблона:

      apiVersion: metrics.aws/v1alpha1
kind: ExternalMetric
metadata:
  name: metric-name
spec:
  name: metric-name
  queries:
    - id: metric_name
      metricStat:
        metric:
          namespace: "AWS/SQS"
          metricName: "ApproximateNumberOfMessagesVisible"
          dimensions:
            - name: QueueName
              value: "queue_name"
        period: 60
        stat: Average
        unit: Count
      returnData: true

Вот шаблон HPA:

      kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2beta1
metadata:
  name: hpa-name
spec:
  scaleTargetRef:
    apiVersion: apps/v1beta1
    kind: Deployment
    name: deployment-name
  minReplicas: 1
  maxReplicas: 50
  metrics:
  - type: External
    external:
      metricName: metric-name
      targetAverageValue: 1

Проблема будет решена, если я смогу определить другую настраиваемую метрику, которая представляет собой сумму этих двух метрик. Как еще я могу решить эту проблему?

2 ответа

Решение

Мы использовали лямбда для получения двух показателей и публикации настраиваемой метрики, которая представляет собой сумму сообщений в полете и ожидании, и запускаем эту лямбду, используя события облачного наблюдения с любой частотой, которую вы хотите, https://console.aws.amazon.com/cloudwatch / home?region = us-east-1#rules:action = create

Вот лямбда-код для справки:

      const AWS = require('aws-sdk');
const cloudwatch = new AWS.CloudWatch({region: ''});  // fill region here
const sqs = new AWS.SQS();

const SQS_URL = ''; // fill queue url here

async function getSqsMetric(queueUrl) {
    var params = {
      QueueUrl: queueUrl,
      AttributeNames: ['All']
    };
    return new Promise((res, rej) => {
        sqs.getQueueAttributes(params, function(err, data) {
            if (err) rej(err);
            else res(data);
        });
    })
    
}

function buildMetric(numMessages) {
  return {
    Namespace: 'yourcompany-custom-metrics',
    MetricData: [{
      MetricName: 'mymetric',
      Dimensions: [{
          Name: 'env',
          Value: 'prod'
      }],
      Timestamp: new Date(),
      Unit: 'Count',
      Value: numMessages
    }]
  }
}

async function pushMetrics(metrics) {
  await new Promise((res) => cloudwatch.putMetricData(metrics, (err, data) => {
    if (err) {
      console.log('err', err, err.stack); // an error occurred
      res(err);
    } else {
      console.log('response', data);           // successful response
      res(data);
    }
  }));
}

exports.handler = async (event) => {
    console.log('Started');
    const sqsMetrics = await getSqsMetric(SQS_URL).catch(console.error);
    var queueSize = null;
    if (sqsMetrics) {
        console.log('Got sqsMetrics', sqsMetrics);
        if (sqsMetrics.Attributes) {
          queueSize = parseInt(sqsMetrics.Attributes.ApproximateNumberOfMessages) + parseInt(sqsMetrics.Attributes.ApproximateNumberOfMessagesNotVisible);
          console.log('Pushing', queueSize);
          await pushMetrics(buildMetric(queueSize))
        } 
    } else {
        console.log('Failed fetching sqsMetrics');
    }
    const response = {
        statusCode: 200,
        body: JSON.stringify('Pushed ' + queueSize),
    };
    return response;
};

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

ИМХО, у вас есть пара вариантов. Вы можете посмотреть на добавление StabilizationWindow в HPA и, возможно, ограничить скорость уменьшения масштаба . Вам нужно будет попробовать несколько комбинаций показателей и посмотреть, что лучше всего подходит для вас, поскольку вы лучше всего знаете природу показателей ( ApproximateNumberOfMessagesVisible в этом случае) вы видите в своей инфраструктуре.

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